ruote-couch 2.1.7 → 2.1.8
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 +5 -0
- data/Rakefile +1 -1
- data/TODO.txt +6 -1
- data/lib/ruote/couch/database.rb +7 -3
- data/lib/ruote/couch/storage.rb +71 -2
- data/lib/ruote/couch/version.rb +1 -1
- data/ruote-couch.gemspec +12 -9
- data/test/functional/base.rb +15 -0
- data/test/functional/ft_0_long_polling.rb +66 -0
- data/test/functional/test.rb +26 -0
- data/test/integration_connection.rb +4 -2
- data/test/test.rb +1 -5
- metadata +45 -23
data/CHANGELOG.txt
CHANGED
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.
|
36
|
+
gem.add_dependency 'rufus-jig', '>= 0.1.15'
|
37
37
|
gem.add_development_dependency 'yard'
|
38
38
|
gem.add_development_dependency 'jeweler'
|
39
39
|
|
data/TODO.txt
CHANGED
@@ -1,8 +1,13 @@
|
|
1
1
|
|
2
|
+
[x] ct_2 --couch says put(gone) is returning nil... :(
|
3
|
+
[o] ?feed=longpool&heartbeat=x (parallel thread or smarter scheduler ?)
|
4
|
+
|
2
5
|
[ ] view for ats
|
3
6
|
[ ] view for crons
|
4
7
|
|
5
8
|
[ ] jig / r-couch should not rely on exceptions
|
6
9
|
|
7
|
-
[
|
10
|
+
[ ] re-run suite with --patron
|
11
|
+
[ ] run suite with --net
|
12
|
+
[ ] run suite with --em
|
8
13
|
|
data/lib/ruote/couch/database.rb
CHANGED
@@ -39,7 +39,11 @@ module Ruote::Couch
|
|
39
39
|
|
40
40
|
def initialize (host, port, type, name, re_put_ok=true)
|
41
41
|
|
42
|
-
|
42
|
+
opts = { :re_put_ok => re_put_ok }
|
43
|
+
#opts[:timeout] = TODO
|
44
|
+
|
45
|
+
@couch = Rufus::Jig::Couch.new(host, port, name, opts)
|
46
|
+
|
43
47
|
@couch.put('.') unless @couch.get('.')
|
44
48
|
|
45
49
|
@type = type
|
@@ -58,9 +62,9 @@ module Ruote::Couch
|
|
58
62
|
# direct "create then apply" chaining
|
59
63
|
end
|
60
64
|
|
61
|
-
def get (key)
|
65
|
+
def get (key, opts={})
|
62
66
|
|
63
|
-
@couch.get(key)
|
67
|
+
@couch.get(key, opts)
|
64
68
|
end
|
65
69
|
|
66
70
|
def delete (doc)
|
data/lib/ruote/couch/storage.rb
CHANGED
@@ -45,9 +45,14 @@ module Couch
|
|
45
45
|
|
46
46
|
# Hooks the storage to a CouchDB instance.
|
47
47
|
#
|
48
|
-
# The main option is '
|
48
|
+
# The main option is 'couch_prefix', which indicate which prefix should be
|
49
49
|
# added to all the database names used by this storage.
|
50
50
|
#
|
51
|
+
# The option 'couch_timeout' is used what is the get_msgs timeout. This
|
52
|
+
# is the long-polling timeout. For functional test it is set to two seconds
|
53
|
+
# but for a production system, something like 10 minutes or 8 hours might
|
54
|
+
# be OK.
|
55
|
+
#
|
51
56
|
def initialize (host, port, options={})
|
52
57
|
|
53
58
|
@host = host
|
@@ -55,9 +60,12 @@ module Couch
|
|
55
60
|
|
56
61
|
@options = options
|
57
62
|
|
58
|
-
@prefix = options['prefix'] || ''
|
63
|
+
@prefix = options['couch_prefix'] || options['prefix'] || ''
|
59
64
|
@prefix = "#{@prefix}_" if @prefix.size > 0
|
60
65
|
|
66
|
+
@zeroes = 21 # maybe make it an option
|
67
|
+
@timeout = options['couch_timeout'] || 60
|
68
|
+
|
61
69
|
@dbs = {}
|
62
70
|
|
63
71
|
%w[ msgs schedules configurations variables ].each do |type|
|
@@ -76,6 +84,8 @@ module Couch
|
|
76
84
|
@host, @port, 'workitems', "#{@prefix}ruote_workitems")
|
77
85
|
|
78
86
|
put_configuration
|
87
|
+
|
88
|
+
@zero_msgs_offset = @zeroes
|
79
89
|
end
|
80
90
|
|
81
91
|
def put (doc, opts={})
|
@@ -119,6 +129,8 @@ module Couch
|
|
119
129
|
|
120
130
|
def shutdown
|
121
131
|
|
132
|
+
@poller.kill if @poller
|
133
|
+
|
122
134
|
@dbs.values.each { |db| db.shutdown }
|
123
135
|
end
|
124
136
|
|
@@ -161,6 +173,63 @@ module Couch
|
|
161
173
|
@dbs['workitems'].query_workitems(criteria)
|
162
174
|
end
|
163
175
|
|
176
|
+
# Overwriting Ruote::StorageBase.get_msgs
|
177
|
+
#
|
178
|
+
# Taking care of using long-polling
|
179
|
+
# (http://wiki.apache.org/couchdb/HTTP_database_API) when possible
|
180
|
+
#
|
181
|
+
def get_msgs
|
182
|
+
|
183
|
+
if @zero_msgs_offset > 0
|
184
|
+
|
185
|
+
msgs = get_many(
|
186
|
+
'msgs', nil, :limit => 300
|
187
|
+
).sort { |a, b|
|
188
|
+
a['put_at'] <=> b['put_at']
|
189
|
+
}
|
190
|
+
|
191
|
+
@zero_msgs_offset = @zero_msgs_offset - 1 if msgs.size == 0
|
192
|
+
return msgs
|
193
|
+
end
|
194
|
+
|
195
|
+
@zero_msgs_offset = @zeroes
|
196
|
+
|
197
|
+
schedules = get_many('schedules')
|
198
|
+
|
199
|
+
next_at = schedules.collect { |s| s['at'] }.sort.first
|
200
|
+
delta = next_at ? (Time.parse(next_at) - Time.now) : nil
|
201
|
+
|
202
|
+
#p [ delta, @timeout ]
|
203
|
+
|
204
|
+
return [] if delta && delta < 5.0
|
205
|
+
|
206
|
+
last_seq = @dbs['msgs'].get('_changes')['last_seq']
|
207
|
+
|
208
|
+
timeout = delta ? delta - 3.0 : -1.0
|
209
|
+
timeout = (timeout < 0.0 || timeout > @timeout) ? @timeout : timeout
|
210
|
+
|
211
|
+
#p [ Time.now, :last_seq, last_seq, :timeout, timeout ]
|
212
|
+
|
213
|
+
begin
|
214
|
+
|
215
|
+
@poller = Thread.current
|
216
|
+
|
217
|
+
@dbs['msgs'].get(
|
218
|
+
"_changes?feed=longpoll&heartbeat=60000&since=#{last_seq}",
|
219
|
+
:timeout => timeout)
|
220
|
+
# block until there is a change in the 'msgs' db
|
221
|
+
|
222
|
+
rescue Exception => e
|
223
|
+
#rescue Rufus::Jig::TimeoutError => te
|
224
|
+
# p [ :caught, e.class ]
|
225
|
+
# e.backtrace.each { |l| puts l }
|
226
|
+
ensure
|
227
|
+
@poller = nil
|
228
|
+
end
|
229
|
+
|
230
|
+
[]
|
231
|
+
end
|
232
|
+
|
164
233
|
protected
|
165
234
|
|
166
235
|
def put_configuration
|
data/lib/ruote/couch/version.rb
CHANGED
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.
|
8
|
+
s.version = "2.1.8"
|
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-
|
12
|
+
s.date = %q{2010-03-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 = [
|
@@ -28,6 +28,9 @@ Gem::Specification.new do |s|
|
|
28
28
|
"lib/ruote/couch/storage.rb",
|
29
29
|
"lib/ruote/couch/version.rb",
|
30
30
|
"ruote-couch.gemspec",
|
31
|
+
"test/functional/base.rb",
|
32
|
+
"test/functional/ft_0_long_polling.rb",
|
33
|
+
"test/functional/test.rb",
|
31
34
|
"test/integration_connection.rb",
|
32
35
|
"test/test.rb"
|
33
36
|
]
|
@@ -35,7 +38,7 @@ Gem::Specification.new do |s|
|
|
35
38
|
s.rdoc_options = ["--charset=UTF-8"]
|
36
39
|
s.require_paths = ["lib"]
|
37
40
|
s.rubyforge_project = %q{ruote}
|
38
|
-
s.rubygems_version = %q{1.3.
|
41
|
+
s.rubygems_version = %q{1.3.6}
|
39
42
|
s.summary = %q{CouchDB storage for ruote 2.1}
|
40
43
|
s.test_files = [
|
41
44
|
"test/test.rb"
|
@@ -46,19 +49,19 @@ Gem::Specification.new do |s|
|
|
46
49
|
s.specification_version = 3
|
47
50
|
|
48
51
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
49
|
-
s.add_runtime_dependency(%q<ruote>, [">= 2.1.
|
50
|
-
s.add_runtime_dependency(%q<rufus-jig>, [">= 0.1.
|
52
|
+
s.add_runtime_dependency(%q<ruote>, [">= 2.1.8"])
|
53
|
+
s.add_runtime_dependency(%q<rufus-jig>, [">= 0.1.15"])
|
51
54
|
s.add_development_dependency(%q<yard>, [">= 0"])
|
52
55
|
s.add_development_dependency(%q<jeweler>, [">= 0"])
|
53
56
|
else
|
54
|
-
s.add_dependency(%q<ruote>, [">= 2.1.
|
55
|
-
s.add_dependency(%q<rufus-jig>, [">= 0.1.
|
57
|
+
s.add_dependency(%q<ruote>, [">= 2.1.8"])
|
58
|
+
s.add_dependency(%q<rufus-jig>, [">= 0.1.15"])
|
56
59
|
s.add_dependency(%q<yard>, [">= 0"])
|
57
60
|
s.add_dependency(%q<jeweler>, [">= 0"])
|
58
61
|
end
|
59
62
|
else
|
60
|
-
s.add_dependency(%q<ruote>, [">= 2.1.
|
61
|
-
s.add_dependency(%q<rufus-jig>, [">= 0.1.
|
63
|
+
s.add_dependency(%q<ruote>, [">= 2.1.8"])
|
64
|
+
s.add_dependency(%q<rufus-jig>, [">= 0.1.15"])
|
62
65
|
s.add_dependency(%q<yard>, [">= 0"])
|
63
66
|
s.add_dependency(%q<jeweler>, [">= 0"])
|
64
67
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
|
2
|
+
$:.unshift(File.join(File.dirname(__FILE__), '..', '..', '..', 'ruote', 'lib'))
|
3
|
+
$:.unshift(File.join(File.dirname(__FILE__), '..', '..', 'lib'))
|
4
|
+
|
5
|
+
require 'test/unit'
|
6
|
+
|
7
|
+
require 'rubygems'
|
8
|
+
require 'yajl'
|
9
|
+
|
10
|
+
require 'patron' unless ARGV.include?('--net')
|
11
|
+
# TODO : provide for em-http-request
|
12
|
+
|
13
|
+
require 'ruote'
|
14
|
+
require 'ruote/couch'
|
15
|
+
|
@@ -0,0 +1,66 @@
|
|
1
|
+
|
2
|
+
#
|
3
|
+
# testing ruote-couch
|
4
|
+
#
|
5
|
+
# Fri Mar 12 17:15:27 JST 2010
|
6
|
+
#
|
7
|
+
|
8
|
+
require File.join(File.dirname(__FILE__), 'base')
|
9
|
+
|
10
|
+
|
11
|
+
class FtLongPollingTest < Test::Unit::TestCase
|
12
|
+
|
13
|
+
def setup
|
14
|
+
|
15
|
+
@engine =
|
16
|
+
Ruote::Engine.new(
|
17
|
+
Ruote::Worker.new(
|
18
|
+
Ruote::Couch::CouchStorage.new(
|
19
|
+
'127.0.0.1',
|
20
|
+
5984,
|
21
|
+
'couch_prefix' => 'test', 'couch_timeout' => 2 * 60)))
|
22
|
+
end
|
23
|
+
|
24
|
+
def teardown
|
25
|
+
|
26
|
+
@engine.shutdown
|
27
|
+
@engine.context.storage.purge!
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_wait
|
31
|
+
|
32
|
+
trace = []
|
33
|
+
|
34
|
+
@engine.register_participant '.+' do |workitem|
|
35
|
+
trace << Time.now
|
36
|
+
end
|
37
|
+
|
38
|
+
pdef = Ruote.process_definition do
|
39
|
+
sequence do
|
40
|
+
alpha
|
41
|
+
wait '3m'
|
42
|
+
bravo
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
@engine.context.logger.noisy = true
|
47
|
+
|
48
|
+
wfid = @engine.launch(pdef)
|
49
|
+
|
50
|
+
sleep 15
|
51
|
+
assert_equal 1, trace.size
|
52
|
+
|
53
|
+
assert_not_nil @engine.context.storage.instance_variable_get(:@poller)
|
54
|
+
|
55
|
+
@engine.wait_for(wfid)
|
56
|
+
|
57
|
+
p trace
|
58
|
+
|
59
|
+
assert_equal 2, trace.size
|
60
|
+
|
61
|
+
delta = trace.last - trace.first
|
62
|
+
|
63
|
+
assert_in_delta 3.0 * 60, delta, 1.0
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
|
2
|
+
#
|
3
|
+
# testing ruote-couch
|
4
|
+
#
|
5
|
+
# Fri Mar 12 17:19:01 JST 2010
|
6
|
+
#
|
7
|
+
|
8
|
+
def l (t)
|
9
|
+
|
10
|
+
if ARGV.include?('--split')
|
11
|
+
|
12
|
+
_v = ARGV.include?('-v') ? ' -v' : ' '
|
13
|
+
|
14
|
+
puts
|
15
|
+
puts "=== #{t} :"
|
16
|
+
puts `ruby#{_v} #{t} #{ARGV.join(' ')}`
|
17
|
+
|
18
|
+
exit $?.exitstatus if $?.exitstatus != 0
|
19
|
+
else
|
20
|
+
load(t)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
Dir.glob(File.join(File.dirname(__FILE__), 'ft_*.rb')).sort.each { |t| l(t) }
|
25
|
+
# functional tests targetting features rather than expressions
|
26
|
+
|
@@ -10,7 +10,7 @@ require 'rufus-json'
|
|
10
10
|
Rufus::Json.detect_backend
|
11
11
|
|
12
12
|
begin
|
13
|
-
require 'patron'
|
13
|
+
require 'patron' unless ARGV.include?('--net')
|
14
14
|
rescue LoadError
|
15
15
|
# then use 'net/http'
|
16
16
|
end
|
@@ -23,6 +23,8 @@ def new_storage (opts)
|
|
23
23
|
opts ||= {}
|
24
24
|
|
25
25
|
Ruote::Couch::CouchStorage.new(
|
26
|
-
'127.0.0.1',
|
26
|
+
'127.0.0.1',
|
27
|
+
5984,
|
28
|
+
opts.merge!('couch_prefix' => 'test', 'couch_timeout' => 1))
|
27
29
|
end
|
28
30
|
|
data/test/test.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruote-couch
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 2
|
7
|
+
- 1
|
8
|
+
- 8
|
9
|
+
version: 2.1.8
|
5
10
|
platform: ruby
|
6
11
|
authors:
|
7
12
|
- John Mettraux
|
@@ -9,49 +14,61 @@ autorequire:
|
|
9
14
|
bindir: bin
|
10
15
|
cert_chain: []
|
11
16
|
|
12
|
-
date: 2010-
|
17
|
+
date: 2010-03-15 00:00:00 +09:00
|
13
18
|
default_executable:
|
14
19
|
dependencies:
|
15
20
|
- !ruby/object:Gem::Dependency
|
16
21
|
name: ruote
|
17
|
-
|
18
|
-
|
19
|
-
version_requirements: !ruby/object:Gem::Requirement
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
20
24
|
requirements:
|
21
25
|
- - ">="
|
22
26
|
- !ruby/object:Gem::Version
|
23
|
-
|
24
|
-
|
27
|
+
segments:
|
28
|
+
- 2
|
29
|
+
- 1
|
30
|
+
- 8
|
31
|
+
version: 2.1.8
|
32
|
+
type: :runtime
|
33
|
+
version_requirements: *id001
|
25
34
|
- !ruby/object:Gem::Dependency
|
26
35
|
name: rufus-jig
|
27
|
-
|
28
|
-
|
29
|
-
version_requirements: !ruby/object:Gem::Requirement
|
36
|
+
prerelease: false
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
30
38
|
requirements:
|
31
39
|
- - ">="
|
32
40
|
- !ruby/object:Gem::Version
|
33
|
-
|
34
|
-
|
41
|
+
segments:
|
42
|
+
- 0
|
43
|
+
- 1
|
44
|
+
- 15
|
45
|
+
version: 0.1.15
|
46
|
+
type: :runtime
|
47
|
+
version_requirements: *id002
|
35
48
|
- !ruby/object:Gem::Dependency
|
36
49
|
name: yard
|
37
|
-
|
38
|
-
|
39
|
-
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
prerelease: false
|
51
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
40
52
|
requirements:
|
41
53
|
- - ">="
|
42
54
|
- !ruby/object:Gem::Version
|
55
|
+
segments:
|
56
|
+
- 0
|
43
57
|
version: "0"
|
44
|
-
|
58
|
+
type: :development
|
59
|
+
version_requirements: *id003
|
45
60
|
- !ruby/object:Gem::Dependency
|
46
61
|
name: jeweler
|
47
|
-
|
48
|
-
|
49
|
-
version_requirements: !ruby/object:Gem::Requirement
|
62
|
+
prerelease: false
|
63
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
50
64
|
requirements:
|
51
65
|
- - ">="
|
52
66
|
- !ruby/object:Gem::Version
|
67
|
+
segments:
|
68
|
+
- 0
|
53
69
|
version: "0"
|
54
|
-
|
70
|
+
type: :development
|
71
|
+
version_requirements: *id004
|
55
72
|
description: CouchDB storage for ruote 2.1 (ruby workflow engine)
|
56
73
|
email: jmettraux@gmail.com
|
57
74
|
executables: []
|
@@ -73,6 +90,9 @@ files:
|
|
73
90
|
- lib/ruote/couch/storage.rb
|
74
91
|
- lib/ruote/couch/version.rb
|
75
92
|
- ruote-couch.gemspec
|
93
|
+
- test/functional/base.rb
|
94
|
+
- test/functional/ft_0_long_polling.rb
|
95
|
+
- test/functional/test.rb
|
76
96
|
- test/integration_connection.rb
|
77
97
|
- test/test.rb
|
78
98
|
has_rdoc: true
|
@@ -88,18 +108,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
88
108
|
requirements:
|
89
109
|
- - ">="
|
90
110
|
- !ruby/object:Gem::Version
|
111
|
+
segments:
|
112
|
+
- 0
|
91
113
|
version: "0"
|
92
|
-
version:
|
93
114
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
94
115
|
requirements:
|
95
116
|
- - ">="
|
96
117
|
- !ruby/object:Gem::Version
|
118
|
+
segments:
|
119
|
+
- 0
|
97
120
|
version: "0"
|
98
|
-
version:
|
99
121
|
requirements: []
|
100
122
|
|
101
123
|
rubyforge_project: ruote
|
102
|
-
rubygems_version: 1.3.
|
124
|
+
rubygems_version: 1.3.6
|
103
125
|
signing_key:
|
104
126
|
specification_version: 3
|
105
127
|
summary: CouchDB storage for ruote 2.1
|