ruote-couch 2.1.9 → 2.1.10

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.txt CHANGED
@@ -2,7 +2,15 @@
2
2
  = ruote-couch - CHANGELOG.txt
3
3
 
4
4
 
5
- == ruote-couch 2.1.9 not yet released
5
+ == ruote-couch 2.1.10 released 2010/06/15
6
+
7
+ - storage#ids not returning design doc ids anymore
8
+ - now using CouchDB 0.11 continuous&all_docs
9
+ - multi-worker hardened
10
+ - adapted #query_workitems to ruote 2.1.10
11
+
12
+
13
+ == ruote-couch 2.1.9 released 2010/03/22
6
14
 
7
15
  - trusting rufus-jig : not closing couches anymore
8
16
  - CouchStorage#clear and purge cleanup
data/README.rdoc CHANGED
@@ -5,6 +5,8 @@ A storage implementation for ruote 2.1.x.
5
5
 
6
6
  Warning : this is a very naive implementation for now. Not many optimizations...
7
7
 
8
+ Note : CouchDB >= 0.11
9
+
8
10
 
9
11
  == running tests
10
12
 
data/Rakefile CHANGED
@@ -33,7 +33,7 @@ CouchDB storage for ruote 2.1 (ruby workflow engine)
33
33
  gem.test_file = 'test/test.rb'
34
34
 
35
35
  gem.add_dependency 'ruote', ">= #{Ruote::Couch::VERSION}"
36
- gem.add_dependency 'rufus-jig', '>= 0.1.17'
36
+ gem.add_dependency 'rufus-jig', '>= 0.1.18'
37
37
  gem.add_development_dependency 'yard'
38
38
  gem.add_development_dependency 'rake'
39
39
  gem.add_development_dependency 'jeweler'
data/TODO.txt CHANGED
@@ -1,11 +1,14 @@
1
1
 
