jmongo 1.1.4 → 1.1.5
Sign up to get free protection for your applications and to get access to all the features.
- data/jmongo.gemspec +3 -3
- data/lib/jmongo/collection.rb +64 -6
- data/lib/jmongo/cursor.rb +0 -9
- data/lib/jmongo/mongo/collection.rb +8 -0
- data/lib/jmongo/version.rb +1 -1
- data/test/subscribe_test.rb +84 -0
- metadata +11 -11
- data/Gemfile.lock +0 -44
data/jmongo.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'jmongo'
|
3
|
-
s.version = '1.1.
|
4
|
-
s.date = '2011-10-
|
3
|
+
s.version = '1.1.5'
|
4
|
+
s.date = '2011-10-22'
|
5
5
|
s.platform = Gem::Platform::RUBY
|
6
6
|
s.authors = ["Chuck Remes","Guy Boertje", "Lee Henson"]
|
7
7
|
s.email = ["cremes@mac.com", "guyboertje@gmail.com", "lee.m.henson@gmail.com"]
|
@@ -12,7 +12,6 @@ Gem::Specification.new do |s|
|
|
12
12
|
# = MANIFEST =
|
13
13
|
s.files = %w[
|
14
14
|
Gemfile
|
15
|
-
Gemfile.lock
|
16
15
|
History.txt
|
17
16
|
LICENSE.txt
|
18
17
|
README.txt
|
@@ -87,6 +86,7 @@ Gem::Specification.new do |s|
|
|
87
86
|
test/replica_sets/replication_ack_test.rb
|
88
87
|
test/replica_sets/rs_test_helper.rb
|
89
88
|
test/safe_test.rb
|
89
|
+
test/subscribe_test.rb
|
90
90
|
test/support/hash_with_indifferent_access.rb
|
91
91
|
test/support/keys.rb
|
92
92
|
test/support_test.rb
|
data/lib/jmongo/collection.rb
CHANGED
@@ -48,20 +48,37 @@ module Mongo
|
|
48
48
|
if args.size < 2
|
49
49
|
raise ArgumentError.new("Must supply at least name and db parameters")
|
50
50
|
end
|
51
|
-
if args.first.
|
52
|
-
db, name = args
|
53
|
-
else
|
51
|
+
if args.first.is_a?(String)
|
54
52
|
name, db = args
|
53
|
+
else
|
54
|
+
db, name = args
|
55
55
|
end
|
56
|
-
|
57
56
|
@name = validate_name(name)
|
58
57
|
@db, @j_db = db, db.j_db
|
59
58
|
@connection = @db.connection
|
60
59
|
@pk_factory = @opts.delete(:pk)|| BSON::ObjectId
|
61
60
|
@hint = nil
|
61
|
+
|
62
|
+
@monitor = @opts.delete(:monitor)
|
63
|
+
if @monitor
|
64
|
+
setup_monitor
|
65
|
+
elsif @opts.has_key?(:monitor_source)
|
66
|
+
@monitor_source = @opts.delete(:monitor_source)
|
67
|
+
end
|
68
|
+
|
62
69
|
@j_collection = j_collection || @j_db.create_collection(@name, to_dbobject(@opts))
|
63
70
|
end
|
64
71
|
|
72
|
+
def setup_monitor
|
73
|
+
mon_opts = @monitor.is_a?(Hash)? @monitor : {}
|
74
|
+
size = mon_opts.fetch(:size, 8000)
|
75
|
+
@monitor_max = mon_opts.fetch(:max, 100)
|
76
|
+
opts = {:capped => true, :max => @monitor_max, :size => size, :monitor_source => self}
|
77
|
+
@mon_collection = @db.create_collection("#{@name}-monitor", opts)
|
78
|
+
@j_mon_collection = @mon_collection.j_collection
|
79
|
+
@monitorable = true
|
80
|
+
end
|
81
|
+
|
65
82
|
def safe
|
66
83
|
!!@opts.fetch(:safe, false)
|
67
84
|
end
|
@@ -648,5 +665,46 @@ module Mongo
|
|
648
665
|
end
|
649
666
|
|
650
667
|
alias :size :count
|
651
|
-
|
652
|
-
|
668
|
+
|
669
|
+
def monitor_collection
|
670
|
+
raise InvalidOperation, "Monitoring has not been setup, add :monitor - true or Hash" unless @monitorable
|
671
|
+
@mon_collection
|
672
|
+
end
|
673
|
+
|
674
|
+
def monitored_collection
|
675
|
+
@monitor_source
|
676
|
+
end
|
677
|
+
|
678
|
+
def monitor_subscribe(opts, &callback_doc)
|
679
|
+
raise MongoArgumentError, "Not a monitorable collection" if @monitor_source.nil?
|
680
|
+
raise MongoArgumentError, "Must supply a block" unless block_given?
|
681
|
+
raise MongoArgumentError, "opts needs to be a Hash" unless opts.is_a?(Hash)
|
682
|
+
callback_exit = opts[:callback_exit]
|
683
|
+
raise MongoArgumentError, "Need a callable for exit callback" unless callback_doc.respond_to?('call')
|
684
|
+
exit_check_timeout = opts[:exit_check_timeout]
|
685
|
+
raise MongoArgumentError, "Need a positive float for timeout" unless exit_check_timeout.to_f > 0.0
|
686
|
+
|
687
|
+
tail = Mongo::Cursor.new(self, :timeout => false, :tailable => true, :await_data => 0.5, :order => [['$natural', 1]])
|
688
|
+
|
689
|
+
loop_th = Thread.new(tail, callback_doc) do |cur, cb|
|
690
|
+
while !Thread.current[:stop]
|
691
|
+
doc = cur.next
|
692
|
+
cb.call(doc) if doc
|
693
|
+
end
|
694
|
+
end
|
695
|
+
loop_th[:stop] = false
|
696
|
+
|
697
|
+
exit_th = Thread.new(exit_check_timeout.to_f, callback_exit) do |to, cb|
|
698
|
+
while true
|
699
|
+
sleep to
|
700
|
+
must_exit = cb.call
|
701
|
+
break if must_exit
|
702
|
+
end
|
703
|
+
loop_th[:stop] = true
|
704
|
+
end
|
705
|
+
#
|
706
|
+
end
|
707
|
+
|
708
|
+
|
709
|
+
end #class
|
710
|
+
end #module
|
data/lib/jmongo/cursor.rb
CHANGED
@@ -106,6 +106,10 @@ module Mongo
|
|
106
106
|
else
|
107
107
|
begin
|
108
108
|
@j_collection.insert( to_dbobject(to_do), concern )
|
109
|
+
if @monitorable
|
110
|
+
mon_do = to_do.map{ |doc| {'_id'=>doc['_id'], 'action'=>1} }
|
111
|
+
@j_mon_collection.insert( to_dbobject(mon_do), concern )
|
112
|
+
end
|
109
113
|
rescue => ex
|
110
114
|
if ex.message =~ /E11000/
|
111
115
|
msg = "Failed to insert document #{obj.inspect}, duplicate key, E11000"
|
@@ -125,6 +129,10 @@ module Mongo
|
|
125
129
|
begin
|
126
130
|
jres = @j_collection.insert( dbo, concern )
|
127
131
|
result = from_dbobject(jres.get_last_error(concern))
|
132
|
+
if @monitorable
|
133
|
+
mon_obj = one_obj.map{ |doc| {'_id'=>doc['_id'], 'action'=>1} }
|
134
|
+
@j_mon_collection.( to_dbobject(mon_obj), concern )
|
135
|
+
end
|
128
136
|
rescue => ex
|
129
137
|
if ex.message =~ /E11000/ #noop duplicate key
|
130
138
|
result = {'err'=>ex.message}
|
data/lib/jmongo/version.rb
CHANGED
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'minitest/spec'
|
2
|
+
require './test/test_helper'
|
3
|
+
|
4
|
+
Cfg.connection :op_timeout => 10
|
5
|
+
Cfg.db
|
6
|
+
|
7
|
+
describe "Monitorable Pair Collection" do
|
8
|
+
before do
|
9
|
+
Cfg.clear_all
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "monitoring a collection with defaults" do
|
13
|
+
|
14
|
+
before do
|
15
|
+
opts = {:monitor => true}
|
16
|
+
@collection = Cfg.db.create_collection('buffer', opts)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should have a monitor_collection" do
|
20
|
+
assert @collection.monitor_collection
|
21
|
+
assert_equal "buffer-monitor", @collection.monitor_collection.name
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should insert into the monitorable collection as well" do
|
25
|
+
@collection.insert({'field1' => 'some value', 'field2' => 99})
|
26
|
+
assert_equal 1, @collection.size
|
27
|
+
rec = @collection.find().to_a.first
|
28
|
+
assert_equal 1, @collection.monitor_collection.size
|
29
|
+
mon_rec = @collection.monitor_collection.find().to_a.first
|
30
|
+
assert_equal rec['_id'], mon_rec['_id']
|
31
|
+
assert_equal 1, mon_rec['action']
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should raise when the subscribe method is called on a normal collection" do
|
35
|
+
normal = Cfg.db.create_collection('normal')
|
36
|
+
assert normal.respond_to?('monitor_subscribe')
|
37
|
+
assert_raises Mongo::MongoArgumentError do
|
38
|
+
normal.monitor_subscribe(2)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should raise for invalid options" do
|
43
|
+
@stop_callback = lambda{ true }
|
44
|
+
@monitored = @collection.monitor_collection
|
45
|
+
assert_raises Mongo::MongoArgumentError do
|
46
|
+
@monitored.monitor_subscribe({}) #no block
|
47
|
+
end
|
48
|
+
assert_raises Mongo::MongoArgumentError do
|
49
|
+
@monitored.monitor_subscribe({:callback_exit => ''}) {|doc| apr(doc,'doc')} #not callable
|
50
|
+
end
|
51
|
+
assert_raises Mongo::MongoArgumentError do
|
52
|
+
@monitored.monitor_subscribe({ :callback_exit => @stop_callback }) {|doc| apr(doc,'doc')} #no timeout
|
53
|
+
end
|
54
|
+
assert_raises Mongo::MongoArgumentError do
|
55
|
+
@monitored.monitor_subscribe({:callback_exit => @stop_callback, :exit_check_timeout => 0}) {|doc| apr(doc,'doc')} #timeout not positive float
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
it "the monitored collection should have a subscribe method" do
|
60
|
+
@stop = 0
|
61
|
+
@count = 0
|
62
|
+
@values = []
|
63
|
+
@stop_callback = lambda{ @stop += 1; true }
|
64
|
+
@monitored = @collection.monitor_collection
|
65
|
+
assert_equal @collection, @monitored.monitored_collection
|
66
|
+
|
67
|
+
@monitored.monitor_subscribe({:callback_exit => @stop_callback, :exit_check_timeout => 1.0}) do |doc|
|
68
|
+
if doc
|
69
|
+
id, act = doc.values_at('_id','action')
|
70
|
+
@count += (act || 0)
|
71
|
+
orig = @monitored.monitored_collection.find_one('_id'=>id)
|
72
|
+
@values << orig['field2'] if orig
|
73
|
+
end
|
74
|
+
end
|
75
|
+
@collection.insert({'field1' => 'some value', 'field2' => 99})
|
76
|
+
@collection.insert({'field1' => 'some value', 'field2' => 98})
|
77
|
+
|
78
|
+
sleep 1.2
|
79
|
+
assert_equal 1, @stop
|
80
|
+
assert_equal 2, @count
|
81
|
+
assert_equal [99,98], @values
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jmongo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -11,11 +11,11 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2011-10-
|
14
|
+
date: 2011-10-22 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: require_all
|
18
|
-
requirement: &
|
18
|
+
requirement: &9275500 !ruby/object:Gem::Requirement
|
19
19
|
none: false
|
20
20
|
requirements:
|
21
21
|
- - ~>
|
@@ -23,10 +23,10 @@ dependencies:
|
|
23
23
|
version: '1.2'
|
24
24
|
type: :runtime
|
25
25
|
prerelease: false
|
26
|
-
version_requirements: *
|
26
|
+
version_requirements: *9275500
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: awesome_print
|
29
|
-
requirement: &
|
29
|
+
requirement: &9275020 !ruby/object:Gem::Requirement
|
30
30
|
none: false
|
31
31
|
requirements:
|
32
32
|
- - ~>
|
@@ -34,10 +34,10 @@ dependencies:
|
|
34
34
|
version: '0.4'
|
35
35
|
type: :development
|
36
36
|
prerelease: false
|
37
|
-
version_requirements: *
|
37
|
+
version_requirements: *9275020
|
38
38
|
- !ruby/object:Gem::Dependency
|
39
39
|
name: fuubar
|
40
|
-
requirement: &
|
40
|
+
requirement: &9274520 !ruby/object:Gem::Requirement
|
41
41
|
none: false
|
42
42
|
requirements:
|
43
43
|
- - ~>
|
@@ -45,10 +45,10 @@ dependencies:
|
|
45
45
|
version: '0.0'
|
46
46
|
type: :development
|
47
47
|
prerelease: false
|
48
|
-
version_requirements: *
|
48
|
+
version_requirements: *9274520
|
49
49
|
- !ruby/object:Gem::Dependency
|
50
50
|
name: rspec
|
51
|
-
requirement: &
|
51
|
+
requirement: &9273680 !ruby/object:Gem::Requirement
|
52
52
|
none: false
|
53
53
|
requirements:
|
54
54
|
- - ~>
|
@@ -56,7 +56,7 @@ dependencies:
|
|
56
56
|
version: '2.6'
|
57
57
|
type: :development
|
58
58
|
prerelease: false
|
59
|
-
version_requirements: *
|
59
|
+
version_requirements: *9273680
|
60
60
|
description: Thin jruby wrapper around Mongo Java Driver
|
61
61
|
email:
|
62
62
|
- cremes@mac.com
|
@@ -68,7 +68,6 @@ extensions: []
|
|
68
68
|
extra_rdoc_files: []
|
69
69
|
files:
|
70
70
|
- Gemfile
|
71
|
-
- Gemfile.lock
|
72
71
|
- History.txt
|
73
72
|
- LICENSE.txt
|
74
73
|
- README.txt
|
@@ -143,6 +142,7 @@ files:
|
|
143
142
|
- test/replica_sets/replication_ack_test.rb
|
144
143
|
- test/replica_sets/rs_test_helper.rb
|
145
144
|
- test/safe_test.rb
|
145
|
+
- test/subscribe_test.rb
|
146
146
|
- test/support/hash_with_indifferent_access.rb
|
147
147
|
- test/support/keys.rb
|
148
148
|
- test/support_test.rb
|
data/Gemfile.lock
DELETED
@@ -1,44 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
jmongo (1.1.1)
|
5
|
-
require_all (~> 1.2)
|
6
|
-
|
7
|
-
GEM
|
8
|
-
remote: http://rubygems.org/
|
9
|
-
specs:
|
10
|
-
awesome_print (0.4.0)
|
11
|
-
diff-lcs (1.1.3)
|
12
|
-
fuubar (0.0.6)
|
13
|
-
rspec (~> 2.0)
|
14
|
-
rspec-instafail (~> 0.1.8)
|
15
|
-
ruby-progressbar (~> 0.0.10)
|
16
|
-
metaclass (0.0.1)
|
17
|
-
mocha (0.10.0)
|
18
|
-
metaclass (~> 0.0.1)
|
19
|
-
rake (0.9.2)
|
20
|
-
require_all (1.2.0)
|
21
|
-
rspec (2.6.0)
|
22
|
-
rspec-core (~> 2.6.0)
|
23
|
-
rspec-expectations (~> 2.6.0)
|
24
|
-
rspec-mocks (~> 2.6.0)
|
25
|
-
rspec-core (2.6.4)
|
26
|
-
rspec-expectations (2.6.0)
|
27
|
-
diff-lcs (~> 1.1.2)
|
28
|
-
rspec-instafail (0.1.8)
|
29
|
-
rspec-mocks (2.6.0)
|
30
|
-
ruby-progressbar (0.0.10)
|
31
|
-
shoulda (2.11.3)
|
32
|
-
|
33
|
-
PLATFORMS
|
34
|
-
java
|
35
|
-
ruby
|
36
|
-
|
37
|
-
DEPENDENCIES
|
38
|
-
awesome_print (~> 0.4)
|
39
|
-
fuubar (~> 0.0)
|
40
|
-
jmongo!
|
41
|
-
mocha
|
42
|
-
rake
|
43
|
-
rspec (~> 2.6)
|
44
|
-
shoulda
|