mongo 1.3.1 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. data/README.md +9 -6
  2. data/Rakefile +3 -4
  3. data/docs/HISTORY.md +20 -2
  4. data/docs/READ_PREFERENCE.md +39 -0
  5. data/docs/RELEASES.md +1 -1
  6. data/docs/REPLICA_SETS.md +23 -2
  7. data/docs/TAILABLE_CURSORS.md +51 -0
  8. data/docs/TUTORIAL.md +4 -4
  9. data/docs/WRITE_CONCERN.md +5 -2
  10. data/lib/mongo.rb +7 -22
  11. data/lib/mongo/collection.rb +96 -29
  12. data/lib/mongo/connection.rb +107 -62
  13. data/lib/mongo/cursor.rb +136 -57
  14. data/lib/mongo/db.rb +26 -5
  15. data/lib/mongo/exceptions.rb +17 -1
  16. data/lib/mongo/gridfs/grid.rb +1 -1
  17. data/lib/mongo/repl_set_connection.rb +273 -156
  18. data/lib/mongo/util/logging.rb +42 -0
  19. data/lib/mongo/util/node.rb +183 -0
  20. data/lib/mongo/util/pool.rb +76 -13
  21. data/lib/mongo/util/pool_manager.rb +208 -0
  22. data/lib/mongo/util/ssl_socket.rb +38 -0
  23. data/lib/mongo/util/support.rb +9 -1
  24. data/lib/mongo/util/timeout.rb +42 -0
  25. data/lib/mongo/version.rb +3 -0
  26. data/mongo.gemspec +2 -2
  27. data/test/bson/binary_test.rb +1 -1
  28. data/test/bson/bson_string_test.rb +30 -0
  29. data/test/bson/bson_test.rb +6 -3
  30. data/test/bson/byte_buffer_test.rb +1 -1
  31. data/test/bson/hash_with_indifferent_access_test.rb +1 -1
  32. data/test/bson/json_test.rb +1 -1
  33. data/test/bson/object_id_test.rb +2 -18
  34. data/test/bson/ordered_hash_test.rb +38 -3
  35. data/test/bson/test_helper.rb +46 -0
  36. data/test/bson/timestamp_test.rb +32 -10
  37. data/test/collection_test.rb +89 -3
  38. data/test/connection_test.rb +35 -20
  39. data/test/cursor_test.rb +63 -2
  40. data/test/db_test.rb +12 -2
  41. data/test/pool_test.rb +21 -0
  42. data/test/replica_sets/connect_test.rb +26 -13
  43. data/test/replica_sets/connection_string_test.rb +1 -4
  44. data/test/replica_sets/count_test.rb +1 -0
  45. data/test/replica_sets/insert_test.rb +1 -0
  46. data/test/replica_sets/pooled_insert_test.rb +4 -1
  47. data/test/replica_sets/query_secondaries.rb +2 -1
  48. data/test/replica_sets/query_test.rb +2 -1
  49. data/test/replica_sets/read_preference_test.rb +43 -0
  50. data/test/replica_sets/refresh_test.rb +123 -0
  51. data/test/replica_sets/replication_ack_test.rb +9 -4
  52. data/test/replica_sets/rs_test_helper.rb +2 -2
  53. data/test/timeout_test.rb +14 -0
  54. data/test/tools/repl_set_manager.rb +134 -23
  55. data/test/unit/collection_test.rb +6 -8
  56. data/test/unit/connection_test.rb +4 -4
  57. data/test/unit/cursor_test.rb +23 -5
  58. data/test/unit/db_test.rb +2 -0
  59. data/test/unit/grid_test.rb +2 -0
  60. data/test/unit/node_test.rb +73 -0
  61. data/test/unit/pool_manager_test.rb +47 -0
  62. data/test/unit/read_test.rb +101 -0
  63. metadata +214 -138
  64. data/lib/mongo/test.rb +0 -20
  65. data/test/async/collection_test.rb +0 -224
  66. data/test/async/connection_test.rb +0 -24
  67. data/test/async/cursor_test.rb +0 -162
  68. data/test/async/worker_pool_test.rb +0 -99
  69. data/test/load/resque/load.rb +0 -21
  70. data/test/load/resque/processor.rb +0 -26
  71. data/test/load/unicorn/unicorn.rb +0 -29
  72. data/test/tools/load.rb +0 -58
  73. data/test/tools/sharding_manager.rb +0 -202
  74. data/test/tools/test.rb +0 -4
  75. data/test/unit/repl_set_connection_test.rb +0 -59