2
2
  [x] ct_2 --couch says put(gone) is returning nil... :(
3
3
  [o] ?feed=longpool&heartbeat=x (parallel thread or smarter scheduler ?)
4
+ [o] remove re_put_ok (rufus-jig >= 0.1.18)
4
5
 
5
6
  [ ] view for ats
6
7
  [ ] view for crons
7
8
 
8
9
  [ ] jig / r-couch should not rely on exceptions
9
10
 
10
- [ ] issue with cron '* * * * *' and long-polling
11
+ =================================================+
12
+ [ ] issue with cron '* * * * *' and long-polling |
13
+ =================================================+
11
14
 
@@ -37,9 +37,12 @@ module Ruote::Couch
37
37
 
38
38
  attr_reader :type
39
39
 
40
- def initialize (host, port, type, name, re_put_ok=true)
40
+ attr_reader :couch
41
41
 
42
- opts = { :re_put_ok => re_put_ok }
42
+ def initialize (host, port, type, name)
43
+
44
+ #opts = { :re_put_ok => re_put_ok }
45
+ opts = {}
43
46
  #opts[:timeout] = TODO
44
47
 
45
48
  @couch = Rufus::Jig::Couch.new(host, port, name, opts)
@@ -69,7 +72,13 @@ module Ruote::Couch
69
72
 
70
73
  def delete (doc)
71
74
 
72
- @couch.delete(doc)
75
+ r = @couch.delete(doc)
76
+
77
+ #p [ :del, doc['_id'], Thread.current.object_id.to_s[-3..-1], r.nil? ]
78
+ Thread.pass
79
+ # without this, test/functional/ct_0 fails after 1 to 10 runs...
80
+
81
+ r
73
82
  end
74
83
 
75
84
  def get_many (key, opts)
@@ -84,13 +93,15 @@ module Ruote::Couch
84
93
  rs.select { |doc| ! doc['_id'].match(/^\_design\//) }
85
94
  end
86
95
 
96
+ DESIGN_DOC_REGEX = /^\_design\//
97
+
87
98
  # Returns a sorted list of the ids of all the docs in this database.
88
99
  #
89
100
  def ids
90
101
 
91
102
  rs = @couch.get('_all_docs')
92
103
 
93
- rs['rows'].collect { |r| r['id'] }
104
+ rs['rows'].collect { |r| r['id'] }.reject { |i| i.match(DESIGN_DOC_REGEX) }
94
105
  end
95
106
 
96
107
  def dump
@@ -280,10 +291,9 @@ module Ruote::Couch
280
291
 
281
292
  hwis = hwis.select { |hwi| hwi['fei']['wfid'] == wfid } if wfid
282
293
 
283
- hwis = hwis.select { |hwi|
284
- Ruote::StorageParticipant.matches?(hwi, pname, criteria) }
285
-
286
- hwis.collect { |hwi| Ruote::Workitem.new(hwi) }
294
+ hwis.select { |hwi|
295
+ Ruote::StorageParticipant.matches?(hwi, pname, criteria)
296
+ }
287
297
  end
288
298
 
289
299
  # Returns the design document that goes with this class of database
@@ -22,6 +22,7 @@
22
22
  # Made in Japan.
23
23
  #++
24
24
 
25
+ require 'thread'
25
26
  require 'ruote/storage/base'
26
27
  require 'ruote/couch/version'
27
28
  require 'ruote/couch/database'
@@ -63,7 +64,7 @@ module Couch
63
64
  @prefix = options['couch_prefix'] || options['prefix'] || ''
64
65
  @prefix = "#{@prefix}_" if @prefix.size > 0
65
66
 
66
- @zeroes = 21 # maybe make it an option
67
+ #@zeroes = 21 # maybe make it an option
67
68
  @timeout = options['couch_timeout'] || 60
68
69
 
69
70
  @dbs = {}
@@ -78,14 +79,21 @@ module Couch
78
79
  @host, @port, 'errors', "#{@prefix}ruote_errors")
79
80
 
80
81
  @dbs['expressions'] = WfidIndexedDatabase.new(
81
- @host, @port, 'expressions', "#{@prefix}ruote_expressions", false)
82
+ #@host, @port, 'expressions', "#{@prefix}ruote_expressions", false)
83
+ @host, @port, 'expressions', "#{@prefix}ruote_expressions")
82
84
 
83
85
  @dbs['workitems'] = WorkitemDatabase.new(
84
86
  @host, @port, 'workitems', "#{@prefix}ruote_workitems")
85
87
 
86
88
  put_configuration
87
89
 
88
- @zero_msgs_offset = @zeroes
90
+ #@zero_msgs_offset = @zeroes
91
+ @msgs_thread = nil
92
+ @msgs_queue = ::Queue.new
93
+
94
+ @schedules_thread = nil
95
+ @schedules_queue = ::Queue.new
96
+ @schedules = nil
89
97
  end
90
98
 
91
99
  def put (doc, opts={})
@@ -142,9 +150,12 @@ module Couch
142
150
 
143
151
  def shutdown
144
152
 
145
- @poller.kill if @poller
146
-
147
153
  #@dbs.values.each { |db| db.shutdown }
154
+
155
+ #@poller.kill if @poller
156
+
157
+ @msgs_thread.kill rescue nil
158
+ @schedules_thread.kill rescue nil
148
159
  end
149
160
 
150
161
  # Mainly used by ruote's test/unit/ut_17_storage.rb
@@ -152,7 +163,8 @@ module Couch
152
163
  def add_type (type)
153
164
 
154
165
  @dbs[type] = Database.new(
155
- @host, @port, type, "#{@prefix}ruote_#{type}", false)
166
+ #@host, @port, type, "#{@prefix}ruote_#{type}", false)
167
+ @host, @port, type, "#{@prefix}ruote_#{type}")
156
168
  end
157
169
 
158
170
  # Nukes a db type and reputs it (losing all the documents that were in it).
@@ -193,54 +205,43 @@ module Couch
193
205
  #
194
206
  def get_msgs
195
207
 
196
- if @zero_msgs_offset > 0
208
+ ensure_msgs_thread_is_running
197
209
 
198
- msgs = get_many(
199
- 'msgs', nil, :limit => 300
200
- ).sort { |a, b|
201
- a['put_at'] <=> b['put_at']
202
- }
210
+ msgs = []
203
211
 
204
- @zero_msgs_offset = @zero_msgs_offset - 1 if msgs.size == 0
205
- return msgs
212
+ while @msgs_queue.size > 0
213
+ msgs << @msgs_queue.pop
206
214
  end
