ruby_mongo_x 0.0.1 → 0.0.2

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.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/ruby_mongo_x.rb +76 -23
  3. metadata +16 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 572e5ea8830b21f4383aea598af182771d30cb7825b89632fca870be5de69cee
4
- data.tar.gz: ec51fbaa55bd7593ca2417da94127440930ce5c90c18cb1e07f6d3d82027166b
3
+ metadata.gz: a5d7bd728e88970a0ff957c2935f59e9d30c9992563adb15a79ee897e077827a
4
+ data.tar.gz: e8cfe6bfbb400e25aebc866fc476dadc816f63a678c24bd739a139fad8ff39e9
5
5
  SHA512:
6
- metadata.gz: d9298a9965220c26672083d00407838932367c065f2be36c093e23871d4787c13b2b5eea25a610a1f9f286b784ac6828c96b0d97794327b64cceb357b57ea680
7
- data.tar.gz: 4a719efef6c5eb616adbb38748304a72cbe17ac431784efc0bd06c7f34354f0eb3dca4108f7f652d8bb2dc25a3774439e0b3fb2d3909722c0c6aa35415518be4
6
+ metadata.gz: e8ff01c4f8782680259dad4cc224d7efc1653c6663155025999cee1832d6b6632aead51d3481a2518f73ed6eac9a8e62979926bb71e225a146c86d74eb87412d
7
+ data.tar.gz: 24d259ac7baee8f3c199b9e76ab0bc0e18fcfa34076d5d77cb7ed469e7bd08ccdb554f76e0c186fb194a70153b1599bf23aa3269689e74f3551ddb4e71c362bd
data/lib/ruby_mongo_x.rb CHANGED
@@ -1,6 +1,5 @@
1
1
  require 'mongo'
2
2
  require 'concurrent'
3
- require 'pry'
4
3
  require_relative './helpers/loggable'
5
4
 
6
5
  class RubyMongoX
@@ -14,12 +13,31 @@ class RubyMongoX
14
13
  @max_count_per_shard = max_count_per_shard
15
14
  @mongo_clients = {}
16
15
 
16
+ threads = []
17
+
18
+ options = {}
19
+
17
20
  shards.each_with_index do |shard, idx|
18
- log_debug "\t Connecting to shard #{shard} ..."
19
- @mongo_clients[idx.to_s] = ::Mongo::Client.new(shard)
20
- log_debug " OK\n"
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::NoSRVRecords => e
26
+ log_debug "\t NoSRVRecords: #{e.message}...\n"
27
+ log_debug "\t NoSRVRecords: Retrying connect to shard #{shard}...\n"
28
+ sleep 1
29
+ retry
30
+ rescue Mongo::Error::SocketTimeoutError => e
31
+ log_debug "\t SocketTimeoutError: #{e.message}...\n"
32
+ log_debug "\t SocketTimeoutError: Retrying connect to shard #{shard}...\n"
33
+ sleep 1
34
+ retry
35
+ end
36
+ log_debug "\t Connected to shard #{shard} --> OK\n"
37
+ end
21
38
  end
22
39
 
40
+ threads.each(&:join)
23
41
  @collection_name = collection_name
24
42
  end
25
43
 
@@ -48,44 +66,54 @@ class RubyMongoX
48
66
  ((key.to_i - 1).to_f / @max_count_per_shard).to_i
49
67
  end
50
68
 
51
-
52
69
  def find(query)
53
- log_debug "\t Query: #{query}\n"
70
+ log_debug "\t Query: #{query.to_json}\n"
54
71
  promises = @mongo_clients.map do |mongo_client_item|
55
72
  mongo_client = mongo_client_item[1]
56
- log_debug "\t\tfind() with mongo_client: #{mongo_client.to_s}\n"
57
73
  Concurrent::Promise.execute do
58
74
  fetch_data_from_shard(mongo_client, query)
59
75
  end
60
76
  end
61
-
62
- # Wait for all promises to complete and retrieve their results
63
- results = promises.map { |promise| promise.value }
64
-
65
- # Merge the results from all data sources
77
+ results = promises.map { |promise| promise.value[:results] }
66
78
  merged_results = results.flatten
