openwferu 0.9.10.653 → 0.9.11
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/README.txt +65 -33
- data/examples/README.txt +4 -0
- data/examples/flowtracing.rb +2 -0
- data/examples/homeworkreview.rb +2 -0
- data/examples/mano_tracker.rb +2 -0
- data/examples/openwferu.rb +3 -1
- data/examples/quotereporter.rb +2 -0
- data/examples/scheduler_cron_usage.rb +3 -1
- data/examples/scheduler_usage.rb +3 -1
- data/lib/openwfe/engine/engine.rb +15 -5
- data/lib/openwfe/expool/expressionpool.rb +30 -4
- data/lib/openwfe/expool/journal.rb +16 -18
- data/lib/openwfe/expool/journal_replay.rb +56 -8
- data/lib/openwfe/expool/wfidgen.rb +17 -8
- data/lib/openwfe/expressions/condition.rb +41 -26
- data/lib/openwfe/expressions/expressionmap.rb +7 -0
- data/lib/openwfe/expressions/fe_cancel.rb +1 -1
- data/lib/openwfe/expressions/fe_concurrence.rb +14 -5
- data/lib/openwfe/expressions/fe_cron.rb +3 -1
- data/lib/openwfe/expressions/fe_cursor.rb +1 -1
- data/lib/openwfe/expressions/fe_fqv.rb +58 -0
- data/lib/openwfe/expressions/fe_if.rb +1 -1
- data/lib/openwfe/expressions/fe_iterator.rb +5 -0
- data/lib/openwfe/expressions/fe_listen.rb +224 -0
- data/lib/openwfe/expressions/fe_misc.rb +32 -9
- data/lib/openwfe/expressions/fe_participant.rb +26 -6
- data/lib/openwfe/expressions/fe_sleep.rb +5 -7
- data/lib/openwfe/expressions/fe_timeout.rb +127 -0
- data/lib/openwfe/expressions/fe_when.rb +13 -1
- data/lib/openwfe/expressions/flowexpression.rb +4 -1
- data/lib/openwfe/expressions/time.rb +10 -27
- data/lib/openwfe/expressions/timeout.rb +23 -6
- data/lib/openwfe/flowexpressionid.rb +7 -6
- data/lib/openwfe/listeners/socketlisteners.rb +1 -1
- data/lib/openwfe/participants/enoparticipants.rb +103 -47
- data/lib/openwfe/participants/participant.rb +29 -3
- data/lib/openwfe/participants/participantmap.rb +10 -2
- data/lib/openwfe/participants/participants.rb +31 -19
- data/lib/openwfe/participants/socketparticipants.rb +3 -1
- data/lib/openwfe/rest/controlclient.rb +5 -18
- data/lib/openwfe/rest/oldrestservlet.rb +279 -0
- data/lib/openwfe/rest/restclient.rb +55 -25
- data/lib/openwfe/rest/worklistclient.rb +35 -44
- data/lib/openwfe/rest/xmlcodec.rb +79 -69
- data/lib/openwfe/rudefinitions.rb +15 -7
- data/lib/openwfe/storage/yamlextras.rb +3 -3
- data/lib/openwfe/util/observable.rb +64 -7
- data/lib/openwfe/util/scheduler.rb +107 -77
- data/lib/openwfe/util/workqueue.rb +5 -11
- data/lib/openwfe/utils.rb +3 -3
- data/lib/openwfe/version.rb +1 -2
- data/lib/openwfe/workitem.rb +3 -4
- data/lib/openwfe/worklist/oldrest.rb +244 -0
- data/lib/openwfe/worklist/storelocks.rb +288 -0
- data/lib/openwfe/worklist/storeparticipant.rb +4 -2
- data/lib/openwfe/worklist/worklist.rb +297 -0
- data/test/cron_test.rb +8 -9
- data/test/eno_test.rb +10 -13
- data/test/flowtestbase.rb +26 -17
- data/test/ft_15_iterator.rb +19 -0
- data/test/ft_23c_wait.rb +2 -2
- data/test/ft_2b_concurrence.rb +2 -2
- data/test/ft_30_socketlistener.rb +5 -1
- data/test/ft_32_journal.rb +1 -1
- data/test/ft_32c_journal.rb +102 -0
- data/test/ft_32d_journal.rb +85 -0
- data/test/ft_45_citerator.rb +25 -0
- data/test/ft_49_condition.rb +60 -2
- data/test/ft_4_misc.rb +15 -0
- data/test/ft_50_xml_attribute.rb +4 -4
- data/test/ft_53_null_noop_participant.rb +66 -0
- data/test/ft_54_listen.rb +223 -0
- data/test/ft_55_ptimeout.rb +64 -0
- data/test/ft_56_timeout.rb +55 -0
- data/test/ft_57_a.rb +109 -0
- data/test/ft_tests.rb +7 -0
- data/test/hparticipant_test.rb +3 -3
- data/test/obs_test.rb +115 -0
- data/test/orest_test.rb +224 -0
- data/test/pending.rb +24 -0
- data/test/rake_qtest.rb +5 -1
- data/test/rake_test.rb +4 -0
- data/test/scheduler_test.rb +31 -2
- data/test/sec_test.rb +7 -3
- data/test/slock_test.rb +82 -0
- metadata +19 -3
- data/test/ft_32b_journal.rb +0 -76
data/README.txt
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
= OpenWFEru, Standard Library Documentation
|
|
2
2
|
|
|
3
3
|
== Prerequisites
|
|
4
|
-
Ruby 1.8.
|
|
4
|
+
Ruby 1.8.5 or later
|
|
5
5
|
|
|
6
6
|
== Supported platforms
|
|
7
7
|
TODO
|
|
@@ -32,27 +32,70 @@ These are mostly stolen from the unit tests
|
|
|
32
32
|
|
|
33
33
|
Creating an workflow engine instance
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
require 'rubygems'
|
|
36
|
+
require 'openwfe/def'
|
|
37
|
+
require 'openwfe/workitem'
|
|
38
|
+
require 'openwfe/engine/engine'
|
|
39
|
+
|
|
40
|
+
#
|
|
41
|
+
# instantiating an engine
|
|
42
|
+
|
|
43
|
+
engine = OpenWFE::Engine.new
|
|
44
|
+
|
|
45
|
+
#
|
|
46
|
+
# adding some participants
|
|
47
|
+
|
|
48
|
+
engine.register_participant :alice do |workitem|
|
|
49
|
+
puts "alice got a workitem..."
|
|
50
|
+
workitem.alice_comment = "this thing looks interesting"
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
engine.register_participant :bob do |workitem|
|
|
54
|
+
puts "bob got a workitem..."
|
|
55
|
+
workitem.bob_comment = "not for me, I prefer VB"
|
|
56
|
+
workitem.bob_comment2 = "Bob rules"
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
engine.register_participant :summarize do |workitem|
|
|
60
|
+
puts
|
|
61
|
+
puts "summary of process #{workitem.fei.workflow_instance_id}"
|
|
62
|
+
workitem.attributes.each do |k, v|
|
|
63
|
+
next unless k.match ".*_comment$"
|
|
64
|
+
puts " - #{k} : '#{v}'"
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
#
|
|
69
|
+
# a process definition
|
|
70
|
+
|
|
71
|
+
class TheProcessDefinition0 < OpenWFE::ProcessDefinition
|
|
72
|
+
sequence do
|
|
73
|
+
concurrence do
|
|
74
|
+
participant :alice
|
|
75
|
+
participant :bob
|
|
76
|
+
end
|
|
77
|
+
participant :summarize
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
#
|
|
82
|
+
# launching the process
|
|
83
|
+
|
|
84
|
+
li = OpenWFE::LaunchItem.new(TheProcessDefinition0)
|
|
85
|
+
|
|
86
|
+
li.initial_comment = "please give your impressions about http://ruby-lang.org"
|
|
87
|
+
|
|
88
|
+
fei = engine.launch li
|
|
89
|
+
#
|
|
90
|
+
# 'fei' means FlowExpressionId, the fei returned here is the
|
|
91
|
+
# identifier for the root expression of the newly launched process
|
|
92
|
+
|
|
93
|
+
puts "started process '#{fei.workflow_instance_id}'"
|
|
94
|
+
|
|
95
|
+
engine.wait_for fei
|
|
96
|
+
#
|
|
97
|
+
# blocks until the process terminates
|
|
37
98
|
|
|
38
|
-
# Create an engine to launch the flow
|
|
39
|
-
engine = OpenWFEru::Engine.new
|
|
40
|
-
engine.register_participant('test-.*', OpenWFEru::PrintParticipant.new())
|
|
41
|
-
|
|
42
|
-
# Create a flow definition and assign to a new instance
|
|
43
|
-
flow = '''<process-definition name="equals_0" revision="0">
|
|
44
|
-
<if>
|
|
45
|
-
<equals value="a" other-value="a" />
|
|
46
|
-
<print>${field:__result__}</print>
|
|
47
|
-
</if>
|
|
48
|
-
</process-definition>'''
|
|
49
|
-
li = OpenWFE::LaunchItem.new(flow)
|
|
50
|
-
|
|
51
|
-
# Launch the instance
|
|
52
|
-
engine.launch(li)
|
|
53
|
-
|
|
54
|
-
# Examine it
|
|
55
|
-
pp engine.get_expression_storage
|
|
56
99
|
|
|
57
100
|
== How to help
|
|
58
101
|
|
|
@@ -69,19 +112,11 @@ tedious by hand.
|
|
|
69
112
|
|
|
70
113
|
=== Prerequisites
|
|
71
114
|
|
|
72
|
-
You'll need libxml2-dev in order to compile the native libraries
|
|
73
|
-
for libxml. Please check your your packaging system for the appropriate
|
|
74
|
-
name.
|
|
75
|
-
|
|
76
|
-
On Ubuntu you can install libxml2 with:
|
|
77
|
-
sudo apt-get install libxml2-dev
|
|
78
|
-
|
|
79
115
|
=== Ruby Libraries Install
|
|
80
116
|
|
|
81
117
|
1. gem install -r rake
|
|
82
118
|
2. gem install -r rote redcloth
|
|
83
119
|
3. gem install -r tidy
|
|
84
|
-
4. gem install -r libxml-ruby
|
|
85
120
|
|
|
86
121
|
== Documentation
|
|
87
122
|
|
|
@@ -90,8 +125,5 @@ http://rubyforge.org/projects/openwferu
|
|
|
90
125
|
or
|
|
91
126
|
http://openwferu.rubyforge.org
|
|
92
127
|
|
|
93
|
-
|
|
94
|
-
http://www.openwfe.org/openwfe-ruby.html
|
|
95
|
-
|
|
96
|
-
If you're interested in helping : http://groups.google.com/group/openwferu-users/topics
|
|
128
|
+
The users mailing list is at : http://groups.google.com/group/openwferu-users
|
|
97
129
|
|
data/examples/README.txt
CHANGED
data/examples/flowtracing.rb
CHANGED
data/examples/homeworkreview.rb
CHANGED
data/examples/mano_tracker.rb
CHANGED
data/examples/openwferu.rb
CHANGED
data/examples/quotereporter.rb
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
# showing how to use the scheduler
|
|
4
4
|
#
|
|
5
5
|
|
|
6
|
+
require 'rubygems'
|
|
7
|
+
|
|
6
8
|
require 'time'
|
|
7
9
|
|
|
8
10
|
require 'openwfe/util/scheduler'
|
|
@@ -34,7 +36,7 @@ end
|
|
|
34
36
|
|
|
35
37
|
scheduler.schedule_in("2m10s") do
|
|
36
38
|
p "after 2 minutes and 10 seconds stopping the scheduler and exiting..."
|
|
37
|
-
scheduler.
|
|
39
|
+
scheduler.stop
|
|
38
40
|
end
|
|
39
41
|
#
|
|
40
42
|
# using a regular "at" job to stop the scheduler after 4 minutes
|
data/examples/scheduler_usage.rb
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
# showing how to use the scheduler
|
|
4
4
|
#
|
|
5
5
|
|
|
6
|
+
require 'rubygems'
|
|
7
|
+
|
|
6
8
|
require 'time'
|
|
7
9
|
|
|
8
10
|
require 'openwfe/util/scheduler'
|
|
@@ -35,7 +37,7 @@ end
|
|
|
35
37
|
|
|
36
38
|
scheduler.schedule_in("5500") do
|
|
37
39
|
p "after 5500 ms stopping the scheduler and exiting..."
|
|
38
|
-
scheduler.
|
|
40
|
+
scheduler.stop
|
|
39
41
|
end
|
|
40
42
|
|
|
41
43
|
#scheduler.schedule_at("x" do
|
|
@@ -41,6 +41,7 @@
|
|
|
41
41
|
#
|
|
42
42
|
|
|
43
43
|
require 'logger'
|
|
44
|
+
require 'fileutils'
|
|
44
45
|
|
|
45
46
|
require 'openwfe/workitem'
|
|
46
47
|
require 'openwfe/rudefinitions'
|
|
@@ -70,11 +71,20 @@ module OpenWFE
|
|
|
70
71
|
# Accepts an optional initial application_context (containing
|
|
71
72
|
# initialization params for services for example).
|
|
72
73
|
#
|
|
74
|
+
# The engine itself uses one param :logger, used to define
|
|
75
|
+
# where all the log output for OpenWFEru should go.
|
|
76
|
+
# By default, this output goes to logs/openwferu.log
|
|
77
|
+
#
|
|
73
78
|
def initialize (application_context={})
|
|
74
79
|
|
|
75
80
|
super(S_ENGINE, application_context)
|
|
76
81
|
|
|
77
|
-
$OWFE_LOG =
|
|
82
|
+
$OWFE_LOG = application_context[:logger]
|
|
83
|
+
|
|
84
|
+
unless $OWFE_LOG
|
|
85
|
+
FileUtils.mkdir("logs") unless File.exist?("logs")
|
|
86
|
+
$OWFE_LOG = Logger.new("logs/openwferu.log")
|
|
87
|
+
end
|
|
78
88
|
|
|
79
89
|
# build order matters.
|
|
80
90
|
#
|
|
@@ -91,8 +101,6 @@ module OpenWFE
|
|
|
91
101
|
|
|
92
102
|
build_participant_map()
|
|
93
103
|
|
|
94
|
-
#get_expression_pool.reschedule()
|
|
95
|
-
|
|
96
104
|
linfo { "new() --- engine started --- #{self.object_id}" }
|
|
97
105
|
end
|
|
98
106
|
|
|
@@ -255,10 +263,10 @@ module OpenWFE
|
|
|
255
263
|
|
|
256
264
|
result = if Scheduler.is_cron_string(freq)
|
|
257
265
|
|
|
258
|
-
get_scheduler.schedule(freq,
|
|
266
|
+
get_scheduler.schedule(freq, listener)
|
|
259
267
|
else
|
|
260
268
|
|
|
261
|
-
get_scheduler.schedule_every(freq, listener
|
|
269
|
+
get_scheduler.schedule_every(freq, listener)
|
|
262
270
|
end
|
|
263
271
|
end
|
|
264
272
|
|
|
@@ -332,6 +340,8 @@ module OpenWFE
|
|
|
332
340
|
end
|
|
333
341
|
end
|
|
334
342
|
|
|
343
|
+
linfo { "stop() stopped engine '#{@service_name}'" }
|
|
344
|
+
|
|
335
345
|
nil
|
|
336
346
|
end
|
|
337
347
|
|
|
@@ -47,6 +47,7 @@ require 'rexml/document'
|
|
|
47
47
|
require 'openwfe/utils'
|
|
48
48
|
require 'openwfe/service'
|
|
49
49
|
require 'openwfe/logging'
|
|
50
|
+
require 'openwfe/omixins'
|
|
50
51
|
require 'openwfe/rudefinitions'
|
|
51
52
|
require 'openwfe/flowexpressionid'
|
|
52
53
|
require 'openwfe/util/lru'
|
|
@@ -132,7 +133,8 @@ module OpenWFE
|
|
|
132
133
|
MonitorMixin,
|
|
133
134
|
OwfeServiceLocator,
|
|
134
135
|
Observable,
|
|
135
|
-
WorkqueueMixin
|
|
136
|
+
WorkqueueMixin,
|
|
137
|
+
FeiMixin
|
|
136
138
|
|
|
137
139
|
SAFETY_LEVEL = 2
|
|
138
140
|
#
|
|
@@ -155,7 +157,7 @@ module OpenWFE
|
|
|
155
157
|
end
|
|
156
158
|
|
|
157
159
|
#
|
|
158
|
-
#
|
|
160
|
+
# Stops this expression pool (especially its workqueue).
|
|
159
161
|
#
|
|
160
162
|
def stop
|
|
161
163
|
@stopped = true
|
|
@@ -186,6 +188,9 @@ module OpenWFE
|
|
|
186
188
|
|
|
187
189
|
wfdurl = launchitem.workflow_definition_url
|
|
188
190
|
|
|
191
|
+
raise "launchitem.workflow_definition_url not set, cannot launch" \
|
|
192
|
+
unless wfdurl
|
|
193
|
+
|
|
189
194
|
definition = if wfdurl.match "^field:"
|
|
190
195
|
wfdfield = wfdurl[6..-1]
|
|
191
196
|
launchitem.attributes.delete wfdfield
|
|
@@ -717,10 +722,31 @@ module OpenWFE
|
|
|
717
722
|
|
|
718
723
|
protected
|
|
719
724
|
|
|
725
|
+
#
|
|
726
|
+
# This method is called by the workqueue when processing
|
|
727
|
+
# the atomic work operations.
|
|
728
|
+
#
|
|
720
729
|
def do_process_workelement elt
|
|
721
730
|
|
|
722
|
-
|
|
723
|
-
|
|
731
|
+
begin
|
|
732
|
+
|
|
733
|
+
message, fei, workitem = elt
|
|
734
|
+
send message, fei, workitem
|
|
735
|
+
|
|
736
|
+
rescue Exception => e
|
|
737
|
+
|
|
738
|
+
se = OpenWFE::exception_to_s(e)
|
|
739
|
+
|
|
740
|
+
onotify :error, fei, message, workitem, se
|
|
741
|
+
|
|
742
|
+
fei = extract_fei fei
|
|
743
|
+
|
|
744
|
+
lwarn do
|
|
745
|
+
"#{self.service_name} " +
|
|
746
|
+
"operation :#{message.to_s} on #{fei.to_s} " +
|
|
747
|
+
"failed with\n" + se
|
|
748
|
+
end
|
|
749
|
+
end
|
|
724
750
|
end
|
|
725
751
|
|
|
726
752
|
#
|
|
@@ -107,11 +107,12 @@ module OpenWFE
|
|
|
107
107
|
def queue_event (event, *args)
|
|
108
108
|
synchronize do
|
|
109
109
|
|
|
110
|
+
#ldebug { "queue_event() :#{event}" }
|
|
111
|
+
|
|
110
112
|
return if event == :stop
|
|
111
113
|
return if event == :launch
|
|
112
114
|
return if event == :reschedule
|
|
113
115
|
|
|
114
|
-
#wfid = args[0].parent_wfid
|
|
115
116
|
wfid = extract_fei(args[0]).parent_wfid
|
|
116
117
|
#
|
|
117
118
|
# maybe args[0] could be a FlowExpression instead
|
|
@@ -123,6 +124,8 @@ module OpenWFE
|
|
|
123
124
|
bucket = get_bucket(wfid)
|
|
124
125
|
bucket << e
|
|
125
126
|
|
|
127
|
+
#ldebug { "queue_event() bucket : #{bucket.object_id}" }
|
|
128
|
+
|
|
126
129
|
if event == :terminate
|
|
127
130
|
|
|
128
131
|
bucket.flush
|
|
@@ -133,11 +136,11 @@ module OpenWFE
|
|
|
133
136
|
# 'move' journal to the done/ subdir of journal/
|
|
134
137
|
#
|
|
135
138
|
FileUtils.cp(
|
|
136
|
-
bucket.
|
|
137
|
-
@donedir + "/" + bucket.
|
|
139
|
+
bucket.path,
|
|
140
|
+
@donedir + "/" + File.basename(bucket.path))
|
|
138
141
|
end
|
|
139
142
|
|
|
140
|
-
FileUtils.rm bucket.
|
|
143
|
+
FileUtils.rm bucket.path
|
|
141
144
|
end
|
|
142
145
|
end
|
|
143
146
|
end
|
|
@@ -163,7 +166,7 @@ module OpenWFE
|
|
|
163
166
|
end
|
|
164
167
|
|
|
165
168
|
def get_bucket (wfid)
|
|
166
|
-
@buckets[wfid] ||= Bucket.new(
|
|
169
|
+
@buckets[wfid] ||= Bucket.new(get_path(wfid))
|
|
167
170
|
end
|
|
168
171
|
|
|
169
172
|
def serialize_event (event, *args)
|
|
@@ -172,18 +175,21 @@ module OpenWFE
|
|
|
172
175
|
args.to_yaml
|
|
173
176
|
end
|
|
174
177
|
|
|
178
|
+
def get_path (wfid)
|
|
179
|
+
@workdir + "/" + wfid.to_s + ".journal"
|
|
180
|
+
end
|
|
181
|
+
|
|
175
182
|
#
|
|
176
183
|
# for each process instance, there is one bucket holding the
|
|
177
184
|
# events waiting to get written in the journal
|
|
178
185
|
#
|
|
179
186
|
class Bucket
|
|
180
187
|
|
|
181
|
-
attr_reader :
|
|
188
|
+
attr_reader :path, :events
|
|
182
189
|
|
|
183
|
-
def initialize (
|
|
190
|
+
def initialize (path)
|
|
184
191
|
super()
|
|
185
|
-
@
|
|
186
|
-
@wfid = wfid
|
|
192
|
+
@path = path
|
|
187
193
|
@events = []
|
|
188
194
|
end
|
|
189
195
|
|
|
@@ -197,21 +203,13 @@ module OpenWFE
|
|
|
197
203
|
alias :length :size
|
|
198
204
|
|
|
199
205
|
def flush
|
|
200
|
-
File.open(
|
|
206
|
+
File.open(@path, "a+") do |f|
|
|
201
207
|
@events.each do |e|
|
|
202
208
|
f.puts e
|
|
203
209
|
end
|
|
204
210
|
end
|
|
205
211
|
@events.clear
|
|
206
212
|
end
|
|
207
|
-
|
|
208
|
-
def get_path
|
|
209
|
-
@workdir + "/" + get_file_name
|
|
210
|
-
end
|
|
211
|
-
|
|
212
|
-
def get_file_name
|
|
213
|
-
@wfid.to_s + ".journal"
|
|
214
|
-
end
|
|
215
213
|
end
|
|
216
214
|
|
|
217
215
|
end
|
|
@@ -136,6 +136,60 @@ module OpenWFE
|
|
|
136
136
|
do_decompose(load_events(file_path), [], nil, 0)
|
|
137
137
|
end
|
|
138
138
|
|
|
139
|
+
#
|
|
140
|
+
# Loads a journal file and return the content as a list of
|
|
141
|
+
# events. This method is made available for unit tests, as
|
|
142
|
+
# a public method it has not much interest.
|
|
143
|
+
#
|
|
144
|
+
def load_events (file_path)
|
|
145
|
+
|
|
146
|
+
File.open(file_path) do |f|
|
|
147
|
+
s = YAML.load_stream f
|
|
148
|
+
s.documents
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
#
|
|
153
|
+
# Takes an error event (as stored in the journal) and replays it
|
|
154
|
+
# (usually you'd have to fix the engine conf before replaying
|
|
155
|
+
# the error trigger)
|
|
156
|
+
#
|
|
157
|
+
# (Make sure to fix the cause of the error before triggering this
|
|
158
|
+
# method)
|
|
159
|
+
#
|
|
160
|
+
def replay_at_error (error_source_event)
|
|
161
|
+
|
|
162
|
+
get_expression_pool.queue_work \
|
|
163
|
+
error_source_event[3], # message (:do_apply for example)
|
|
164
|
+
error_source_event[2], # fei or exp
|
|
165
|
+
error_source_event[4] # workitem
|
|
166
|
+
|
|
167
|
+
# 0 is :error and 1 is the date and time of the error
|
|
168
|
+
|
|
169
|
+
linfo do
|
|
170
|
+
fei = extract_fei(error_source_event[2])
|
|
171
|
+
"replay_at_error() #{error_source_event[3]} #{fei}"
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
#
|
|
176
|
+
# Detects the last error that ocurred for a workflow instance
|
|
177
|
+
# and replays at that point (see replay_at_error).
|
|
178
|
+
#
|
|
179
|
+
# (Make sure to fix the cause of the error before triggering this
|
|
180
|
+
# method)
|
|
181
|
+
#
|
|
182
|
+
def replay_at_last_error (wfid)
|
|
183
|
+
|
|
184
|
+
events = load_events(get_path(wfid))
|
|
185
|
+
|
|
186
|
+
error_event = events.reverse.find do |evt|
|
|
187
|
+
evt[0] == :error
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
replay_at_error(error_event)
|
|
191
|
+
end
|
|
192
|
+
|
|
139
193
|
protected
|
|
140
194
|
|
|
141
195
|
def do_decompose (events, result, previous_state, offset)
|
|
@@ -149,14 +203,6 @@ module OpenWFE
|
|
|
149
203
|
do_decompose(events, result, current_state, offset + 1)
|
|
150
204
|
end
|
|
151
205
|
|
|
152
|
-
def load_events (file_path)
|
|
153
|
-
|
|
154
|
-
File.open(file_path) do |f|
|
|
155
|
-
s = YAML.load_stream f
|
|
156
|
-
s.documents
|
|
157
|
-
end
|
|
158
|
-
end
|
|
159
|
-
|
|
160
206
|
def extract_state (file, offset)
|
|
161
207
|
|
|
162
208
|
events = if file.is_a?(String)
|
|
@@ -189,6 +235,7 @@ module OpenWFE
|
|
|
189
235
|
next if etype == :apply
|
|
190
236
|
next if etype == :reply
|
|
191
237
|
next if etype == :reply_to_parent
|
|
238
|
+
next if etype == :error
|
|
192
239
|
next if seen[fei]
|
|
193
240
|
|
|
194
241
|
seen[fei] = true
|
|
@@ -208,6 +255,7 @@ module OpenWFE
|
|
|
208
255
|
fei = extract_fei e[2]
|
|
209
256
|
next if etype == :update
|
|
210
257
|
next if etype == :remove
|
|
258
|
+
next if etype == :error
|
|
211
259
|
#next if etype == :reply_to_parent
|
|
212
260
|
next if seen[fei]
|
|
213
261
|
next unless participants[fei]
|
|
@@ -65,14 +65,7 @@ module OpenWFE
|
|
|
65
65
|
|
|
66
66
|
load_last()
|
|
67
67
|
|
|
68
|
-
|
|
69
|
-
@last_f = File.open(@last_fn, "w+")
|
|
70
|
-
rescue Exception => e
|
|
71
|
-
lwarn do
|
|
72
|
-
"new() failed to open #{@last_fn}, continuing anyway...\n"+
|
|
73
|
-
OpenWFE::exception_to_s(e)
|
|
74
|
-
end
|
|
75
|
-
end
|
|
68
|
+
ensure_last_f
|
|
76
69
|
end
|
|
77
70
|
|
|
78
71
|
#
|
|
@@ -124,11 +117,26 @@ module OpenWFE
|
|
|
124
117
|
# file is closed.
|
|
125
118
|
#
|
|
126
119
|
def stop
|
|
120
|
+
#linfo { "stop() stopping '#{@service_name}'" }
|
|
127
121
|
@last_f.close if @last_f
|
|
128
122
|
end
|
|
129
123
|
|
|
130
124
|
protected
|
|
131
125
|
|
|
126
|
+
def ensure_last_f
|
|
127
|
+
if (not @last_f) or @last_f.closed?
|
|
128
|
+
begin
|
|
129
|
+
@last_f = File.open(@last_fn, "w+")
|
|
130
|
+
rescue Exception => e
|
|
131
|
+
lwarn do
|
|
132
|
+
"new() failed to open #{@last_fn}, "+
|
|
133
|
+
"continuing anyway...\n"+
|
|
134
|
+
OpenWFE::exception_to_s(e)
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
132
140
|
def now
|
|
133
141
|
wfid = Time.now.to_f * 1000 * 10
|
|
134
142
|
wfid.to_i
|
|
@@ -136,6 +144,7 @@ module OpenWFE
|
|
|
136
144
|
|
|
137
145
|
def save_last
|
|
138
146
|
return unless @last_f
|
|
147
|
+
ensure_last_f()
|
|
139
148
|
@last_f.pos = 0
|
|
140
149
|
@last_f.puts @last
|
|
141
150
|
end
|
|
@@ -65,37 +65,19 @@ module OpenWFE
|
|
|
65
65
|
# This is the method brought to expression classes including this
|
|
66
66
|
# mixin. Easy evaluation of a conditon expressed in an attribute.
|
|
67
67
|
#
|
|
68
|
-
def eval_condition (attname, workitem)
|
|
68
|
+
def eval_condition (attname, workitem, nattname=nil)
|
|
69
69
|
|
|
70
|
-
|
|
71
|
-
|
|
70
|
+
positive = nil
|
|
71
|
+
negative = nil
|
|
72
72
|
|
|
73
|
-
|
|
74
|
-
|
|
73
|
+
positive = do_eval_condition(attname, workitem)
|
|
74
|
+
negative = do_eval_condition(nattname, workitem) if nattname
|
|
75
75
|
|
|
76
|
-
|
|
77
|
-
if rconditional and not conditional
|
|
76
|
+
negative = (not negative) if negative != nil
|
|
78
77
|
|
|
79
|
-
return nil
|
|
80
|
-
unless conditional
|
|
78
|
+
return positive if positive != nil
|
|
81
79
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
conditional = from_xml conditional
|
|
85
|
-
|
|
86
|
-
ldebug { "eval_condition() 1 for '#{conditional}'" }
|
|
87
|
-
|
|
88
|
-
begin
|
|
89
|
-
return to_boolean(do_eval(conditional))
|
|
90
|
-
rescue Exception => e
|
|
91
|
-
# probably needs some quoting...
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
conditional = do_quote(conditional)
|
|
95
|
-
|
|
96
|
-
ldebug { "eval_condition() 2 for '#{conditional}'" }
|
|
97
|
-
|
|
98
|
-
to_boolean(do_eval(conditional))
|
|
80
|
+
negative
|
|
99
81
|
end
|
|
100
82
|
|
|
101
83
|
#
|
|
@@ -122,6 +104,39 @@ module OpenWFE
|
|
|
122
104
|
|
|
123
105
|
protected
|
|
124
106
|
|
|
107
|
+
def do_eval_condition (attname, workitem)
|
|
108
|
+
|
|
109
|
+
#attname = pick_attribute(attname) \
|
|
110
|
+
# if attname.is_a?(Array)
|
|
111
|
+
|
|
112
|
+
conditional = lookup_attribute(attname, workitem)
|
|
113
|
+
rconditional = lookup_attribute("r"+attname.to_s, workitem)
|
|
114
|
+
|
|
115
|
+
return do_eval(rconditional) \
|
|
116
|
+
if rconditional and not conditional
|
|
117
|
+
|
|
118
|
+
return nil \
|
|
119
|
+
unless conditional
|
|
120
|
+
|
|
121
|
+
ldebug { "do_eval_condition() 0 for '#{conditional}'" }
|
|
122
|
+
|
|
123
|
+
conditional = from_xml conditional
|
|
124
|
+
|
|
125
|
+
ldebug { "do_eval_condition() 1 for '#{conditional}'" }
|
|
126
|
+
|
|
127
|
+
begin
|
|
128
|
+
return to_boolean(do_eval(conditional))
|
|
129
|
+
rescue Exception => e
|
|
130
|
+
# probably needs some quoting...
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
conditional = do_quote(conditional)
|
|
134
|
+
|
|
135
|
+
ldebug { "do_eval_condition() 2 for '#{conditional}'" }
|
|
136
|
+
|
|
137
|
+
to_boolean(do_eval(conditional))
|
|
138
|
+
end
|
|
139
|
+
|
|
125
140
|
private
|
|
126
141
|
|
|
127
142
|
#
|