207
215
 
208
- @zero_msgs_offset = @zeroes
209
-
210
- schedules = get_many('schedules')
211
-
212
- next_at = schedules.collect { |s| s['at'] }.sort.first
213
- delta = next_at ? (Time.parse(next_at) - Time.now) : nil
214
-
215
- #p [ delta, @timeout ]
216
+ msgs
217
+ end
216
218
 
217
- return [] if delta && delta < 5.0
219
+ def get_schedules (delta, now)
218
220
 
219
- last_seq = @dbs['msgs'].get('_changes')['last_seq']
221
+ ensure_schedules_thread_is_running
220
222
 
221
- timeout = delta ? delta - 3.0 : -1.0
222
- timeout = (timeout < 0.0 || timeout > @timeout) ? @timeout : timeout
223
+ if @schedules.nil?
223
224
 
224
- #p [ Time.now, :last_seq, last_seq, :timeout, timeout ]
225
+ # NOTE : the problem with this approach is that ALL the schedules
226
+ # are stored in memory. Most of the time it's not a problem, but
227
+ # for people will lots of schedules...
225
228
 
226
- begin
229
+ @schedules = get_many('schedules')
230
+ @schedules = @schedules.inject({}) { |h, s| h[s['_id']] = s; h }
231
+ end
227
232
 
228
- @poller = Thread.current
233
+ while @schedules_queue.size > 0
229
234
 
230
- @dbs['msgs'].get(
231
- "_changes?feed=longpoll&heartbeat=60000&since=#{last_seq}",
232
- :timeout => timeout)
233
- # block until there is a change in the 'msgs' db
235
+ deleted, s = @schedules_queue.pop
234
236
 
235
- rescue Exception => e
236
- #rescue Rufus::Jig::TimeoutError => te
237
- # p [ :caught, e.class ]
238
- # e.backtrace.each { |l| puts l }
239
- ensure
240
- @poller = nil
237
+ if deleted
238
+ @schedules.delete(s['_id'])
239
+ else
240
+ @schedules[s['_id']] = s
241
+ end
241
242
  end
242
243
 
243
- []
244
+ filter_schedules(@schedules.values, now)
244
245
  end
245
246
 
246
247
  protected
@@ -253,6 +254,30 @@ module Couch
253
254
 
254
255
  put(conf)
255
256
  end
257
+
258
+ def ensure_msgs_thread_is_running
259
+
260
+ status = @msgs_thread ? @msgs_thread.status : -1
261
+ return if status == 'run' || status == 'sleep'
262
+
263
+ @msgs_thread = Thread.new do
264
+ @dbs['msgs'].couch.on_change do |_, deleted, doc|
265
+ @msgs_queue << doc unless deleted
266
+ end
267
+ end
268
+ end
269
+
270
+ def ensure_schedules_thread_is_running
271
+
272
+ status = @schedules_thread ? @schedules_thread.status : -1
273
+ return if status == 'run' || status == 'sleep'
274
+
275
+ @schedules_thread = Thread.new do
276
+ @dbs['schedules'].couch.on_change do |_, deleted, doc|
277
+ @schedules_queue << [ deleted, doc ]
278
+ end
279
+ end
280
+ end
256
281
  end
257
282
  end
258
283
  end
@@ -1,7 +1,7 @@
1
1
 
2
2
  module Ruote
3
3
  module Couch
4
- VERSION = '2.1.9'
4
+ VERSION = '2.1.10'
5
5
  end
6
6
  end
7
7
 
data/ruote-couch.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{ruote-couch}
8
- s.version = "2.1.9"
8
+ s.version = "2.1.10"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["John Mettraux"]
12
- s.date = %q{2010-03-23}
12
+ s.date = %q{2010-06-15}
13
13
  s.description = %q{CouchDB storage for ruote 2.1 (ruby workflow engine)}
