monga 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Build Status](https://travis-ci.org/fl00r/monga.png?branch=master)](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
|