monga 0.0.3 → 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.
- data/.gitignore +0 -1
- data/README.md +76 -34
- data/benchmarks/inserts.rb +87 -0
- data/benchmarks/prof.rb +26 -0
- data/lib/monga/clients/replica_set_client.rb +4 -2
- data/lib/monga/collection.rb +1 -1
- data/lib/monga/connection.rb +4 -3
- data/lib/monga/connections/buffer.rb +62 -15
- data/lib/monga/connections/em_proxy_connection.rb +7 -7
- data/lib/monga/connections/kgio_connection.rb +93 -0
- data/lib/monga/connections/proxy_connection.rb +57 -0
- data/lib/monga/connections/tcp_connection.rb +3 -1
- data/lib/monga/cursor.rb +25 -13
- data/lib/monga/database.rb +9 -2
- data/lib/monga/protocol/delete.rb +5 -6
- data/lib/monga/protocol/get_more.rb +5 -6
- data/lib/monga/protocol/insert.rb +5 -6
- data/lib/monga/protocol/kill_cursors.rb +3 -7
- data/lib/monga/protocol/query.rb +6 -8
- data/lib/monga/protocol/update.rb +6 -7
- data/lib/monga/request.rb +3 -18
- data/lib/monga/utils/constants.rb +1 -0
- data/lib/monga.rb +2 -0
- data/monga.gemspec +3 -1
- data/spec/helpers/mongodb.rb +1 -1
- data/spec/monga/block/cursor_spec.rb +3 -3
- data/spec/monga/block/replica_set_client_spec.rb +58 -0
- data/spec/monga/block/single_instance_client_spec.rb +6 -8
- data/spec/monga/em/cursor_spec.rb +4 -7
- data/spec/monga/sync/cursor_spec.rb +3 -3
- data/spec/monga/sync/replica_set_client_spec.rb +4 -4
- metadata +41 -4
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -1,65 +1,107 @@
|
|
1
1
|
[](https://travis-ci.org/fl00r/monga)
|
2
2
|
|
3
|
-
|
3
|
+
This client is under development. You can try
|
4
|
+
|
5
|
+
* [em-mongo](https://github.com/bcg/em-mongo) with Eventmachine inside
|
6
|
+
* Official [mongo-ruby-driver](https://github.com/mongodb/mongo-ruby-driver) from 10gen
|
7
|
+
* [Moped](http://mongoid.org/en/moped/) from Mongoid guys
|
4
8
|
|
5
|
-
|
9
|
+
# Monga
|
6
10
|
|
7
|
-
|
11
|
+
Yet another [MongoDB](http://www.mongodb.org/) Ruby Client.
|
8
12
|
|
9
|
-
|
13
|
+
It supports three kind of interfaces:
|
10
14
|
|
11
|
-
|
15
|
+
* Asynchronous over [EventMachine](https://github.com/eventmachine/eventmachine)
|
16
|
+
* Synchronous (on Fibers)
|
17
|
+
* Blocking (over TCPSocket, [kgio](http://bogomips.org/kgio/) actually)
|
12
18
|
|
13
|
-
|
19
|
+
## Introduction
|
14
20
|
|
15
|
-
API will be familiar to Node.js developers
|
21
|
+
Asynchronous API will be familiar to Node.js developers. Instead of Deferrable Object you will receive `err, response` into callback.
|
16
22
|
|
17
23
|
```ruby
|
18
|
-
# Async mode
|
19
24
|
EM.run do
|
20
|
-
|
21
|
-
db =
|
25
|
+
client = Monga::Client.new(type: :em)
|
26
|
+
db = client["testDb"]
|
22
27
|
collection = db["testCollection"]
|
23
|
-
|
28
|
+
|
29
|
+
# Fire and forget
|
30
|
+
collection.insert(artist: "Madonna", title: "Frozen")
|
31
|
+
|
32
|
+
# Safe method
|
33
|
+
collection.safe_insert(artist: "Madonna", title: "Burning Up") do |err, response|
|
24
34
|
if err
|
25
|
-
puts "
|
35
|
+
puts "Ha, an error! #{err.message}"
|
26
36
|
else
|
27
|
-
puts "
|
28
|
-
|
29
|
-
|
30
|
-
|
37
|
+
puts "Job is done. Let's do more job"
|
38
|
+
|
39
|
+
# Cursor
|
40
|
+
collection.find.batch_size(100).limit(500).each_doc do |err, doc, iter|
|
41
|
+
if iter
|
42
|
+
puts "What have we got here: #{doc['title']}"
|
43
|
+
iter.next
|
31
44
|
else
|
32
|
-
puts "
|
45
|
+
puts "No more documents in collection"
|
46
|
+
EM.stop
|
33
47
|
end
|
34
|
-
EM.stop
|
35
48
|
end
|
49
|
+
# Yes, you should call `iter.next`, welcome to callback world!
|
36
50
|
end
|
37
51
|
end
|
38
52
|
end
|
53
|
+
```
|
54
|
+
|
55
|
+
Synchronous mode is more simple. It is just like blocking mode, but you can use pool of fibers to make it as fast as lightning.
|
39
56
|
|
40
|
-
|
57
|
+
```ruby
|
41
58
|
EM.synchrony do
|
42
|
-
|
43
|
-
db =
|
59
|
+
client = Monga::Client.new(type: :sync)
|
60
|
+
db = client["testDb"]
|
44
61
|
collection = db["testCollection"]
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
62
|
+
|
63
|
+
# Fire and forget
|
64
|
+
collection.insert(artist: "Madonna", title: "Frozen")
|
65
|
+
|
66
|
+
# Safe method
|
67
|
+
collection.safe_insert(artist: "Madonna", title: "Burning Up")
|
68
|
+
puts "Job is done"
|
69
|
+
|
70
|
+
# Cursor
|
71
|
+
docs = []
|
72
|
+
collection.find.batch_size(100).limit(500).each_doc do |doc|
|
73
|
+
puts "What have we got here: #{doc['title']}"
|
74
|
+
docs << doc
|
75
|
+
end
|
76
|
+
puts "We have got #{docs.size} documents in this pretty array"
|
77
|
+
|
49
78
|
EM.stop
|
50
79
|
end
|
80
|
+
```
|
81
|
+
|
82
|
+
Blocking mode is as simple as a potato
|
51
83
|
|
52
|
-
|
53
|
-
|
54
|
-
|
84
|
+
```ruby
|
85
|
+
# client = Monga::Client.new(type: :block)
|
86
|
+
client = Monga::Client.new
|
87
|
+
db = client["testDb"]
|
55
88
|
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
89
|
|
62
|
-
|
90
|
+
# Fire and forget
|
91
|
+
collection.insert(artist: "Madonna", title: "Frozen")
|
92
|
+
|
93
|
+
# Safe method
|
94
|
+
collection.safe_insert(artist: "Madonna", title: "Burning Up")
|
95
|
+
puts "Job is done"
|
96
|
+
|
97
|
+
# Cursor
|
98
|
+
docs = []
|
99
|
+
collection.find.batch_size(100).limit(500).each_doc do |doc|
|
100
|
+
puts "What have we got here: #{doc['title']}"
|
101
|
+
docs << doc
|
102
|
+
end
|
103
|
+
puts "We have got #{docs.size} documents in this pretty array"
|
104
|
+
```
|
63
105
|
|
64
106
|
## To Do List
|
65
107
|
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'benchmark'
|
2
|
+
require 'mongo'
|
3
|
+
require 'moped'
|
4
|
+
require File.expand_path('../../lib/monga', __FILE__)
|
5
|
+
|
6
|
+
include Mongo
|
7
|
+
|
8
|
+
Benchmark.bm do |x|
|
9
|
+
total = 10000
|
10
|
+
fetch = 50
|
11
|
+
mongo_collection = MongoClient.new.db("dbTest").collection("testCollection")
|
12
|
+
monga_collection = Monga::Client.new(type: :block).get_database("dbTest").get_collection("testCollection")
|
13
|
+
Monga.logger.level = Logger::ERROR
|
14
|
+
moped_session = Moped::Session.new([ "127.0.0.1:27017" ])
|
15
|
+
moped_session.use "dbTest"
|
16
|
+
|
17
|
+
document = {}
|
18
|
+
document[:title] = "Some title"
|
19
|
+
chars = ('a'..'z').to_a
|
20
|
+
document[:body] = 100.times.map{ chars.sample } * ""
|
21
|
+
|
22
|
+
sleep 0.5
|
23
|
+
|
24
|
+
GC.start
|
25
|
+
|
26
|
+
x.report("Inserting with mongo") do
|
27
|
+
total.times do |i|
|
28
|
+
mongo_collection.insert(document.dup)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
GC.start
|
33
|
+
|
34
|
+
x.report("Fetching with mongo") do
|
35
|
+
fetch.times do
|
36
|
+
mongo_collection.find.to_a
|
37
|
+
end
|
38
|
+
end
|
39
|
+
mongo_collection.drop
|
40
|
+
|
41
|
+
sleep 0.5
|
42
|
+
|
43
|
+
GC.start
|
44
|
+
|
45
|
+
x.report("Inserting with monga") do
|
46
|
+
total.times do |i|
|
47
|
+
monga_collection.safe_insert(document.dup)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
GC.start
|
52
|
+
|
53
|
+
x.report("Fetching with monga") do
|
54
|
+
fetch.times do
|
55
|
+
monga_collection.find.all
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
monga_collection.drop
|
60
|
+
|
61
|
+
sleep 0.5
|
62
|
+
|
63
|
+
GC.start
|
64
|
+
|
65
|
+
x.report("Inserting with moped") do
|
66
|
+
moped_session.with(safe: true) do |safe|
|
67
|
+
total.times do |i|
|
68
|
+
safe[:testCollection].insert(document)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
GC.start
|
74
|
+
|
75
|
+
x.report("Fetching with moped") do
|
76
|
+
fetch.times do
|
77
|
+
moped_session[:testCollection].find.to_a
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
monga_collection.drop
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
|
86
|
+
|
87
|
+
|
data/benchmarks/prof.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'ruby-prof'
|
2
|
+
require File.expand_path('../../lib/monga', __FILE__)
|
3
|
+
require 'mongo'
|
4
|
+
include Mongo
|
5
|
+
|
6
|
+
total = 100
|
7
|
+
# monga_collection = Monga::Client.new(type: :block).get_database("dbTest").get_collection("testCollection")
|
8
|
+
mongo_collection = MongoClient.new.db("dbTest").collection("testCollection")
|
9
|
+
|
10
|
+
total.times do |i|
|
11
|
+
mongo_collection.insert(title: "Row #{i}")
|
12
|
+
end
|
13
|
+
RubyProf.start
|
14
|
+
mongo_collection.find.to_a
|
15
|
+
|
16
|
+
result = RubyProf.stop
|
17
|
+
mongo_collection.drop
|
18
|
+
|
19
|
+
# Print a flat profile to text
|
20
|
+
printer = RubyProf::FlatPrinter.new(result)
|
21
|
+
printer.print(STDOUT)
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
mongo_collection = MongoClient.new.db("dbTest").collection("testCollection")
|
26
|
+
mongo_collection.find.to_a
|
@@ -14,7 +14,7 @@ module Monga::Clients
|
|
14
14
|
|
15
15
|
servers = opts.delete :servers
|
16
16
|
@clients = servers.map do |server|
|
17
|
-
case server
|
17
|
+
c = case server
|
18
18
|
when Hash
|
19
19
|
Monga::Clients::SingleInstanceClient.new(opts.merge(server))
|
20
20
|
when String
|
@@ -22,9 +22,11 @@ module Monga::Clients
|
|
22
22
|
o = { host: h, port: p.to_i }
|
23
23
|
Monga::Clients::SingleInstanceClient.new(opts.merge(o))
|
24
24
|
end
|
25
|
+
c.force_status!
|
26
|
+
c
|
25
27
|
end
|
26
28
|
|
27
|
-
@proxy_connection = Monga::Connection.proxy_connection_class(opts[:type]
|
29
|
+
@proxy_connection = Monga::Connection.proxy_connection_class(opts[:type], self)
|
28
30
|
end
|
29
31
|
|
30
32
|
# Aquires connection due to read_pref option
|
data/lib/monga/collection.rb
CHANGED
data/lib/monga/connection.rb
CHANGED
@@ -9,7 +9,7 @@ module Monga
|
|
9
9
|
CONNECTIONS = {
|
10
10
|
em: Monga::Connections::EMConnection,
|
11
11
|
sync: Monga::Connections::FiberedConnection,
|
12
|
-
block: Monga::Connections::
|
12
|
+
block: Monga::Connections::KGIOConnection,
|
13
13
|
}
|
14
14
|
PROXY_CONNECTIONS = {
|
15
15
|
em: Monga::Connections::EMProxyConnection,
|
@@ -41,8 +41,9 @@ module Monga
|
|
41
41
|
end
|
42
42
|
|
43
43
|
# Returns name of proxy_connection class
|
44
|
-
def self.proxy_connection_class(type)
|
45
|
-
PROXY_CONNECTIONS[type]
|
44
|
+
def self.proxy_connection_class(type, client)
|
45
|
+
conn_class = PROXY_CONNECTIONS[type]
|
46
|
+
conn_class.new(client) if conn_class
|
46
47
|
end
|
47
48
|
end
|
48
49
|
end
|
@@ -1,33 +1,80 @@
|
|
1
1
|
module Monga::Connections
|
2
2
|
class Buffer
|
3
|
-
include Enumerable
|
3
|
+
# include Enumerable
|
4
4
|
|
5
|
-
attr_reader :buffer
|
5
|
+
attr_reader :buffer, :responses
|
6
6
|
|
7
7
|
def initialize
|
8
8
|
@buffer = ""
|
9
|
-
@
|
9
|
+
@position = 0
|
10
|
+
@docs = []
|
11
|
+
@responses = []
|
10
12
|
end
|
11
13
|
|
12
14
|
def append(data)
|
13
|
-
@buffer
|
15
|
+
@buffer << data
|
16
|
+
@buffer_size = @buffer.bytesize
|
17
|
+
job
|
18
|
+
@buffer
|
14
19
|
end
|
15
20
|
|
16
|
-
def
|
21
|
+
def job
|
22
|
+
parse_meta if @position == 0
|
23
|
+
parse_doc if @position > 0
|
24
|
+
end
|
25
|
+
|
26
|
+
def parse_meta
|
27
|
+
return if @buffer_size < 36
|
28
|
+
@response = []
|
29
|
+
@response << ::BinUtils.get_int32_le(@buffer, @position)
|
30
|
+
@response << ::BinUtils.get_int32_le(@buffer, @position += 4)
|
31
|
+
@response << ::BinUtils.get_int32_le(@buffer, @position += 4)
|
32
|
+
@response << ::BinUtils.get_int32_le(@buffer, @position += 4)
|
33
|
+
@response << ::BinUtils.get_int32_le(@buffer, @position += 4)
|
34
|
+
@response << ::BinUtils.get_int64_le(@buffer, @position += 4)
|
35
|
+
@response << ::BinUtils.get_int32_le(@buffer, @position += 8)
|
36
|
+
@response << (@number_returned = ::BinUtils.get_int32_le(@buffer, @position += 4))
|
37
|
+
@response << []
|
38
|
+
|
39
|
+
@position += 4
|
40
|
+
end
|
41
|
+
|
42
|
+
def parse_doc
|
17
43
|
while true
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
44
|
+
if @number_returned == 0
|
45
|
+
done
|
46
|
+
break
|
47
|
+
end
|
48
|
+
break if @buffer_size < @position + 4
|
49
|
+
doc_length = ::BinUtils.get_int32_le(@buffer, @position)
|
50
|
+
break if @buffer_size < @position + doc_length
|
51
|
+
doc = @buffer[@position, doc_length]
|
52
|
+
@response[-1] << CBson.deserialize(doc)
|
53
|
+
@position += doc_length
|
54
|
+
@number_returned -= 1
|
55
|
+
if @number_returned == 0
|
56
|
+
done
|
28
57
|
break
|
29
58
|
end
|
30
59
|
end
|
31
60
|
end
|
61
|
+
|
62
|
+
def each
|
63
|
+
while resp = @responses.shift
|
64
|
+
yield resp
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def done
|
69
|
+
@responses << @response
|
70
|
+
@response = nil
|
71
|
+
if @buffer_size == @position
|
72
|
+
@buffer.clear
|
73
|
+
else
|
74
|
+
@buffer = @buffer[@position, @buffer_size-@position]
|
75
|
+
end
|
76
|
+
@buffer_size = @buffer.bytesize
|
77
|
+
@position = 0
|
78
|
+
end
|
32
79
|
end
|
33
80
|
end
|
@@ -66,14 +66,14 @@ module Monga::Connections
|
|
66
66
|
end
|
67
67
|
end
|
68
68
|
end
|
69
|
+
end
|
69
70
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
end
|
71
|
+
# YEEEHA! Send all collected requests back to client
|
72
|
+
def server_found!
|
73
|
+
@pending_timeout = false
|
74
|
+
@requests.keys.each do |request_id|
|
75
|
+
msg, blk = @requests.delete request_id
|
76
|
+
@client.aquire_connection.send_command(msg, request_id, &blk)
|
77
77
|
end
|
78
78
|
end
|
79
79
|
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'kgio'
|
2
|
+
require 'io/nonblock'
|
3
|
+
module Monga::Connections
|
4
|
+
class KGIOConnection
|
5
|
+
def self.connect(host, port, timeout)
|
6
|
+
new(host, port, timeout)
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(host, port, timeout)
|
10
|
+
@host, @port, @timout = host, port, timeout
|
11
|
+
@connected = true
|
12
|
+
@buffer = Buffer.new
|
13
|
+
end
|
14
|
+
|
15
|
+
def connected?
|
16
|
+
@connected
|
17
|
+
end
|
18
|
+
|
19
|
+
def socket
|
20
|
+
@socket ||= begin
|
21
|
+
sock = Kgio::TCPSocket.new(@host, @port)
|
22
|
+
sock.kgio_autopush = true
|
23
|
+
@connected = true
|
24
|
+
sock
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# Fake answer, as far as we are blocking
|
29
|
+
def responses
|
30
|
+
0
|
31
|
+
end
|
32
|
+
|
33
|
+
def send_command(msg, request_id=nil, &cb)
|
34
|
+
socket.kgio_write msg.to_s
|
35
|
+
if cb
|
36
|
+
read_socket
|
37
|
+
|
38
|
+
message = @buffer.responses.shift
|
39
|
+
rid = message[2]
|
40
|
+
|
41
|
+
fail "Returned Request Id is not equal to sended one (#{rid} != #{request_id}), #{message}" if rid != request_id
|
42
|
+
|
43
|
+
cb.call(message)
|
44
|
+
end
|
45
|
+
rescue Errno::ECONNREFUSED, Errno::EPIPE => e
|
46
|
+
close
|
47
|
+
if cb
|
48
|
+
err = Monga::Exceptions::Disconnected.new("Disconnected from #{@host}:#{@port}, #{e.message}")
|
49
|
+
cb.call(err)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def read_socket
|
54
|
+
torecv = 512
|
55
|
+
length = nil
|
56
|
+
buf = ''.force_encoding('ASCII-8BIT')
|
57
|
+
tmp = ''
|
58
|
+
while torecv > 0
|
59
|
+
resp = socket.kgio_read(torecv, tmp)
|
60
|
+
raise Errno::ECONNREFUSED.new "Nil was return. Closing connection" unless resp
|
61
|
+
buf << resp
|
62
|
+
size = buf.bytesize
|
63
|
+
length ||= ::BinUtils.get_int32_le(buf) if size > 4
|
64
|
+
torecv = length - size if length
|
65
|
+
end
|
66
|
+
@buffer.append(buf)
|
67
|
+
end
|
68
|
+
|
69
|
+
def primary?
|
70
|
+
@primary || false
|
71
|
+
end
|
72
|
+
|
73
|
+
def is_master?
|
74
|
+
req = Monga::Protocol::Query.new(self, "admin", "$cmd", query: {"isMaster" => 1}, limit: 1)
|
75
|
+
command = req.command
|
76
|
+
request_id = req.request_id
|
77
|
+
socket.kgio_write command
|
78
|
+
read_socket
|
79
|
+
message = @buffer.responses.shift
|
80
|
+
@primary = message.last.first["ismaster"]
|
81
|
+
yield @primary ? :primary : :secondary
|
82
|
+
rescue => e
|
83
|
+
close
|
84
|
+
yield nil
|
85
|
+
end
|
86
|
+
|
87
|
+
def close
|
88
|
+
@socket = nil
|
89
|
+
@primary = false
|
90
|
+
@connected = false
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -1,4 +1,61 @@
|
|
1
|
+
require 'timeout'
|
2
|
+
|
1
3
|
module Monga::Connections
|
2
4
|
class ProxyConnection
|
5
|
+
# Pause while searching server in seconds
|
6
|
+
WAIT = 0.1
|
7
|
+
|
8
|
+
def initialize(client)
|
9
|
+
@client = client
|
10
|
+
@timeout = @client.timeout
|
11
|
+
@requests = {}
|
12
|
+
end
|
13
|
+
|
14
|
+
# If timeout is defined then collect request and start timout.
|
15
|
+
# If timout is not defined or zero then return exception.
|
16
|
+
def send_command(msg, request_id = nil, &cb)
|
17
|
+
if @timeout && @timeout > 0
|
18
|
+
@requests[request_id] = [msg, cb] if cb
|
19
|
+
set_timeout
|
20
|
+
else
|
21
|
+
error = Monga::Exceptions::Disconnected.new "Can't find appropriate server (all disconnected)"
|
22
|
+
cb.call(error) if cb
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# If timeout happend send exception to all collected requests.
|
27
|
+
def set_timeout
|
28
|
+
@not_found = true
|
29
|
+
Timeout::timeout(@timeout) do
|
30
|
+
while @not_found
|
31
|
+
find_server!
|
32
|
+
sleep(WAIT)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Find server unless server is found
|
38
|
+
def find_server!
|
39
|
+
@client.clients.each do |client|
|
40
|
+
client.force_status! do |status|
|
41
|
+
if status == :primary && [:primary, :primary_preferred, :secondary_preferred].include?(@client.read_pref)
|
42
|
+
@pending_server = false
|
43
|
+
server_found!
|
44
|
+
elsif status == :secondary && [:secondary, :primary_preferred, :secondary_preferred].include?(@client.read_pref)
|
45
|
+
@pending_server = false
|
46
|
+
server_found!
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# YEEEHA! Send all collected requests back to client
|
53
|
+
def server_found!
|
54
|
+
@not_found = false
|
55
|
+
@requests.keys.each do |request_id|
|
56
|
+
msg, blk = @requests.delete request_id
|
57
|
+
@client.aquire_connection.send_command(msg, request_id, &blk)
|
58
|
+
end
|
59
|
+
end
|
3
60
|
end
|
4
61
|
end
|
data/lib/monga/cursor.rb
CHANGED
@@ -154,9 +154,16 @@ module Monga
|
|
154
154
|
end
|
155
155
|
|
156
156
|
def each_batch(&blk)
|
157
|
+
iter_more = true
|
157
158
|
iterator = Proc.new do
|
158
|
-
|
159
|
-
|
159
|
+
if iter_more
|
160
|
+
next_batch do |err, batch, more|
|
161
|
+
iter_more = more
|
162
|
+
(more || batch || err) ? blk.call(err, batch, iterator) : blk.call
|
163
|
+
end
|
164
|
+
else
|
165
|
+
# iteration stopped
|
166
|
+
blk.call
|
160
167
|
end
|
161
168
|
end
|
162
169
|
class << iterator
|
@@ -184,9 +191,16 @@ module Monga
|
|
184
191
|
alias :next_document :next_doc
|
185
192
|
|
186
193
|
def each_doc(&blk)
|
194
|
+
iter_more = true
|
187
195
|
iterator = Proc.new do
|
188
|
-
|
189
|
-
|
196
|
+
if iter_more
|
197
|
+
next_doc do |err, doc, more|
|
198
|
+
iter_more = more
|
199
|
+
(more || doc || err) ? blk.call(err, doc, iterator) : blk.call
|
200
|
+
end
|
201
|
+
else
|
202
|
+
# iteration stopped
|
203
|
+
blk.call
|
190
204
|
end
|
191
205
|
end
|
192
206
|
class << iterator
|
@@ -202,8 +216,8 @@ module Monga
|
|
202
216
|
if err
|
203
217
|
block_given? ? yield(err) : raise(err)
|
204
218
|
else
|
205
|
-
documents += batch
|
206
219
|
if iter
|
220
|
+
documents += batch
|
207
221
|
iter.next
|
208
222
|
else
|
209
223
|
block_given? ? yield(nil, documents) : documents
|
@@ -231,7 +245,7 @@ module Monga
|
|
231
245
|
end
|
232
246
|
end
|
233
247
|
|
234
|
-
def each_batch
|
248
|
+
def each_batch
|
235
249
|
begin
|
236
250
|
batch, more = next_batch
|
237
251
|
yield batch
|
@@ -242,13 +256,11 @@ module Monga
|
|
242
256
|
if doc = @fetched_docs.shift
|
243
257
|
[doc, more?]
|
244
258
|
else
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
return [doc, m]
|
251
|
-
end
|
259
|
+
batch, more = next_batch
|
260
|
+
@fetched_docs = batch
|
261
|
+
doc = @fetched_docs.shift
|
262
|
+
m = more || @fetched_docs.any?
|
263
|
+
return [doc, m]
|
252
264
|
end
|
253
265
|
end
|
254
266
|
alias :next_document :next_doc
|
data/lib/monga/database.rb
CHANGED
@@ -75,7 +75,12 @@ module Monga
|
|
75
75
|
cmd = {}
|
76
76
|
cmd[:getLastError] = 1
|
77
77
|
cmd[:connection] = connection
|
78
|
-
|
78
|
+
|
79
|
+
cmd[:j] = opts[:j] if opts[:j]
|
80
|
+
cmd[:fsync] = opts[:fsync] if opts[:fsync]
|
81
|
+
cmd[:w] = opts[:w] if opts[:w]
|
82
|
+
cmd[:wtimeout] = opts[:wtimeout] if opts[:wtimeout]
|
83
|
+
|
79
84
|
run_cmd(cmd, blk)
|
80
85
|
end
|
81
86
|
|
@@ -170,7 +175,9 @@ module Monga
|
|
170
175
|
|
171
176
|
Monga::CallbackCursor.new(connection, name, "$cmd", options).first do |err, resp|
|
172
177
|
res = make_response(err, resp, ret_blk, resp_blk)
|
173
|
-
|
178
|
+
unless ret_blk
|
179
|
+
return res
|
180
|
+
end
|
174
181
|
end
|
175
182
|
end
|
176
183
|
|
@@ -10,12 +10,11 @@ module Monga::Protocol
|
|
10
10
|
@body ||= begin
|
11
11
|
query = @options[:query]
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
b
|
13
|
+
msg = ::BinUtils.append_int32_le!(nil, 0)
|
14
|
+
msg << full_name << Monga::NULL_BYTE
|
15
|
+
::BinUtils.append_int32_le!(msg, flags)
|
16
|
+
msg << BSON::BSON_C.serialize(query).to_s
|
17
|
+
msg
|
19
18
|
end
|
20
19
|
end
|
21
20
|
end
|
@@ -7,12 +7,11 @@ module Monga::Protocol
|
|
7
7
|
batch_size = @options[:batch_size] || 0
|
8
8
|
cursor_id = @options[:cursor_id]
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
b
|
10
|
+
msg = ::BinUtils.append_int32_le!(nil, 0)
|
11
|
+
msg << full_name << Monga::NULL_BYTE
|
12
|
+
::BinUtils.append_int32_le!(msg, batch_size)
|
13
|
+
::BinUtils.append_int64_le!(msg, cursor_id)
|
14
|
+
msg
|
16
15
|
end
|
17
16
|
end
|
18
17
|
end
|
@@ -10,18 +10,17 @@ module Monga::Protocol
|
|
10
10
|
@body ||= begin
|
11
11
|
documents = @options[:documents]
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
BSON::BSON_RUBY.serialize_cstr(b, full_name)
|
13
|
+
msg = ::BinUtils.append_int32_le!(nil, flags)
|
14
|
+
msg << full_name << Monga::NULL_BYTE
|
16
15
|
case documents
|
17
16
|
when Array
|
18
17
|
documents.each do |doc|
|
19
|
-
|
18
|
+
msg << BSON::BSON_C.serialize(doc).to_s
|
20
19
|
end
|
21
20
|
when Hash
|
22
|
-
|
21
|
+
msg << BSON::BSON_C.serialize(documents).to_s
|
23
22
|
end
|
24
|
-
|
23
|
+
msg
|
25
24
|
end
|
26
25
|
end
|
27
26
|
end
|
@@ -12,13 +12,9 @@ module Monga::Protocol
|
|
12
12
|
@body ||= begin
|
13
13
|
cursor_ids = @options[:cursor_ids]
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
cursor_ids.each do |cursor_id|
|
19
|
-
b.put_long(cursor_id)
|
20
|
-
end
|
21
|
-
b
|
15
|
+
msg = ::BinUtils.append_int32_le!(nil, 0, cursor_ids.size)
|
16
|
+
::BinUtils.append_int64_le!(msg, 0, *cursor_ids)
|
17
|
+
msg
|
22
18
|
end
|
23
19
|
end
|
24
20
|
end
|
data/lib/monga/protocol/query.rb
CHANGED
@@ -23,14 +23,12 @@ module Monga::Protocol
|
|
23
23
|
query["$orderby"] = @options[:sort] if @options[:sort]
|
24
24
|
query["$explain"] = @options[:explain] if @options[:explain]
|
25
25
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
b.append!(BSON::BSON_C.serialize(selector).to_s) if selector.any?
|
33
|
-
b
|
26
|
+
msg = ::BinUtils.append_int32_le!(nil, flags)
|
27
|
+
msg << full_name << Monga::NULL_BYTE
|
28
|
+
::BinUtils.append_int32_le!(msg, skip, limit)
|
29
|
+
msg << BSON::BSON_C.serialize(query).to_s
|
30
|
+
msg << BSON::BSON_C.serialize(selector).to_s if selector.any?
|
31
|
+
msg
|
34
32
|
end
|
35
33
|
end
|
36
34
|
|
@@ -12,13 +12,12 @@ module Monga::Protocol
|
|
12
12
|
query = @options[:query]
|
13
13
|
update = @options[:update]
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
b
|
15
|
+
msg = ::BinUtils.append_int32_le!(nil, 0)
|
16
|
+
msg << full_name << Monga::NULL_BYTE
|
17
|
+
::BinUtils.append_int32_le!(msg, flags)
|
18
|
+
msg << BSON::BSON_C.serialize(query).to_s
|
19
|
+
msg << BSON::BSON_C.serialize(update).to_s
|
20
|
+
msg
|
22
21
|
end
|
23
22
|
end
|
24
23
|
end
|
data/lib/monga/request.rb
CHANGED
@@ -24,16 +24,11 @@ module Monga
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def command
|
27
|
-
header
|
27
|
+
header + body
|
28
28
|
end
|
29
29
|
|
30
30
|
def header
|
31
|
-
|
32
|
-
headers.put_int(command_length)
|
33
|
-
headers.put_int(@request_id)
|
34
|
-
headers.put_int(0)
|
35
|
-
headers.put_int(op_code)
|
36
|
-
headers
|
31
|
+
::BinUtils.append_int32_le!(nil, command_length, @request_id, 0, op_code)
|
37
32
|
end
|
38
33
|
|
39
34
|
# Fire and Forget
|
@@ -59,9 +54,7 @@ module Monga
|
|
59
54
|
[data, nil]
|
60
55
|
else
|
61
56
|
flags = data[4]
|
62
|
-
|
63
|
-
docs = unpack_docs(data.last, number)
|
64
|
-
data[-1] = docs
|
57
|
+
docs = data.last
|
65
58
|
if flags & 2**0 > 0
|
66
59
|
Monga::Exceptions::CursorNotFound.new(docs.first)
|
67
60
|
elsif flags & 2**1 > 0
|
@@ -76,14 +69,6 @@ module Monga
|
|
76
69
|
|
77
70
|
private
|
78
71
|
|
79
|
-
def unpack_docs(data, number)
|
80
|
-
number.times.map do
|
81
|
-
size = data.slice(0, 4).unpack("L").first
|
82
|
-
d = data.slice!(0, size)
|
83
|
-
BSON.deserialize(d)
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
72
|
def flags
|
88
73
|
flags = 0
|
89
74
|
self.class::FLAGS.each do |k, byte|
|
data/lib/monga.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require "em-synchrony"
|
2
2
|
require "bson"
|
3
|
+
require "bin_utils"
|
3
4
|
require "logger"
|
4
5
|
require "forwardable"
|
5
6
|
|
@@ -23,6 +24,7 @@ require File.expand_path("../monga/clients/replica_set_client", __FILE__)
|
|
23
24
|
require File.expand_path("../monga/connections/em_connection", __FILE__)
|
24
25
|
require File.expand_path("../monga/connections/fibered_connection", __FILE__)
|
25
26
|
require File.expand_path("../monga/connections/tcp_connection", __FILE__)
|
27
|
+
require File.expand_path("../monga/connections/kgio_connection", __FILE__)
|
26
28
|
require File.expand_path("../monga/connections/em_proxy_connection", __FILE__)
|
27
29
|
require File.expand_path("../monga/connections/fibered_proxy_connection", __FILE__)
|
28
30
|
require File.expand_path("../monga/connections/proxy_connection", __FILE__)
|
data/monga.gemspec
CHANGED
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
6
|
spec.name = "monga"
|
7
|
-
spec.version = "0.0.
|
7
|
+
spec.version = "0.0.4"
|
8
8
|
spec.authors = ["Petr Yanovich"]
|
9
9
|
spec.email = ["fl00r@yandex.ru"]
|
10
10
|
spec.description = %q{MongoDB Ruby Evented Driver on EventMachine}
|
@@ -19,8 +19,10 @@ Gem::Specification.new do |spec|
|
|
19
19
|
|
20
20
|
spec.add_development_dependency "bundler", "~> 1.3"
|
21
21
|
spec.add_development_dependency "rake"
|
22
|
+
spec.add_development_dependency "kgio"
|
22
23
|
spec.add_development_dependency "em-synchrony"
|
23
24
|
|
24
25
|
spec.add_dependency "bson"
|
25
26
|
spec.add_dependency "bson_ext"
|
27
|
+
spec.add_dependency "bin_utils"
|
26
28
|
end
|
data/spec/helpers/mongodb.rb
CHANGED
@@ -132,20 +132,20 @@ describe Monga::Cursor do
|
|
132
132
|
|
133
133
|
describe "tailable cursor" do
|
134
134
|
before do
|
135
|
+
@capped = @db["testCapped"]
|
135
136
|
@db.create_collection("testCapped", capped: true, size: 4*1024)
|
136
|
-
@capped = @db["testCapped"]
|
137
137
|
@capped.safe_insert(title: "Test")
|
138
138
|
end
|
139
139
|
|
140
140
|
after do
|
141
|
-
@
|
141
|
+
@capped.drop
|
142
142
|
end
|
143
143
|
|
144
144
|
it "should be tailable" do
|
145
145
|
tailable_cursor = @capped.find.flag(tailable_cursor: true)
|
146
146
|
docs = []
|
147
147
|
tailable_cursor.each_doc do |doc|
|
148
|
-
@capped.
|
148
|
+
@capped.safe_insert(title: "New!")
|
149
149
|
if doc
|
150
150
|
docs << doc
|
151
151
|
if docs.size == 2
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Monga::Clients::ReplicaSetClient do
|
4
|
+
before do
|
5
|
+
@thread = Thread.new do
|
6
|
+
EM.run do
|
7
|
+
@replset = Fake::ReplicaSet.new([29000, 29100, 29200])
|
8
|
+
@replset.start_all
|
9
|
+
end
|
10
|
+
end
|
11
|
+
sleep 0.1
|
12
|
+
@client = Monga::Client.new servers: ['127.0.0.1:29000', '127.0.0.1:29100', '127.0.0.1:29200'], type: :block, timeout: 1
|
13
|
+
@collection = @client["dbTest"]["myCollection"]
|
14
|
+
end
|
15
|
+
|
16
|
+
after do
|
17
|
+
EM.stop if EM.reactor_running?
|
18
|
+
@thread.join
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should fail on disconnect and reconnect when primary is up again" do
|
22
|
+
sleep(0.1)
|
23
|
+
@replset.start_all
|
24
|
+
sleep(0.1)
|
25
|
+
@collection.safe_insert(name: "Peter")
|
26
|
+
@replset.primary.stop
|
27
|
+
proc{ @collection.safe_insert(name: "Peter") }.must_raise Monga::Exceptions::Disconnected
|
28
|
+
proc{ @collection.safe_insert(name: "Peter") }.must_raise Timeout::Error
|
29
|
+
proc{ @collection.safe_insert(name: "Peter") }.must_raise Timeout::Error
|
30
|
+
@replset.primary.start
|
31
|
+
sleep(0.1)
|
32
|
+
@collection.safe_insert(name: "Madonna")
|
33
|
+
@collection.safe_insert(name: "Madonna")
|
34
|
+
@collection.safe_insert(name: "Madonna")
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should work even if secondaries down" do
|
38
|
+
sleep(0.1)
|
39
|
+
@replset.start_all
|
40
|
+
@collection.safe_insert(name: "Peter")
|
41
|
+
@collection.safe_insert(name: "Peter")
|
42
|
+
@replset.secondaries.each(&:stop)
|
43
|
+
@collection.safe_insert(name: "Peter")
|
44
|
+
@collection.safe_insert(name: "Peter")
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should find new primary if it is down" do
|
48
|
+
sleep(0.1)
|
49
|
+
@replset.start_all
|
50
|
+
@collection.safe_insert(name: "Peter")
|
51
|
+
@replset.primary.stop
|
52
|
+
proc{ @collection.safe_insert(name: "Peter") }.must_raise Monga::Exceptions::Disconnected
|
53
|
+
proc{ @collection.safe_insert(name: "Peter") }.must_raise Timeout::Error
|
54
|
+
proc{ @collection.safe_insert(name: "Peter") }.must_raise Timeout::Error
|
55
|
+
@replset.vote
|
56
|
+
@collection.safe_insert(name: "Madonna")
|
57
|
+
end
|
58
|
+
end
|
@@ -2,14 +2,11 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Monga::Clients::SingleInstanceClient do
|
4
4
|
before do
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
@instance = Fake::SingleInstance.new(29000)
|
9
|
-
EM.stop
|
10
|
-
end
|
11
|
-
@t = Thread.new do
|
5
|
+
@client = Monga::Client.new port: 28000, type: :block
|
6
|
+
@collection = @client["dbTest"]["myCollection"]
|
7
|
+
@thread = Thread.new do
|
12
8
|
EM.run do
|
9
|
+
@instance = Fake::SingleInstance.new(28000)
|
13
10
|
@instance.start
|
14
11
|
end
|
15
12
|
end
|
@@ -17,10 +14,11 @@ describe Monga::Clients::SingleInstanceClient do
|
|
17
14
|
|
18
15
|
after do
|
19
16
|
EM.stop
|
20
|
-
@
|
17
|
+
@thread.join
|
21
18
|
end
|
22
19
|
|
23
20
|
it "should fail on disconnect and reconnect when instance is up again" do
|
21
|
+
sleep(0.1) # wait till instance started
|
24
22
|
@collection.safe_insert(name: "Peter")
|
25
23
|
@instance.stop
|
26
24
|
proc{ @collection.safe_insert(name: "Peter") }.must_raise Monga::Exceptions::Disconnected
|
@@ -119,8 +119,8 @@ describe Monga::Cursor do
|
|
119
119
|
EM.run do
|
120
120
|
docs = []
|
121
121
|
@collection.find.batch_size(2).limit(3).each_batch do |err, batch, iter|
|
122
|
-
docs += batch
|
123
122
|
if iter
|
123
|
+
docs += batch
|
124
124
|
iter.next
|
125
125
|
else
|
126
126
|
docs.size.must_equal 3
|
@@ -157,8 +157,8 @@ describe Monga::Cursor do
|
|
157
157
|
EM.run do
|
158
158
|
docs = []
|
159
159
|
@collection.find.limit(100).skip(15).batch_size(3).each_doc do |err, doc, iter|
|
160
|
-
docs << doc
|
161
160
|
if iter
|
161
|
+
docs << doc
|
162
162
|
iter.next
|
163
163
|
else
|
164
164
|
docs.size.must_equal 5
|
@@ -172,8 +172,8 @@ describe Monga::Cursor do
|
|
172
172
|
EM.run do
|
173
173
|
docs = []
|
174
174
|
@collection.find.batch_size(3).each_doc do |err, doc, iter|
|
175
|
-
docs << doc
|
176
175
|
if iter
|
176
|
+
docs << doc
|
177
177
|
iter.next
|
178
178
|
else
|
179
179
|
docs.size.must_equal 20
|
@@ -206,9 +206,9 @@ describe Monga::Cursor do
|
|
206
206
|
describe "tailable cursor" do
|
207
207
|
before do
|
208
208
|
EM.run do
|
209
|
+
@capped = @db["testCapped"]
|
209
210
|
@db.create_collection("testCapped", capped: true, size: 4*1024) do |err, resp|
|
210
211
|
raise err if err
|
211
|
-
@capped = @db["testCapped"]
|
212
212
|
@capped.safe_insert(title: "Test") do |err, resp|
|
213
213
|
raise err if err
|
214
214
|
EM.stop
|
@@ -219,7 +219,6 @@ describe Monga::Cursor do
|
|
219
219
|
|
220
220
|
after do
|
221
221
|
EM.run do
|
222
|
-
@capped = @db["testCapped"]
|
223
222
|
@capped.drop do |err, resp|
|
224
223
|
raise err if err
|
225
224
|
EM.stop
|
@@ -246,8 +245,6 @@ describe Monga::Cursor do
|
|
246
245
|
iter.next
|
247
246
|
end
|
248
247
|
end
|
249
|
-
else
|
250
|
-
EM.stop
|
251
248
|
end
|
252
249
|
end
|
253
250
|
end
|
@@ -175,8 +175,8 @@ describe Monga::Cursor do
|
|
175
175
|
describe "tailable cursor" do
|
176
176
|
before do
|
177
177
|
EM.synchrony do
|
178
|
-
@db.create_collection("testCapped", capped: true, size: 4*1024)
|
179
178
|
@capped = @db["testCapped"]
|
179
|
+
@db.create_collection("testCapped", capped: true, size: 4*1024)
|
180
180
|
@capped.safe_insert(title: "Test")
|
181
181
|
EM.stop
|
182
182
|
end
|
@@ -184,7 +184,7 @@ describe Monga::Cursor do
|
|
184
184
|
|
185
185
|
after do
|
186
186
|
EM.synchrony do
|
187
|
-
@
|
187
|
+
@capped.drop
|
188
188
|
EM.stop
|
189
189
|
end
|
190
190
|
end
|
@@ -194,7 +194,7 @@ describe Monga::Cursor do
|
|
194
194
|
tailable_cursor = @capped.find.flag(tailable_cursor: true)
|
195
195
|
docs = []
|
196
196
|
tailable_cursor.each_doc do |doc|
|
197
|
-
@capped.
|
197
|
+
@capped.safe_insert(title: "New!")
|
198
198
|
if doc
|
199
199
|
docs << doc
|
200
200
|
if docs.size == 2
|
@@ -17,10 +17,10 @@ describe Monga::Clients::ReplicaSetClient do
|
|
17
17
|
@replset.primary.stop
|
18
18
|
proc{ @collection.safe_insert(name: "Peter") }.must_raise Monga::Exceptions::Disconnected
|
19
19
|
proc{ @collection.safe_insert(name: "Peter") }.must_raise Monga::Exceptions::Disconnected
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
@collection.safe_insert(name: "
|
20
|
+
EM.add_timer(0.5) do
|
21
|
+
@replset.primary.start
|
22
|
+
end
|
23
|
+
@collection.safe_insert(name: "Peter")
|
24
24
|
@collection.safe_insert(name: "Madonna")
|
25
25
|
EM.stop
|
26
26
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: monga
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-04-
|
12
|
+
date: 2013-04-24 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
@@ -43,6 +43,22 @@ dependencies:
|
|
43
43
|
none: false
|
44
44
|
prerelease: false
|
45
45
|
name: rake
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
requirement: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ! '>='
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: '0'
|
52
|
+
none: false
|
53
|
+
type: :development
|
54
|
+
version_requirements: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - ! '>='
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: '0'
|
59
|
+
none: false
|
60
|
+
prerelease: false
|
61
|
+
name: kgio
|
46
62
|
- !ruby/object:Gem::Dependency
|
47
63
|
requirement: !ruby/object:Gem::Requirement
|
48
64
|
requirements:
|
@@ -91,6 +107,22 @@ dependencies:
|
|
91
107
|
none: false
|
92
108
|
prerelease: false
|
93
109
|
name: bson_ext
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
requirement: !ruby/object:Gem::Requirement
|
112
|
+
requirements:
|
113
|
+
- - ! '>='
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
version: '0'
|
116
|
+
none: false
|
117
|
+
type: :runtime
|
118
|
+
version_requirements: !ruby/object:Gem::Requirement
|
119
|
+
requirements:
|
120
|
+
- - ! '>='
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: '0'
|
123
|
+
none: false
|
124
|
+
prerelease: false
|
125
|
+
name: bin_utils
|
94
126
|
description: MongoDB Ruby Evented Driver on EventMachine
|
95
127
|
email:
|
96
128
|
- fl00r@yandex.ru
|
@@ -104,6 +136,8 @@ files:
|
|
104
136
|
- LICENSE.txt
|
105
137
|
- README.md
|
106
138
|
- Rakefile
|
139
|
+
- benchmarks/inserts.rb
|
140
|
+
- benchmarks/prof.rb
|
107
141
|
- lib/monga.rb
|
108
142
|
- lib/monga/client.rb
|
109
143
|
- lib/monga/clients/master_slave_client.rb
|
@@ -117,6 +151,7 @@ files:
|
|
117
151
|
- lib/monga/connections/em_proxy_connection.rb
|
118
152
|
- lib/monga/connections/fibered_connection.rb
|
119
153
|
- lib/monga/connections/fibered_proxy_connection.rb
|
154
|
+
- lib/monga/connections/kgio_connection.rb
|
120
155
|
- lib/monga/connections/proxy_connection.rb
|
121
156
|
- lib/monga/connections/tcp_connection.rb
|
122
157
|
- lib/monga/cursor.rb
|
@@ -135,6 +170,7 @@ files:
|
|
135
170
|
- spec/monga/block/collection_spec.rb
|
136
171
|
- spec/monga/block/cursor_spec.rb
|
137
172
|
- spec/monga/block/database_spec.rb
|
173
|
+
- spec/monga/block/replica_set_client_spec.rb
|
138
174
|
- spec/monga/block/single_instance_client_spec.rb
|
139
175
|
- spec/monga/em/collection_spec.rb
|
140
176
|
- spec/monga/em/cursor_spec.rb
|
@@ -158,7 +194,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
158
194
|
requirements:
|
159
195
|
- - ! '>='
|
160
196
|
- !ruby/object:Gem::Version
|
161
|
-
hash:
|
197
|
+
hash: 3881917270092852844
|
162
198
|
version: '0'
|
163
199
|
segments:
|
164
200
|
- 0
|
@@ -167,7 +203,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
167
203
|
requirements:
|
168
204
|
- - ! '>='
|
169
205
|
- !ruby/object:Gem::Version
|
170
|
-
hash:
|
206
|
+
hash: 3881917270092852844
|
171
207
|
version: '0'
|
172
208
|
segments:
|
173
209
|
- 0
|
@@ -183,6 +219,7 @@ test_files:
|
|
183
219
|
- spec/monga/block/collection_spec.rb
|
184
220
|
- spec/monga/block/cursor_spec.rb
|
185
221
|
- spec/monga/block/database_spec.rb
|
222
|
+
- spec/monga/block/replica_set_client_spec.rb
|
186
223
|
- spec/monga/block/single_instance_client_spec.rb
|
187
224
|
- spec/monga/em/collection_spec.rb
|
188
225
|
- spec/monga/em/cursor_spec.rb
|