monga 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
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