14
14
  s.email = %q{jmettraux@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -31,7 +31,7 @@ Gem::Specification.new do |s|
31
31
  "test/functional/base.rb",
32
32
  "test/functional/ft_0_long_polling.rb",
33
33
  "test/functional/test.rb",
34
- "test/integration_connection.rb",
34
+ "test/functional_connection.rb",
35
35
  "test/test.rb",
36
36
  "test/unit/test.rb",
37
37
  "test/unit/ut_0_design_doc.rb"
@@ -51,21 +51,21 @@ Gem::Specification.new do |s|
51
51
  s.specification_version = 3
52
52
 
53
53
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
54
- s.add_runtime_dependency(%q<ruote>, [">= 2.1.9"])
55
- s.add_runtime_dependency(%q<rufus-jig>, [">= 0.1.17"])
54
+ s.add_runtime_dependency(%q<ruote>, [">= 2.1.10"])
55
+ s.add_runtime_dependency(%q<rufus-jig>, [">= 0.1.18"])
56
56
  s.add_development_dependency(%q<yard>, [">= 0"])
57
57
  s.add_development_dependency(%q<rake>, [">= 0"])
58
58
  s.add_development_dependency(%q<jeweler>, [">= 0"])
59
59
  else
60
- s.add_dependency(%q<ruote>, [">= 2.1.9"])
61
- s.add_dependency(%q<rufus-jig>, [">= 0.1.17"])
60
+ s.add_dependency(%q<ruote>, [">= 2.1.10"])
61
+ s.add_dependency(%q<rufus-jig>, [">= 0.1.18"])
62
62
  s.add_dependency(%q<yard>, [">= 0"])
63
63
  s.add_dependency(%q<rake>, [">= 0"])
64
64
  s.add_dependency(%q<jeweler>, [">= 0"])
65
65
  end
66
66
  else
67
- s.add_dependency(%q<ruote>, [">= 2.1.9"])
68
- s.add_dependency(%q<rufus-jig>, [">= 0.1.17"])
67
+ s.add_dependency(%q<ruote>, [">= 2.1.10"])
68
+ s.add_dependency(%q<rufus-jig>, [">= 0.1.18"])
69
69
  s.add_dependency(%q<yard>, [">= 0"])
70
70
  s.add_dependency(%q<rake>, [">= 0"])
71
71
  s.add_dependency(%q<jeweler>, [">= 0"])
@@ -17,7 +17,18 @@ end
17
17
 
18
18
  require 'ruote/couch/storage'
19
19
 
20
- # TODO : maybe place delete_all_test_databases here
20
+
21
+ unless $_RUOTE_COUCH_CLEANED
22
+
23
+ couch = Rufus::Jig::Couch.new('127.0.0.1', 5984)
24
+ %w[
25
+ configurations errors expressions msgs schedules variables workitems
26
+ ].each do |type|
27
+ couch.delete("/test_ruote_#{type}")
28
+ end
29
+ puts "(purged all /test_ruote_xxx databases)"
30
+ $_RUOTE_COUCH_CLEANED = true
31
+ end
21
32
 
22
33
 
23
34
  def new_storage (opts)
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 2
7
7
  - 1
8
- - 9
9
- version: 2.1.9
8
+ - 10
9
+ version: 2.1.10
10
10
  platform: ruby
11
11
  authors:
12
12
  - John Mettraux
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-03-23 00:00:00 +09:00
17
+ date: 2010-06-15 00:00:00 +09:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -27,8 +27,8 @@ dependencies:
27
27
  segments:
28
28
  - 2
29
29
  - 1
30
- - 9
31
- version: 2.1.9
30
+ - 10
31
+ version: 2.1.10
32
32
  type: :runtime
33
33
  version_requirements: *id001
34
34
  - !ruby/object:Gem::Dependency
@@ -41,8 +41,8 @@ dependencies:
41
41
  segments:
42
42
  - 0
43
43
  - 1
44
- - 17
45
- version: 0.1.17
44
+ - 18
45
+ version: 0.1.18
46
46
  type: :runtime
47
47
  version_requirements: *id002
48
48
  - !ruby/object:Gem::Dependency
@@ -105,7 +105,7 @@ files:
105
105
  - test/functional/base.rb
106
106
  - test/functional/ft_0_long_polling.rb
107
107
  - test/functional/test.rb
108
- - test/integration_connection.rb
108
+ - test/functional_connection.rb
109
109
  - test/test.rb
110
110
  - test/unit/test.rb
111
111
  - test/unit/ut_0_design_doc.rb