monga 0.0.2 → 0.0.3

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 (63) hide show
  1. data/.gitignore +1 -0
  2. data/.travis.yml +1 -0
  3. data/README.md +59 -3
  4. data/lib/monga/client.rb +51 -6
  5. data/lib/monga/clients/master_slave_client.rb +0 -5
  6. data/lib/monga/clients/replica_set_client.rb +32 -71
  7. data/lib/monga/clients/single_instance_client.rb +53 -0
  8. data/lib/monga/collection.rb +102 -41
  9. data/lib/monga/connection.rb +38 -13
  10. data/lib/monga/connection_pool.rb +6 -17
  11. data/lib/monga/connections/buffer.rb +33 -0
  12. data/lib/monga/connections/em_connection.rb +25 -56
  13. data/lib/monga/connections/em_proxy_connection.rb +80 -0
  14. data/lib/monga/connections/fibered_connection.rb +26 -0
  15. data/lib/monga/connections/fibered_proxy_connection.rb +23 -0
  16. data/lib/monga/connections/proxy_connection.rb +4 -0
  17. data/lib/monga/connections/tcp_connection.rb +57 -0
  18. data/lib/monga/cursor.rb +197 -95
  19. data/lib/monga/database.rb +175 -60
  20. data/lib/monga/{requests → protocol}/delete.rb +1 -2
  21. data/lib/monga/{requests → protocol}/get_more.rb +1 -1
  22. data/lib/monga/{requests → protocol}/insert.rb +1 -2
  23. data/lib/monga/{requests → protocol}/kill_cursors.rb +1 -1
  24. data/lib/monga/{requests → protocol}/query.rb +3 -3
  25. data/lib/monga/{requests → protocol}/update.rb +1 -1
  26. data/lib/monga/request.rb +27 -23
  27. data/lib/monga/utils/constants.rb +5 -0
  28. data/lib/monga/utils/exceptions.rb +11 -0
  29. data/lib/monga.rb +19 -11
  30. data/monga.gemspec +2 -2
  31. data/spec/helpers/mongodb.rb +115 -38
  32. data/spec/monga/block/collection_spec.rb +172 -0
  33. data/spec/monga/block/cursor_spec.rb +160 -0
  34. data/spec/monga/block/database_spec.rb +80 -0
  35. data/spec/monga/block/single_instance_client_spec.rb +31 -0
  36. data/spec/monga/em/collection_spec.rb +308 -0
  37. data/spec/monga/em/cursor_spec.rb +256 -0
  38. data/spec/monga/em/database_spec.rb +140 -0
  39. data/spec/monga/em/replica_set_client_spec.rb +86 -0
  40. data/spec/monga/em/single_instance_client_spec.rb +28 -0
  41. data/spec/monga/sync/collection_spec.rb +247 -0
  42. data/spec/monga/sync/cursor_spec.rb +211 -0
  43. data/spec/monga/sync/database_spec.rb +110 -0
  44. data/spec/monga/sync/replica_set_client_spec.rb +54 -0
  45. data/spec/monga/sync/single_instance_client_spec.rb +25 -0
  46. data/spec/spec_helper.rb +2 -20
  47. metadata +50 -38
  48. data/lib/monga/clients/client.rb +0 -24
  49. data/lib/monga/connections/primary.rb +0 -46
  50. data/lib/monga/connections/secondary.rb +0 -13
  51. data/lib/monga/exceptions.rb +0 -9
  52. data/lib/monga/miner.rb +0 -72
  53. data/lib/monga/response.rb +0 -11
  54. data/spec/helpers/truncate.rb +0 -15
  55. data/spec/monga/collection_spec.rb +0 -448
  56. data/spec/monga/connection_pool_spec.rb +0 -50
  57. data/spec/monga/connection_spec.rb +0 -64
  58. data/spec/monga/cursor_spec.rb +0 -186
  59. data/spec/monga/database_spec.rb +0 -67
  60. data/spec/monga/replica_set_client_spec.rb +0 -46
  61. data/spec/monga/requests/delete_spec.rb +0 -0
  62. data/spec/monga/requests/insert_spec.rb +0 -0
  63. data/spec/monga/requests/query_spec.rb +0 -28