67
-
68
- # Now you have merged_results containing data from all sources
69
79
  merged_results
70
80
  end
71
81
 
72
82
  def count(query)
73
- log_debug "\t Count query: #{query}\n"
83
+ log_debug "\t Count query: #{query.to_json}\n"
84
+ promises = @mongo_clients.map do |mongo_client_item|
85
+ mongo_client = mongo_client_item[1]
86
+ Concurrent::Promise.execute do
87
+ count_data_from_shard(mongo_client, query)
88
+ end
89
+ end
90
+ results = promises.map { |promise| promise.value[:count] }.sort.reverse
91
+ log_debug "Results sorted: #{results}\n"
92
+ merged_results = results.sum()
93
+ merged_results
94
+ end
95
+
96
+ def count_per_shard(query)
97
+ log_debug "\t Count query per shard: #{query.to_json}\n"
74
98
  promises = @mongo_clients.map do |mongo_client_item|
75
99
  mongo_client = mongo_client_item[1]
76
- log_debug "\t\tcount() with mongo_client: #{mongo_client.to_s}\n"
77
100
  Concurrent::Promise.execute do
78
101
  count_data_from_shard(mongo_client, query)
79
102
  end
80
103
  end
81
104
 
82
- # Wait for all promises to complete and retrieve their results
83
- results = promises.map { |promise| promise.value }
105
+ results = {
106
+ count: 0,
107
+ shards: {}
108
+ }
84
109
 
85
- merged_results = results.sum()
110
+ promises.map { |promise|
111
+ results[:shards][promise.value[:shard]] = promise.value[:count]
112
+ results[:count] = results[:count] + promise.value[:count]
113
+ }
86
114
 
87
- # Now you have merged_results containing data from all sources
88
- merged_results
115
+ log_debug "Results: #{results}\n"
116
+ results
89
117
  end
90
118
 
91
119
 
@@ -99,14 +127,39 @@ class RubyMongoX
99
127
 
100
128
  def fetch_data_from_shard(mongo_client, query)
101
129
  collection = mongo_client[@collection_name.to_sym]
102
- collection.find(query).to_a
130
+ results = collection.find(query).to_a
131
+ mongo_server = mongo_client&.cluster&.servers&.first
132
+ mongo_user = mongo_server&.options["user"] || ""
133
+ mongo_db = mongo_server&.options["database"] || ""
134
+ log_debug "\t\tfind() with mongo_client user: #{mongo_user}, database: #{mongo_db} returns #{results.count} items...\n"
135
+
136
+ {
137
+ shard: (mongo_user.nil? || mongo_user == "") ? mongo_db : mongo_user,
138
+ results: results
139
+ }
103
140
  end
104
141
 
105
142
  def count_data_from_shard(mongo_client, query)
106
143
  collection = mongo_client[@collection_name.to_sym]
107
144
  count = collection.count_documents(query)
108
145
  count = 0 if count.nil?
109
- count
146
+ mongo_server = mongo_client&.cluster&.servers&.first
147
+ mongo_user = mongo_server&.options["user"] || ""
148
+ mongo_db = mongo_server&.options["database"] || ""
149
+ log_debug "\t\tcount() with mongo_client user: #{mongo_user}, database: #{mongo_db} returns #{count}\n"
150
+
151
+ {
152
+ shard: (mongo_user.nil? || mongo_user == "") ? mongo_db : mongo_user,
153
+ count: count
154
+ }
155
+ end
156
+
157
+ def disconnect()
158
+ @mongo_clients.values.each do |client|
159
+ log_debug "\t Disconnecting from client #{client.to_s} ..."
160
+ client.close
161
+ log_debug " OK\n"
162
+ end
110
163
  end
111
164
 
112
165
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_mongo_x
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Grzegorz Błaszczyk
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-09-09 00:00:00.000000000 Z
11
+ date: 2023-10-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: config
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
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: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
55
69
  description: MongoDB client in Ruby that connects to dozens of Mongo databases, performs
56
70
  queries simultaneously and gets the results in a unified way.
57
71
  email: grzegorz.blaszczyk@gmail.com