ruby_mongo_x 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/helpers/loggable.rb +7 -0
- data/lib/ruby_mongo_x.rb +168 -0
- metadata +101 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 9eaedb3e5a9b24803714ebeecbb8b2e1bb5116724da0ae0ef639127372403531
|
4
|
+
data.tar.gz: 91bd5334eaf9309e714ada4c27b1d427794880ca206e30743c2be253af52bf22
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 109a0d54f4e697f9aa41caf0f810e6952020926fd75f467cf3734bfc974aca81e719f98196f278d289ff94ed568fc073261625f561cd46b32820bde4892366c7
|
7
|
+
data.tar.gz: 1241abab507078eb3b1b43527a48e12dba103eb1c99b069022250d7874914804f547d90d68d88d20d6a1391392337c8cf926885598c1a3325a74ec0ba4636c75
|
data/lib/ruby_mongo_x.rb
ADDED
@@ -0,0 +1,168 @@
|
|
1
|
+
require 'mongo'
|
2
|
+
require 'concurrent'
|
3
|
+
require_relative './helpers/loggable'
|
4
|
+
|
5
|
+
class RubyMongoX
|
6
|
+
include ::Helpers::Loggable
|
7
|
+
|
8
|
+
def self.build(collection_name, shards, max_count_per_shard)
|
9
|
+
new(collection_name, shards, max_count_per_shard)
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(collection_name, shards, max_count_per_shard)
|
13
|
+
@max_count_per_shard = max_count_per_shard
|
14
|
+
@mongo_clients = {}
|
15
|
+
|
16
|
+
threads = []
|
17
|
+
|
18
|
+
options = {}
|
19
|
+
|
20
|
+
shards.each_with_index do |shard, idx|
|
21
|
+
threads << Thread.new do
|
22
|
+
log_debug "\t Connecting to shard #{shard} ...\n"
|
23
|
+
begin
|
24
|
+
@mongo_clients[idx.to_s] = ::Mongo::Client.new(shard, options)
|
25
|
+
rescue Mongo::Error::SocketError => e
|
26
|
+
log_debug "\t SocketError: #{e.message}...\n"
|
27
|
+
log_debug "\t SocketError: Stopped trying to connect to shard #{shard}... FAIL!\n"
|
28
|
+
rescue Mongo::Error::NoSRVRecords => e
|
29
|
+
log_debug "\t NoSRVRecords: #{e.message}...\n"
|
30
|
+
log_debug "\t NoSRVRecords: Retrying connect to shard #{shard}...\n"
|
31
|
+
sleep 1
|
32
|
+
retry
|
33
|
+
rescue Mongo::Error::SocketTimeoutError => e
|
34
|
+
log_debug "\t SocketTimeoutError: #{e.message}...\n"
|
35
|
+
log_debug "\t SocketTimeoutError: Retrying connect to shard #{shard}...\n"
|
36
|
+
sleep 1
|
37
|
+
retry
|
38
|
+
end
|
39
|
+
log_debug "\t Connected to shard #{shard} --> OK\n"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
threads.each(&:join)
|
44
|
+
@collection_name = collection_name
|
45
|
+
end
|
46
|
+
|
47
|
+
def get_collection(key)
|
48
|
+
shard_idx = get_shard_index(key)
|
49
|
+
unless @mongo_clients[shard_idx.to_s].nil?
|
50
|
+
return @mongo_clients[shard_idx.to_s][@collection_name.to_sym]
|
51
|
+
else
|
52
|
+
raise StandardError.new("No Mongo shard for shard index: #{shard_idx} !!!")
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# def ensure_indices(collection_name, index_definitions)
|
57
|
+
# @mongo_clients.each do |e|
|
58
|
+
# mongo_client = e[1]
|
59
|
+
# collection = mongo_client[collection_name.to_sym]
|
60
|
+
# mongo_user = collection.client.cluster.servers.first.options["user"]
|
61
|
+
|
62
|
+
# log_debug "\tEnsuring index: #{index_definitions} on #{collection_name} (#{mongo_user})... "
|
63
|
+
# mongo_client[collection_name.to_sym].indexes.create_many(index_definitions)
|
64
|
+
# log_debug " OK\n"
|
65
|
+
# end
|
66
|
+
# end
|
67
|
+
|
68
|
+
def get_shard_index(key)
|
69
|
+
((key.to_i - 1).to_f / @max_count_per_shard).to_i
|
70
|
+
end
|
71
|
+
|
72
|
+
def find(query)
|
73
|
+
log_debug "\t Query: #{query.to_json}\n"
|
74
|
+
promises = @mongo_clients.map do |mongo_client_item|
|
75
|
+
mongo_client = mongo_client_item[1]
|
76
|
+
Concurrent::Promise.execute do
|
77
|
+
fetch_data_from_shard(mongo_client, query)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
results = promises.map { |promise| promise.value[:results] }
|
81
|
+
merged_results = results.flatten
|
82
|
+
merged_results
|
83
|
+
end
|
84
|
+
|
85
|
+
def count(query)
|
86
|
+
log_debug "\t Count query: #{query.to_json}\n"
|
87
|
+
promises = @mongo_clients.map do |mongo_client_item|
|
88
|
+
mongo_client = mongo_client_item[1]
|
89
|
+
Concurrent::Promise.execute do
|
90
|
+
count_data_from_shard(mongo_client, query)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
results = promises.map { |promise| promise.value[:count] }.sort.reverse
|
94
|
+
log_debug "Results sorted: #{results}\n"
|
95
|
+
merged_results = results.sum()
|
96
|
+
merged_results
|
97
|
+
end
|
98
|
+
|
99
|
+
def count_per_shard(query)
|
100
|
+
log_debug "\t Count query per shard: #{query.to_json}\n"
|
101
|
+
promises = @mongo_clients.map do |mongo_client_item|
|
102
|
+
mongo_client = mongo_client_item[1]
|
103
|
+
Concurrent::Promise.execute do
|
104
|
+
count_data_from_shard(mongo_client, query)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
results = {
|
109
|
+
count: 0,
|
110
|
+
shards: {}
|
111
|
+
}
|
112
|
+
|
113
|
+
promises.map { |promise|
|
114
|
+
results[:shards][promise.value[:shard]] = promise.value[:count]
|
115
|
+
results[:count] = results[:count] + promise.value[:count]
|
116
|
+
}
|
117
|
+
|
118
|
+
log_debug "Results: #{results}\n"
|
119
|
+
results
|
120
|
+
end
|
121
|
+
|
122
|
+
|
123
|
+
def update_one()
|
124
|
+
# TODO: implement
|
125
|
+
end
|
126
|
+
|
127
|
+
def update_many()
|
128
|
+
# TODO: implement
|
129
|
+
end
|
130
|
+
|
131
|
+
def fetch_data_from_shard(mongo_client, query)
|
132
|
+
collection = mongo_client[@collection_name.to_sym]
|
133
|
+
results = collection.find(query).to_a
|
134
|
+
mongo_server = mongo_client&.cluster&.servers&.first
|
135
|
+
mongo_user = mongo_server&.options["user"] || ""
|
136
|
+
mongo_db = mongo_server&.options["database"] || ""
|
137
|
+
log_debug "\t\tfind() with mongo_client user: #{mongo_user}, database: #{mongo_db} returns #{results.count} items...\n"
|
138
|
+
|
139
|
+
{
|
140
|
+
shard: (mongo_user.nil? || mongo_user == "") ? mongo_db : mongo_user,
|
141
|
+
results: results
|
142
|
+
}
|
143
|
+
end
|
144
|
+
|
145
|
+
def count_data_from_shard(mongo_client, query)
|
146
|
+
collection = mongo_client[@collection_name.to_sym]
|
147
|
+
count = collection.count_documents(query)
|
148
|
+
count = 0 if count.nil?
|
149
|
+
mongo_server = mongo_client&.cluster&.servers&.first
|
150
|
+
mongo_user = mongo_server&.options["user"] || ""
|
151
|
+
mongo_db = mongo_server&.options["database"] || ""
|
152
|
+
log_debug "\t\tcount() with mongo_client user: #{mongo_user}, database: #{mongo_db} returns #{count}\n"
|
153
|
+
|
154
|
+
{
|
155
|
+
shard: (mongo_user.nil? || mongo_user == "") ? mongo_db : mongo_user,
|
156
|
+
count: count
|
157
|
+
}
|
158
|
+
end
|
159
|
+
|
160
|
+
def disconnect()
|
161
|
+
@mongo_clients.values.each do |client|
|
162
|
+
log_debug "\t Disconnecting from client #{client.to_s} ..."
|
163
|
+
client.close
|
164
|
+
log_debug " OK\n"
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
end
|
metadata
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ruby_mongo_x
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.4
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Grzegorz Błaszczyk
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2025-03-09 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: config
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 4.1.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 4.1.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: mongo
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 2.19.1
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 2.19.1
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: pry-byebug
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 3.10.1
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 3.10.1
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 13.2.1
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 13.2.1
|
69
|
+
description: MongoDB client in Ruby that connects to dozens of Mongo databases, performs
|
70
|
+
queries simultaneously and gets the results in a unified way.
|
71
|
+
email: grzegorz.blaszczyk@gmail.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- lib/helpers/loggable.rb
|
77
|
+
- lib/ruby_mongo_x.rb
|
78
|
+
homepage: https://rubygems.org/gems/ruby_mongo_x
|
79
|
+
licenses:
|
80
|
+
- MIT
|
81
|
+
metadata: {}
|
82
|
+
post_install_message:
|
83
|
+
rdoc_options: []
|
84
|
+
require_paths:
|
85
|
+
- lib
|
86
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
requirements: []
|
97
|
+
rubygems_version: 3.4.6
|
98
|
+
signing_key:
|
99
|
+
specification_version: 4
|
100
|
+
summary: Multi-database Ruby MongoDB client
|
101
|
+
test_files: []
|