data/.gitignore CHANGED
@@ -11,6 +11,7 @@ doc/
11
11
  lib/bundler/man
12
12
  pkg
13
13
  rdoc
14
+ benchmarks
14
15
  spec/reports
15
16
  test/tmp
16
17
  test/version_tmp
data/.travis.yml ADDED
@@ -0,0 +1 @@
1
+ services: mongodb
data/README.md CHANGED
@@ -1,11 +1,66 @@
1
+ [![Build Status](https://travis-ci.org/fl00r/monga.png?branch=master)](https://travis-ci.org/fl00r/monga)
2
+
1
3
  # Monga
2
4
 
3
- [MongoDB](http://www.mongodb.org/) Ruby Client on [EventMachine](https://github.com/eventmachine/eventmachine).
5
+ [MongoDB](http://www.mongodb.org/) Ruby Client on [EventMachine](https://github.com/eventmachine/eventmachine). Also it supports synchrony mode ([em-synchrony](https://github.com/igrigorik/em-synchrony)).
4
6
 
5
7
  This client is under development. You can try [em-mongo](https://github.com/bcg/em-mongo).
6
8
 
7
9
  Client supports MongoDB 2.4. Some features won't work in lower versions.
8
10
 
11
+ # Introduction
12
+
13
+ Monga supports asynchronous (over EventMachine), synchronous (Fibers) and blocking (TCPSocket) interfaces.
14
+
15
+ API will be familiar to Node.js developers: it returns `err, response` into callback.
16
+
17
+ ```ruby
18
+ # Async mode
19
+ EM.run do
20
+ connection = Monga::Client.new(host: "127.0.0.1", port: 27017, type: :em)
21
+ db = connection["dbTest"]
22
+ collection = db["testCollection"]
23
+ collection.safe_insert(title: "Test") do |err, resp|
24
+ if err
25
+ puts "Error happend: #{err.message}"
26
+ else
27
+ puts "saved!"
28
+ collection.find.all do |err, docs|
29
+ if err
30
+ puts "Error happend: #{err.message}"
31
+ else
32
+ puts "Docs fetched: #{docs.size}"
33
+ end
34
+ EM.stop
35
+ end
36
+ end
37
+ end
38
+ end
39
+
40
+ # Sync mode
41
+ EM.synchrony do
42
+ connection = Monga::Client.new(host: "127.0.0.1", port: 27017, type: :sync)
43
+ db = connection["dbTest"]
44
+ collection = db["testCollection"]
45
+ collection.safe_insert(title: "Test")
46
+ puts "saved"
47
+ docs = collection.find.all
48
+ puts "Docs fetched: #{docs.size}"
49
+ EM.stop
50
+ end
51
+
52
+ # Blocking mode
53
+ connection = Monga::Client.new(host: "127.0.0.1", port: 27017, type: :block)
54
+ db = connection["dbTest"]
55
+ collection = db["testCollection"]
56
+ collection.safe_insert(title: "Test")
57
+ puts "saved"
58
+ docs = collection.find.all
59
+ puts "Docs fetched: #{docs.size}"
60
+ ```
61
+
62
+ README and WIKI is going to be written.
63
+
9
64
  ## To Do List
10
65
 
11
66
  * [ ] Write a Wiki
@@ -46,13 +101,14 @@ Client supports MongoDB 2.4. Some features won't work in lower versions.
46
101
  * [ ] check maxBsonSize / validate
47
102
  * [x] cmd
48
103
  * [x] eval
49
- * [ ] where
104
+ * [ ] aggregation
105
+ * [ ] gridfs?
50
106
 
51
107
  ### Collection
52
108
  * QUERY_OP
53
109
  * [x] find
54
110
  * [x] find_one (first)
55
- * [ ] sorting
111
+ * [x] sorting
56
112
  * INSERT_OP
57
113
  * [x] insert (single)
58
114
  * [x] insert (batch)
data/lib/monga/client.rb CHANGED
@@ -1,8 +1,53 @@
1
- require File.expand_path("../clients/client", __FILE__)
2
- require File.expand_path("../clients/replica_set_client", __FILE__)
3
- require File.expand_path("../clients/master_slave_client", __FILE__)
4
1
  module Monga
5
- Client = Monga::Clients::Client
6
- ReplicaSetClient = Monga::Clients::ReplicaSetClient
7
- MasterSlaveClient = Monga::Clients::MasterSlaveClient
2
+ class Client
3
+ extend Forwardable
4
+
5
+ def_delegators :@client, :aquire_connection
6
+
7
+ VALID_OPTS = [:host, :port, :server, :type, :pool_size, :servers, :read_pref, :timeout]
8
+
9
+ # Following options are allowed
10
+ # * host - host of server to connect, default 127.0.0.1
11
+ # * port - port of server to connect, default 27017
12
+ # * server - host:port of server to connect (you can pass server or host/port pair)
13
+ # * type - :em/:sync/:block - socket type, asynchronouse on EventMachine, Fibered or blocking TCP
14
+ # * pool_size - connection pool size
15
+ # * servers - array of server names (host:port) to connect or array of hashes host/port (for Replica Set connection)
16
+ # * read_pref - read preference for Replica Set (:primary, :secondary, :primary_preferred, :secondary_preferred), default :primary
17
+ # * timeout - client will try to reconnect till timout (in seconds) if connection failed, default 10 seconds
18
+ def initialize(opts = {})
19
+ @opts = opts
20
+ @opts[:type] ||= :block
21
+
22
+ sanitize_opts!
23
+ create_client
24
+ end
25
+
26
+ # Choose database by it's name
27
+ def get_database(db_name)
28
+ Monga::Database.new(@client, db_name)
29
+ end
30
+ alias :[] :get_database
31
+
32
+ private
33
+
34
+ # Validates incoming options to prevent missunderstanding
35
+ def sanitize_opts!
36
+ @opts.each_key do |key|
37
+ unless VALID_OPTS.include? key
38
+ raise Monga::Exceptions::InvalidClientOption, "`#{key}` is invalid option for Client. Following options are valid: #{VALID_OPTS * ', '}"
39
+ end
40
+ end
41
+ end
42
+
43
+ # If servers options is defined it will create ReplicaSetClient,
44
+ # otherwise SingleInstanceClient will be created
45
+ def create_client
46
+ @client = if @opts[:servers]
47
+ Monga::Clients::ReplicaSetClient.new(@opts)
48
+ else
49
+ Monga::Clients::SingleInstanceClient.new(@opts)
50
+ end
51
+ end
52
+ end
8
53
  end
@@ -1,5 +0,0 @@
1
- module Monga::Clients
2
- class MasterSlaveClient
3
-
4
- end
5
- end
@@ -1,45 +1,35 @@
1
- # How it works
2
- # Replica Set tries to establish connections to all passed servers.
3
- # Till no connection established it queues al queries inside it's
4
-
5
1
  module Monga::Clients
6
2
  class ReplicaSetClient
7
- class ProxyConnection
8
- include EM::Deferrable
9
- def initialize(client)
10
- @client = client
11
- end
12
-
13
- def send_command(msg, request_id=nil, &cb)
14
- callback do
15
- connection = @client.aquire_connection
16
- connection.send_command(msg, request_id, &cb)
3
+ attr_reader :read_pref, :timeout, :clients
4
+
5
+ # ReplicaSetClient creates SingleInstanceClient to each server.
6
+ # Accepts
7
+ # * servers - you could pas them as a array of servers (['1.1.1.1:27017', '1.1.1.2:27017']), or as a array of hashes: ([{host: '1.1.1.1', port: 27017}, {host: '1.1.1.2', port: 27017}])
8
+ # * read_pref - read preferrence (:primary, :primary_preferred, :secondary, :secondary_preferred)
9
+ # * pool_size - connection pool size to each server
10
+ # * type - connection type (:em/:sync/:block)
11
+ def initialize(opts)
12
+ @timeout = opts[:timeout]
13
+ @read_pref = opts[:read_pref] || :primary
14
+
15
+ servers = opts.delete :servers
16
+ @clients = servers.map do |server|
17
+ case server
18
+ when Hash
19
+ Monga::Clients::SingleInstanceClient.new(opts.merge(server))
20
+ when String
21
+ h, p = server.split(":")
22
+ o = { host: h, port: p.to_i }
23
+ Monga::Clients::SingleInstanceClient.new(opts.merge(o))
17
24
  end
18
25
  end
19
- end
20
-
21
- include EM::Deferrable
22
-
23
- attr_reader :servers, :clients
24
-
25
- def initialize(opts = {})
26
- @read_pref = opts.delete(:read_pref) || :primary
27
- @servers = opts.delete(:servers)
28
- raise ArgumentError, "servers option is not passed or empty" if @servers.empty?
29
-
30
- @clients = @servers.map do |server|
31
- Monga::Client.new(server.merge(opts))
32
- end
33
-
34
- @proxy_connection = ProxyConnection.new(self)
35
- end
36
26
 
37
- def [](db_name)
38
- Monga::Database.new(self, db_name)
27
+ @proxy_connection = Monga::Connection.proxy_connection_class(opts[:type]).new(self)
39
28
  end
40
29
 
30
+ # Aquires connection due to read_pref option
41
31
  def aquire_connection
42
- server ||= case @read_pref
32
+ server = case @read_pref
43
33
  when :primary
44
34
  primary
45
35
  when :secondary
@@ -49,53 +39,24 @@ module Monga::Clients
49
39
  when :secondary_preferred
50
40
  secondary || primary
51
41
  when :nearest
52
- fail "unimplemented read_pref mode"
42
+ raise ArgumentError, "nearest read preferrence is not implemented yet"
53
43
  else
54
- fail "read_pref is undefined"
55
- end
56
-
57
-
58
- if server
59
- if @deferred_status != :succeeded
60
- set_deferred_status :succeeded
61
- @proxy_connection.set_deferred_status :succeeded
62
- end
63
- else
64
- if @deferred_status == :succeeded
65
- set_deferred_status nil
66
- @proxy_connection.set_deferred_status nil
67
- end
44
+ raise ArgumentError, "`#{@read_pref}` is not valid read preferrence, use :primary, :primary_preferred, :secondary, or :secondary_preferred"
68
45
  end
69
46
 
70
47
  server || @proxy_connection
71
48
  end
72
49
 
50
+ # Fetch primary server
73
51
  def primary
74
- prim = @clients.detect{ |c| c.primary? && c.connected? }
75
- unless prim
76
- find_primary!
77
- end
78
- prim
52
+ pr = @clients.detect{ |c| c.primary? && c.connected? }
53
+ pr.aquire_connection if pr
79
54
  end
80
55
 
56
+ # Fetch secondary server
81
57
  def secondary
82
- @clients.select{ |c| !c.primary? && c.connected? }.sample
83
- end
84
-
85
- def find_primary!
86
- unless @pending_primary
87
- @pending_primary = true
88
- @clients.each{ |c| c.find_primary! }
89
- EM.add_timer(0.1) do
90
- if primary
91
- aquire_connection
92
- @pending_primary = false
93
- else
94
- @pending_primary = false
95
- find_primary!
96
- end
97
- end
98
- end
58
+ sc = @clients.select{ |c| c.secondary? && c.connected? }.sample
59
+ sc.aquire_connection if sc
99
60
  end
100
61
  end
101
62
  end
@@ -0,0 +1,53 @@
1
+ module Monga::Clients
2
+ class SingleInstanceClient
3
+ # Status will inform Replica Set client of current client's status
4
+ # primary/secondary/nil
5
+ attr_reader :status
6
+
7
+ def initialize(opts)
8
+ pool_size = opts[:pool_size]
9
+ if pool_size && pool_size > 1
10
+ @connection_pool = Monga::ConnectionPool.new(opts)
11
+ else
12
+ @connection = Monga::Connection.new(opts)
13
+ end
14
+ end
15
+
16
+ # If single connection then return it.
17
+ # If connection pool then aquire connection from pool.
18
+ # If connection is not connected, then status will be setted to nil.
19
+ def aquire_connection
20
+ conn = if @connection_pool
21
+ @connection_pool.aquire_connection
22
+ else
23
+ @connection
24
+ end
25
+ @status = nil unless conn.connected?
26
+ conn
27
+ end
28
+
29
+ def connected?
30
+ aquire_connection.connected?
31
+ end
32
+
33
+ # Check status of connection.
34
+ # If ReplicaSetClient can't find connection with read_pref status
35
+ # it will send foce_status! to all clients while timout happend
36
+ # or while preferred status will be returned
37
+ def force_status!
38
+ conn = aquire_connection
39
+ conn.is_master? do |status|
40
+ @status = status
41
+ yield(@status) if block_given?
42
+ end
43
+ end
44
+
45
+ def primary?
46
+ @status == :primary
47
+ end
48
+
49
+ def secondary?
50
+ @status == :secondary
51
+ end
52
+ end
53
+ end
@@ -1,40 +1,50 @@
1
1
  module Monga
2
2
  class Collection
3
- attr_reader :name, :db
3
+ attr_reader :collection_name
4
4
 
5
- def initialize(db, name)
5
+ def initialize(db, collection_name)
6
6
  @db = db
7
- @name = name
7
+ @collection_name = collection_name
8
8
  end
9
9
 
10
- def query(query = {}, fields = {}, opts = {})
10
+ # Querying database. It returns cursor.
11
+ # Alias to collection#query is colleciotn#find
12
+ #
13
+ # cursor = collection.find(title: "Madonna")
14
+ # # choose fields to return
15
+ # cursor = collection.find({ title: "Madonna" }, { track: 1 })
16
+ # # get all documents
17
+ # cursor.all{ |err, docs| docs.each{ |doc| puts doc } }
18
+ #
19
+ def query(query = {}, selector = {}, opts = {})
11
20
  options = {}
12
21
  options[:query] = query
13
- options[:fields] = fields
14
- options.merge! opts
15
- Monga::Miner.new(db, name, options)
22
+ options[:selector] = selector
23
+ options.merge!(opts)
24
+ Monga::Cursor.create(connection, db_name, collection_name, options)
16
25
  end
17
26
  alias :find :query
18
27
 
19
- def find_one(query = {}, fields = {}, opts = {})
28
+ def find_one(query = {}, selector = {}, opts = {})
20
29
  options = {}
21
30
  options[:query] = query
22
- options[:fields] = fields
23
- options.merge! opts
24
-
25
- Monga::Response.surround do |resp|
26
- req = Monga::Miner.new(db, name, options).limit(1)
27
- req.callback{ |data| resp.succeed data.first }
28
- req.errback{ |err| resp.fail err }
31
+ options[:selector] = selector
32
+ options.merge!(opts)
33
+ Monga::Cursor.create(connection, db_name, collection_name, options).first do |err, resp|
34
+ if block_given?
35
+ yield(err, resp)
36
+ else
37
+ err ? raise(err) : resp
38
+ end
29
39
  end
30
40
  end
31
41
  alias :first :find_one
32
42
 
33
- def insert(documents, opts = {})
43
+ def insert(document, opts = {})
34
44
  options = {}
35
- options[:documents] = documents
45
+ options[:documents] = document
36
46
  options.merge!(opts)
37
- Monga::Requests::Insert.new(@db, @name, options).perform
47
+ Monga::Protocol::Insert.new(connection, db_name, collection_name, options).perform
38
48
  end
39
49
 
40
50
  def update(query = {}, update = {}, flags = {})
@@ -42,67 +52,118 @@ module Monga
42
52
  options[:query] = query
43
53
  options[:update] = update
44
54
  options.merge!(flags)
45
- Monga::Requests::Update.new(@db, @name, options).perform
55
+ Monga::Protocol::Update.new(connection, db_name, collection_name, options).perform
46
56
  end
47
57
 
48
58
  def delete(query = {}, opts = {})
49
59
  options = {}
50
60
  options[:query] = query
51
61
  options.merge!(opts)
52
- Monga::Requests::Delete.new(@db, @name, options).perform
62
+ Monga::Protocol::Delete.new(connection, db_name, collection_name, options).perform
53
63
  end
54
64
  alias :remove :delete
55
65
 
56
66
  def ensure_index(keys, opts={})
57
67
  doc = {}
58
- doc.merge!(opts)
68
+ doc[:key] = keys
59
69
  # Read docs about naming
60
70
  doc[:name] ||= keys.to_a.flatten * "_"
61
- doc[:key] = keys
62
- doc[:ns] = "#{db.name}.#{name}"
63
- Monga::Requests::Insert.new(@db, "system.indexes", {documents: doc}).perform
71
+ doc[:ns] = "#{db_name}.#{collection_name}"
72
+ doc.merge!(opts)
73
+ Monga::Protocol::Insert.new(connection, db_name, "system.indexes", {documents: doc}).perform
64
74
  end
65
75
 
66
76
  def drop_index(indexes)
67
- @db.drop_indexes(@name, indexes)
77
+ @db.drop_indexes(@collection_name, indexes) do |err, resp|
78
+ if block_given?
79
+ yield(err, resp)
80
+ else
81
+ raise err if err
82
+ return resp
83
+ end
84
+ end
68
85
  end
69
86
 
70
87
  def drop_indexes
71
- @db.drop_indexes(@name, "*")
88
+ @db.drop_indexes(@collection_name, "*") do |err, resp|
89
+ if block_given?
90
+ yield(err, resp)
91
+ else
92
+ raise err if err
93
+ return resp
94
+ end
95
+ end
72
96
  end
73
97
 
74
98
  def get_indexes
75
- Monga::Miner.new(@db, "system.indexes")
99
+ Monga::Cursor.create(connection, db_name, "system.indexes").all do |err, resp|
100
+ if block_given?
101
+ yield(err, resp)
102
+ else
103
+ raise err if err
104
+ return resp
105
+ end
106
+ end
76
107
  end
77
108
 
78
109
  def drop
79
- @db.drop_collection(@name)
110
+ @db.drop_collection(@collection_name) do |err, resp|
111
+ if block_given?
112
+ yield(err, resp)
113
+ else
114
+ raise err if err
115
+ return resp
116
+ end
117
+ end
80
118
  end
81
119
 
82
- def count
83
- @db.count(@name)
120
+ # You could pass query/limit/skip options
121
+ #
122
+ # count(query: {artist: "Madonna"}, limit: 10, skip: 0)
123
+ #
124
+ def count(opts = {})
125
+ @db.count(@collection_name, opts) do |err, resp|
126
+ if block_given?
127
+ yield(err, resp)
128
+ else
129
+ raise err if err
130
+ return resp
131
+ end
132
+ end
84
133
  end
85
134
 
86
135
  # Safe methods
87
136
  [:update, :insert, :delete, :remove, :ensure_index].each do |meth|
88
137
  class_eval <<-EOS
89
138
  def safe_#{meth}(*args)
90
- safe do
91
- #{meth}(*args)
139
+ last = args.last
140
+ opts = {}
141
+ if Hash === last
142
+ [ :j, :w, :fsync, :wtimeout ].each do |k|
143
+ v = last.delete k
144
+ opts[k] = v if v
145
+ end
146
+ end
147
+ req = #{meth}(*args)
148
+ @db.raise_last_error(req.connection, opts) do |err, resp|
149
+ if block_given?
150
+ yield(err, resp)
151
+ else
152
+ err ? raise(err) : resp
153
+ end
92
154
  end
93
155
  end
94
156
  EOS
95
157
  end
96
158
 
97
- def safe
98
- response = Monga::Response.new
99
- request_id = yield
100
- req = @db.get_last_error
101
- req.callback do |data|
102
- response.succeed(request_id)
103
- end
104
- req.errback{ |err| response.fail(err) }
105
- response
159
+ private
160
+
161
+ def connection
162
+ @db.client.aquire_connection
163
+ end
164
+
165
+ def db_name
166
+ @db.name
106
167
  end
107
168
  end
108
169
  end
@@ -1,23 +1,48 @@
1
- require File.expand_path("../connections/em_connection", __FILE__)
2
- require File.expand_path("../connections/primary", __FILE__)
3
- require File.expand_path("../connections/secondary", __FILE__)
4
-
5
1
  module Monga
6
2
  class Connection
7
3
  extend Forwardable
8
4
 
9
- def_delegators :@connection, :connected?, :reconnect, :responses, :send_command, :master?, :is_master?, :host, :port
5
+ def_delegators :@connection, :connected?, :responses, :send_command, :is_master?, :port
6
+
7
+ attr_reader :type
10
8
 
11
- CONNECTION_TYPES = {
12
- default: Monga::Connections::EMConnection,
13
- primary: Monga::Connections::Primary,
14
- secondary: Monga::Connections::Secondary,
9
+ CONNECTIONS = {
10
+ em: Monga::Connections::EMConnection,
11
+ sync: Monga::Connections::FiberedConnection,
12
+ block: Monga::Connections::TCPConnection,
15
13
  }
14
+ PROXY_CONNECTIONS = {
15
+ em: Monga::Connections::EMProxyConnection,
16
+ sync: Monga::Connections::FiberedProxyConnection,
17
+ block: Monga::Connections::ProxyConnection,
18
+ }
19
+
20
+ # Simple connection wrapper.
21
+ # Accpets
22
+ # * host/port or server
23
+ # * connection type
24
+ # * timeout
25
+ def initialize(opts)
26
+ @type = opts[:type]
27
+
28
+ host, port = if server = opts[:server]
29
+ h, p = server.split(":")
30
+ [h, p.to_i]
31
+ else
32
+ h = opts[:host] || Monga::DEFAULT_HOST
33
+ p = opts[:port] || Monga::DEFAULT_PORT
34
+ [h, p]
35
+ end
36
+ timeout = opts[:timeout]
37
+
38
+ conn_type = CONNECTIONS[@type]
39
+ raise Monga::Exceptions::WrongConnectionType, "Connection type `#{opts[:type]}` is non valid, choose one of: :em, :sync, or :block" unless conn_type
40
+ @connection = conn_type.connect(host, port, timeout)
41
+ end
16
42
 
17
- def initialize(opts={})
18
- conn_type = opts.delete(:connection_type) || :default
19
- conn_class = CONNECTION_TYPES[conn_type]
20
- @connection = conn_class.connect(opts)
43
+ # Returns name of proxy_connection class
44
+ def self.proxy_connection_class(type)
45
+ PROXY_CONNECTIONS[type]
21
46
  end
22
47
  end
23
48
  end
@@ -1,20 +1,18 @@
1
1
  module Monga
2
- class ConnectionPool < Monga::Connection
3
- extend Forwardable
4
-
5
- def_delegators :aquire_connection, :send_command
6
-
2
+ class ConnectionPool
7
3
  attr_reader :connections
8
-
9
- def initialize(opts={})
10
- @connections = []
4
+
5
+ def initialize(opts)
11
6
  pool_size = opts.delete :pool_size
12
7
 
8
+ @connections = []
13
9
  pool_size.times do
14
10
  @connections << Monga::Connection.new(opts)
15
11
  end
16
12
  end
17
13
 
14
+ # Aquires random connection with min waiting responses among connected.
15
+ # Otherwise return random disconnected one.
18
16
  def aquire_connection
19
17
  connected = @connections.select(&:connected?)
20
18
  if connected.any?
@@ -25,14 +23,5 @@ module Monga
25
23
  @connections.sample
26
24
  end
27
25
  end
28
-
29
- def primary?
30
- conn = aquire_connection
31
- conn ? conn.master? : false
32
- end
33
-
34
- def connected?
35
- @connections.any?(&:connected?)
36
- end
37
26
  end
38
27
  end