ruote-couch 2.1.9 → 2.1.10

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/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