@@ -1,21 +0,0 @@
1
- require File.join(File.dirname(__FILE__), '..', '..', '..', 'lib', 'mongo')
2
- require 'logger'
3
- require 'rubygems'
4
- require 'resque'
5
- require 'sinatra'
6
- require File.join(File.dirname(__FILE__), 'processor')
7
-
8
- $con = Mongo::Connection.new
9
- $db = $con['foo']
10
-
11
-
12
- configure do
13
- LOGGER = Logger.new("sinatra.log")
14
- enable :logging, :dump_errors
15
- set :raise_errors, true
16
- end
17
-
18
- get '/' do
19
- Processor.perform(1)
20
- true
21
- end
@@ -1,26 +0,0 @@
1
- require 'logger'
2
-
3
- class Processor
4
- @queue = :processor
5
-
6
- def self.connection
7
- @log ||= Logger.new(STDOUT)
8
- @con ||= Mongo::Connection.new("localhost", 27017)
9
- end
10
-
11
- def self.perform(n)
12
- begin
13
- 100.times do |n|
14
- self.connection['resque']['docs'].insert({:n => n, :data => "0" * 1000}, :safe => true)
15
- end
16
-
17
- 5.times do |n|
18
- num = rand(100)
19
- self.connection['resque']['docs'].find({:n => {"$gt" => num}}).limit(1).to_a
20
- end
21
- rescue => e
22
- @log.warn(e.inspect)
23
- end
24
- end
25
-
26
- end
@@ -1,29 +0,0 @@
1
- # set path to app that will be used to configure unicorn,
2
- # # note the trailing slash in this example
3
- @dir = "/home/kyle/work/10gen/ruby-driver/test/load/"
4
-
5
- worker_processes 10
6
- working_directory @dir
7
-
8
- preload_app true
9
-
10
- timeout 30
11
-
12
- # Specify path to socket unicorn listens to,
13
- # we will use this in our nginx.conf later
14
- listen "#{@dir}tmp/sockets/unicorn.sock", :backlog => 64
15
-
16
- # Set process id path
17
- pid "#{@dir}tmp/pids/unicorn.pid"
18
-
19
- # # Set log file paths
20
- stderr_path "#{@dir}log/unicorn.stderr.log"
21
- stdout_path "#{@dir}log/unicorn.stdout.log"
22
-
23
- # NOTE: You need this when using forking web servers!
24
- after_fork do |server, worker|
25
- $con.close if $con
26
- $con = Mongo::Connection.new
27
- $db = $con['foo']
28
- STDERR << "FORKED #{server} #{worker}"
29
- end
@@ -1,58 +0,0 @@
1
- require 'rubygems'
2
- require 'mongo'
3
- require 'sharding_manager'
4
-
5
- class MongoLoader
6
-
7
- def initialize
8
- @mongo = Mongo::Connection.new("localhost", 50000)
9
- @data = BSON::Binary.new(File.open("tools.gz").read)
10
- @count = 0
11
- @manager = ShardingManager.new(:config_count => 3)
12
- @manager.start_cluster
13
- end
14
-
15
- def kill
16
- @manager.kill_random
17
- end
18
-
19
- def restart
20
- @manager.restart_killed_nodes
21
- end
22
-
23
- def run
24
- Thread.new do
25
- ("a".."z").each do |p|
26
- seed(p)
27
- end
28
- end
29
- end
30
-
31
- def seed(prefix)
32
- @queue = []
33
- 1000.times do |n|
34
- id = BSON::OrderedHash.new
35
- id[:p] = prefix
36
- id[:c] = n
37
- @queue << {:tid => id, :data => @data}
38
- end
39
-
40
- while @queue.length > 0 do
41
- begin
42
- doc = @queue.pop
43
- @mongo['app']['photos'].insert(doc, :safe => {:w => 3})
44
- @count += 1
45
- p @count
46
- rescue StandardError => e
47
- p e
48
- p @count
49
- @queue.push(doc)
50
- @count -= 1
51
- sleep(10)
52
- retry
53
- end
54
- end
55
- end
56
- end
57
-
58
- @m = MongoLoader.new
@@ -1,202 +0,0 @@
1
- require 'repl_set_manager'
2
- require 'thread'
3
-
4
- class ShardingManager
5
-
6
- attr_accessor :shards
7
-
8
- def initialize(opts={})
9
- @durable = opts.fetch(:durable, true)
10
- @host = "localhost"
11
-
12
- @mongos_port = opts[:mongos_port] || 50000
13
- @config_port = opts[:config_port] || 40000
14
- @shard_start_port = opts[:start_shard_port] || 30000
15
- @path = File.join(File.expand_path(File.dirname(__FILE__)), "data")
16
- system("rm -rf #{@path}")
17
-
18
- @shard_count = 2
19
- @mongos_count = 1
20
- @config_count = opts.fetch(:config_count, 1)
21
- if ![1, 3].include?(@config_count)
22
- raise ArgumentError, "Must specify 1 or 3 config servers."
23
- end
24
-
25
- @config_servers = {}
26
- @mongos_servers = {}
27
- @shards = []
28
- @ports = []
29
- end
30
-
31
- def kill_random
32
- shard_to_kill = rand(@shard_count)
33
- @shards[shard_to_kill].kill_primary
34
- end
35
-
36
- def restart_killed
37
- threads = []
38
- @shards.each do |k, shard|
39
- threads << Thread.new do
40
- shard.restart_killed_nodes
41
- end
42
- end
43
- end
44
-
45
- def start_cluster
46
- start_sharding_components
47
- start_mongos_servers
48
- configure_cluster
49
- end
50
-
51
- def configure_cluster
52
- add_shards
53
- enable_sharding
54
- shard_collection
55
- end
56
-
57
- def enable_sharding
58
- mongos['admin'].command({:enablesharding => "app"})
59
- end
60
-
61
- def shard_collection
62
- cmd = BSON::OrderedHash.new
63
- cmd[:shardcollection] = "app.photos"
64
- cmd[:key] = {:tid => 1}
65
- p mongos['admin'].command(cmd)
66
- end
67
-
68
- def add_shards
69
- @shards.each do |shard|
70
- cmd = {:addshard => shard.shard_string}
71
- p cmd
72
- p mongos['admin'].command(cmd)
73
- end
74
- p mongos['admin'].command({:listshards => 1})
75
- end
76
-
77
- def mongos
78
- attempt do
79
- @mongos ||= Mongo::Connection.new(@host, @mongos_servers[0]['port'])
80
- end
81
- end
82
-
83
- private
84
-
85
- def start_sharding_components
86
- system("killall mongos")
87
-
88
- threads = []
89
- threads << Thread.new do
90
- start_shards
91
- end
92
-
93
- threads << Thread.new do
94
- start_config_servers
95
- end
96
- threads.each {|t| t.join}
97
- puts "\nShards and config servers up!"
98
- end
99
-
100
- def start_shards
101
- threads = []
102
- @shard_count.times do |n|
103
- threads << Thread.new do
104
- port = @shard_start_port + n * 100
105
- shard = ReplSetManager.new(:arbiter_count => 0, :secondary_count => 2,
106
- :passive_count => 0, :start_port => port, :durable => @durable,
107
- :name => "shard-#{n}")
108
- shard.start_set
109
- shard.ensure_up
110
- @shards << shard
111
- end
112
- end
113
- threads.each {|t| t.join}
114
- end
115
-
116
- def start_config_servers
117
- @config_count.times do |n|
118
- @config_servers[n] ||= {}
119
- port = @config_port + n
120
- @ports << port
121
- @config_servers[n]['port'] = port
122
- @config_servers[n]['db_path'] = get_path("config-#{port}")
123
- @config_servers[n]['log_path'] = get_path("log-config-#{port}")
124
- system("rm -rf #{@config_servers[n]['db_path']}")
125
- system("mkdir -p #{@config_servers[n]['db_path']}")
126
-
127
- @config_servers[n]['start'] = start_config_cmd(n)
128
-
129
- start(@config_servers, n)
130
- end
131
- end
132
-
133
- def start_mongos_servers
134
- @mongos_count.times do |n|
135
- @mongos_servers[n] ||= {}
136
- port = @mongos_port + n
137
- @ports << port
138
- @mongos_servers[n]['port'] = port
139
- @mongos_servers[n]['db_path'] = get_path("mongos-#{port}")
140
- @mongos_servers[n]['pidfile_path'] = File.join(@mongos_servers[n]['db_path'], "mongod.lock")
141
- @mongos_servers[n]['log_path'] = get_path("log-mongos-#{port}")
142
- system("rm -rf #{@mongos_servers[n]['db_path']}")
143
- system("mkdir -p #{@mongos_servers[n]['db_path']}")
144
-
145
- @mongos_servers[n]['start'] = start_mongos_cmd(n)
146
-
147
- start(@mongos_servers, n)
148
- end
149
- end
150
-
151
- def start_config_cmd(n)
152
- cmd = "mongod --configsvr --logpath '#{@config_servers[n]['log_path']}' " +
153
- " --dbpath #{@config_servers[n]['db_path']} --port #{@config_servers[n]['port']} --fork"
154
- cmd += " --dur" if @durable
155
- cmd
156
- end
157
-
158
- def start_mongos_cmd(n)
159
- "mongos --configdb #{config_db_string} --logpath '#{@mongos_servers[n]['log_path']}' " +
160
- "--pidfilepath #{@mongos_servers[n]['pidfile_path']} --port #{@mongos_servers[n]['port']} --fork"
161
- end
162
-
163
- def config_db_string
164
- @config_servers.map do |k, v|
165
- "#{@host}:#{v['port']}"
166
- end.join(',')
167
- end
168
-
169
- def start(set, node)
170
- system(set[node]['start'])
171
- set[node]['up'] = true
172
- sleep(0.5)
173
- set[node]['pid'] = File.open(File.join(set[node]['db_path'], 'mongod.lock')).read.strip
174
- end
175
- alias :restart :start
176
-
177
- private
178
-
179
- def cleanup_config
180
- end
181
-
182
- def get_path(name)
183
- File.join(@path, name)
184
- end
185
-
186
- # TODO: put this into a shared module
187
- def attempt
188
- raise "No block given!" unless block_given?
189
- count = 0
190
-
191
- while count < 50 do
192
- begin
193
- return yield
194
- rescue Mongo::OperationFailure, Mongo::ConnectionFailure
195
- sleep(1)
196
- count += 1
197
- end
198
- end
199
-
200
- raise exception
201
- end
202
- end
@@ -1,4 +0,0 @@
1
- require 'sharding_manager'
2
-
3
- m = ShardingManager.new(:config_count => 3)
4
- m.start_cluster
@@ -1,59 +0,0 @@
1
- require './test/test_helper'
2
- include Mongo
3
-
4
- class ReplSetConnectionTest < Test::Unit::TestCase
5
- context "Initialization: " do
6
- context "connecting to a replica set" do
7
- setup do
8
- TCPSocket.stubs(:new).returns(new_mock_socket('localhost', 27017))
9
- @conn = ReplSetConnection.new(['localhost', 27017], :connect => false, :read_secondary => true)
10
-
11
- admin_db = new_mock_db
12
- @hosts = ['localhost:27018', 'localhost:27019', 'localhost:27020']
13
-
14
- admin_db.stubs(:command).returns({'ok' => 1, 'ismaster' => 1, 'hosts' => @hosts}).
15
- then.returns({'ok' => 1, 'ismaster' => 0, 'hosts' => @hosts, 'secondary' => 1}).
16
- then.returns({'ok' => 1, 'ismaster' => 0, 'hosts' => @hosts, 'secondary' => 1}).
17
- then.returns({'ok' => 1, 'ismaster' => 0, 'arbiterOnly' => 1})
18
-
19
- @conn.stubs(:[]).with('admin').returns(admin_db)
20
- @conn.connect
21
- end
22
-
23
- should "store the hosts returned from the ismaster command" do
24
- assert_equal 'localhost', @conn.primary_pool.host
25
- assert_equal 27017, @conn.primary_pool.port
26
-
27
- assert_equal 'localhost', @conn.secondary_pools[0].host
28
- assert_equal 27018, @conn.secondary_pools[0].port
29
-
30
- assert_equal 'localhost', @conn.secondary_pools[1].host
31
- assert_equal 27019, @conn.secondary_pools[1].port
32
-
33
- assert_equal 2, @conn.secondary_pools.length
34
- end
35
- end
36
-
37
- context "connecting to a replica set and providing seed nodes" do
38
- setup do
39
- TCPSocket.stubs(:new).returns(new_mock_socket)
40
- @conn = ReplSetConnection.new(['localhost', 27017], ['localhost', 27019], :connect => false)
41
-
42
- admin_db = new_mock_db
43
- @hosts = ['localhost:27017', 'localhost:27018', 'localhost:27019']
44
- admin_db.stubs(:command).returns({'ok' => 1, 'ismaster' => 1, 'hosts' => @hosts})
45
- @conn.stubs(:[]).with('admin').returns(admin_db)
46
- @conn.connect
47
- end
48
- end
49
-
50
- context "initializing with a mongodb uri" do
51
-
52
- should "parse a uri specifying multiple nodes" do
53
- @conn = Connection.from_uri("mongodb://localhost:27017,mydb.com:27018", :connect => false)
54
- assert_equal ['localhost', 27017], @conn.nodes[0]
55
- assert_equal ['mydb.com', 27018], @conn.nodes[1]
56
- end
57
- end
58
- end
59
- end