openwferu 0.9.2 → 0.9.3
Sign up to get free protection for your applications and to get access to all the features.
- data/examples/mano_tracker.rb +165 -0
- data/examples/scheduler_cron_usage.rb +46 -0
- data/examples/scheduler_usage.rb +54 -0
- data/lib/openwfe/contextual.rb +7 -1
- data/lib/openwfe/engine/engine.rb +58 -15
- data/lib/openwfe/expool/expressionpool.rb +116 -14
- data/lib/openwfe/expool/expstorage.rb +12 -12
- data/lib/openwfe/expool/journalexpstorage.rb +1 -1
- data/lib/openwfe/expool/yamlexpstorage.rb +58 -22
- data/lib/openwfe/expressions/environment.rb +32 -2
- data/lib/openwfe/expressions/expressionmap.rb +17 -0
- data/lib/openwfe/expressions/fe_condition.rb +122 -0
- data/lib/openwfe/expressions/fe_cursor.rb +14 -5
- data/lib/openwfe/expressions/fe_participant.rb +55 -4
- data/lib/openwfe/expressions/fe_raw.rb +43 -12
- data/lib/openwfe/expressions/fe_subprocess.rb +10 -0
- data/lib/openwfe/expressions/fe_time.rb +117 -22
- data/lib/openwfe/expressions/fe_value.rb +27 -8
- data/lib/openwfe/expressions/flowexpression.rb +13 -6
- data/lib/openwfe/expressions/raw_prog.rb +13 -11
- data/lib/openwfe/expressions/timeout.rb +94 -0
- data/lib/openwfe/flowexpressionid.rb +17 -19
- data/lib/openwfe/logging.rb +35 -16
- data/lib/openwfe/participants/atomparticipants.rb +31 -7
- data/lib/openwfe/participants/enoparticipant.rb +43 -3
- data/lib/openwfe/participants/participant.rb +21 -1
- data/lib/openwfe/participants/participantmap.rb +4 -2
- data/lib/openwfe/participants/participants.rb +12 -17
- data/lib/openwfe/participants/soapparticipants.rb +15 -3
- data/lib/openwfe/rudefinitions.rb +3 -0
- data/lib/openwfe/service.rb +8 -0
- data/lib/openwfe/storage/yamlfilestorage.rb +85 -47
- data/lib/openwfe/{otime.rb → util/otime.rb} +0 -0
- data/lib/openwfe/util/scheduler.rb +415 -231
- data/lib/openwfe/util/schedulers.rb +11 -3
- data/lib/openwfe/util/stoppable.rb +69 -0
- data/lib/openwfe/utils.rb +14 -25
- data/lib/openwfe/workitem.rb +12 -6
- data/lib/openwfe/worklist/storeparticipant.rb +145 -0
- data/test/{atomtest.rb → atom_test.rb} +0 -0
- data/test/{crontest.rb → cron_test.rb} +7 -6
- data/test/cronline_test.rb +51 -0
- data/test/{dollartest.rb → dollar_test.rb} +0 -0
- data/test/{feitest.rb → fei_test.rb} +0 -0
- data/test/file_persistence_test.rb +15 -9
- data/test/flowtestbase.rb +11 -5
- data/test/ft_0.rb +8 -0
- data/test/ft_10_loop.rb +72 -10
- data/test/ft_11_ppd.rb +49 -0
- data/test/ft_17_condition.rb +83 -0
- data/test/ft_18_pname.rb +59 -0
- data/test/hparticipant_test.rb +96 -0
- data/test/{misctest.rb → misc_test.rb} +1 -1
- data/test/rake_qtest.rb +10 -4
- data/test/rake_test.rb +12 -1
- data/test/raw_prog_test.rb +1 -1
- data/test/restart_cron_test.rb +78 -0
- data/test/restart_test.rb +79 -0
- data/test/scheduler_test.rb +92 -0
- data/test/{timetest.rb → time_test.rb} +3 -38
- data/test/timeout_test.rb +73 -0
- metadata +26 -11
- data/lib/openwfe/worklist/worklists.rb +0 -175
@@ -0,0 +1,165 @@
|
|
1
|
+
#
|
2
|
+
#--
|
3
|
+
# Copyright (c) 2007, John Mettraux OpenWFE.org
|
4
|
+
# All rights reserved.
|
5
|
+
#
|
6
|
+
# Redistribution and use in source and binary forms, with or without
|
7
|
+
# modification, are permitted provided that the following conditions are met:
|
8
|
+
#
|
9
|
+
# . Redistributions of source code must retain the above copyright notice, this
|
10
|
+
# list of conditions and the following disclaimer.
|
11
|
+
#
|
12
|
+
# . Redistributions in binary form must reproduce the above copyright notice,
|
13
|
+
# this list of conditions and the following disclaimer in the documentation
|
14
|
+
# and/or other materials provided with the distribution.
|
15
|
+
#
|
16
|
+
# . Neither the name of the "OpenWFE" nor the names of its contributors may be
|
17
|
+
# used to endorse or promote products derived from this software without
|
18
|
+
# specific prior written permission.
|
19
|
+
#
|
20
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
21
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
22
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
23
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
24
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
25
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
26
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
27
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
28
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
29
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
30
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
31
|
+
#++
|
32
|
+
#
|
33
|
+
# $Id: definitions.rb 2725 2006-06-02 13:26:32Z jmettraux $
|
34
|
+
#
|
35
|
+
|
36
|
+
#
|
37
|
+
# "made in Japan"
|
38
|
+
#
|
39
|
+
# John Mettraux at openwfe.org
|
40
|
+
#
|
41
|
+
|
42
|
+
#
|
43
|
+
# see
|
44
|
+
# http://groups.google.com/group/openwferu-users/browse_frm/thread/81294030fc52cd04
|
45
|
+
# for the context of this example
|
46
|
+
#
|
47
|
+
|
48
|
+
require 'openwfe/engine/engine'
|
49
|
+
require 'openwfe/expressions/raw_prog'
|
50
|
+
require 'openwfe/participants/storeparticipant'
|
51
|
+
|
52
|
+
|
53
|
+
#
|
54
|
+
# The process definition
|
55
|
+
# (using a programmatic process definition instead of an XML process definition)
|
56
|
+
|
57
|
+
class TrackerDefinition < OpenWFE::ProcessDefinition
|
58
|
+
def make
|
59
|
+
|
60
|
+
process_definition :name => "mano_tracker", :revision => "0.2" do
|
61
|
+
_loop do
|
62
|
+
participant "${f:creative}"
|
63
|
+
participant "${f:analyst}"
|
64
|
+
|
65
|
+
_break :if => "${f:done}"
|
66
|
+
#
|
67
|
+
# loops until the analyst sets the value of the field
|
68
|
+
# 'done' to true.
|
69
|
+
end
|
70
|
+
#
|
71
|
+
# 'loop' and 'break' are ruby keywords, they have to be
|
72
|
+
# preceded by an underscore '_' to be used in their
|
73
|
+
# OpenWFEru sense.
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
#
|
79
|
+
# prepare the engine and the participants
|
80
|
+
|
81
|
+
ANALYSTS = [ "Mano", "Matt", "Moe" ]
|
82
|
+
CREATIVES = [ "Jamie", "Jeff", "John", "Jeremy" ]
|
83
|
+
|
84
|
+
#
|
85
|
+
# instantiate the engine (a transient one is sufficient for the example)
|
86
|
+
|
87
|
+
$engine = OpenWFE::engine.new
|
88
|
+
#
|
89
|
+
# setting up a transient engine
|
90
|
+
|
91
|
+
$analyst_stores = {}
|
92
|
+
$creative_stores = {}
|
93
|
+
#
|
94
|
+
# gathering the stores for our fictitious organization
|
95
|
+
|
96
|
+
def add_stores (names, store_map)
|
97
|
+
names.each do |name|
|
98
|
+
hp = OpenWFE::HashParticipant.new
|
99
|
+
$engine.register_participant(name, hp)
|
100
|
+
store_map[name] = hp
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
add_stores(ANALYSTS, $analyst_stores)
|
105
|
+
add_stores(CREATIVES, $creative_stores)
|
106
|
+
|
107
|
+
#
|
108
|
+
# a quick method for launching a tracker process instance
|
109
|
+
#
|
110
|
+
def launch_tracker (analyst_name, creative_name, title, item_url)
|
111
|
+
|
112
|
+
li = LaunchItem.new(TrackerDefinition)
|
113
|
+
#
|
114
|
+
# preparing a lunchitem ;) around our TrackerDefinition
|
115
|
+
|
116
|
+
li.analyst = analyst_name
|
117
|
+
li.creative = creative_name
|
118
|
+
li.title = title
|
119
|
+
li.item_url = item_url
|
120
|
+
#
|
121
|
+
# filling the workitem with attributes
|
122
|
+
|
123
|
+
$engine.launch(li)
|
124
|
+
end
|
125
|
+
|
126
|
+
# the system is ready...
|
127
|
+
|
128
|
+
|
129
|
+
#
|
130
|
+
# (...)
|
131
|
+
#
|
132
|
+
# Later it can be used as follow
|
133
|
+
|
134
|
+
fei = launch_tracker(
|
135
|
+
"Mano",
|
136
|
+
"Jamie",
|
137
|
+
"new logo for company",
|
138
|
+
"http://openwferu.rubyforge.org/images/openwfe-logo.png")
|
139
|
+
|
140
|
+
puts "launched tracker process #{fei.workflow_instance_id}"
|
141
|
+
|
142
|
+
#
|
143
|
+
# the creative Jamie can browse the items he has to treat with :
|
144
|
+
|
145
|
+
jamie_store = $analyst_stores["Jamie"]
|
146
|
+
|
147
|
+
first_fei = nil
|
148
|
+
|
149
|
+
jamie_store.each do |fei, workitem|
|
150
|
+
first_fei = fei unless fei
|
151
|
+
puts " - #{fei.workflow_instance_id} -- #{workitem.title}"
|
152
|
+
end
|
153
|
+
|
154
|
+
workitem = jamie_store[first_fei]
|
155
|
+
|
156
|
+
# play with the workitem and then send it back to the engine
|
157
|
+
|
158
|
+
workitem.item_url = "some other url"
|
159
|
+
#
|
160
|
+
# actually just changing the item_url
|
161
|
+
|
162
|
+
jamie_store.forward(workitem)
|
163
|
+
|
164
|
+
# ...
|
165
|
+
|
@@ -0,0 +1,46 @@
|
|
1
|
+
|
2
|
+
#
|
3
|
+
# showing how to use the scheduler
|
4
|
+
#
|
5
|
+
|
6
|
+
require 'time'
|
7
|
+
|
8
|
+
require 'openwfe/util/scheduler'
|
9
|
+
include OpenWFE
|
10
|
+
|
11
|
+
|
12
|
+
def p (msg)
|
13
|
+
t = Time.new
|
14
|
+
puts "#{t.iso8601} -- #{msg}"
|
15
|
+
end
|
16
|
+
#
|
17
|
+
# a small method for displaying the time at the beginning
|
18
|
+
# of each output line
|
19
|
+
|
20
|
+
|
21
|
+
scheduler = Scheduler.new
|
22
|
+
scheduler.start
|
23
|
+
#
|
24
|
+
# create a scheduler instance and start it
|
25
|
+
|
26
|
+
p "started scheduler"
|
27
|
+
|
28
|
+
i = 0
|
29
|
+
|
30
|
+
scheduler.schedule("1-60 * * * *") do
|
31
|
+
p "minute ##{i}"
|
32
|
+
i = i + 1
|
33
|
+
end
|
34
|
+
|
35
|
+
scheduler.schedule_in("2m10s") do
|
36
|
+
p "after 2 minutes and 10 seconds stopping the scheduler and exiting..."
|
37
|
+
scheduler.do_stop
|
38
|
+
end
|
39
|
+
#
|
40
|
+
# using a regular "at" job to stop the scheduler after 4 minutes
|
41
|
+
|
42
|
+
scheduler.join
|
43
|
+
#
|
44
|
+
# align the thread of this program to the scheduler thread
|
45
|
+
# i.e. exit program only when scheduler terminates
|
46
|
+
|
@@ -0,0 +1,54 @@
|
|
1
|
+
|
2
|
+
#
|
3
|
+
# showing how to use the scheduler
|
4
|
+
#
|
5
|
+
|
6
|
+
require 'time'
|
7
|
+
|
8
|
+
require 'openwfe/util/scheduler'
|
9
|
+
include OpenWFE
|
10
|
+
|
11
|
+
|
12
|
+
def p (msg)
|
13
|
+
t = Time.new
|
14
|
+
puts "#{t.iso8601} -- #{msg}"
|
15
|
+
end
|
16
|
+
#
|
17
|
+
# a small method for displaying the time at the beginning
|
18
|
+
# of each output line
|
19
|
+
|
20
|
+
|
21
|
+
scheduler = Scheduler.new
|
22
|
+
scheduler.start
|
23
|
+
#
|
24
|
+
# create a scheduler instance and start it
|
25
|
+
|
26
|
+
p "started scheduler"
|
27
|
+
|
28
|
+
scheduler.schedule_in("3s") do
|
29
|
+
p "after 3 seconds"
|
30
|
+
end
|
31
|
+
|
32
|
+
scheduler.schedule_in("2s") do
|
33
|
+
p "after 2 seconds"
|
34
|
+
end
|
35
|
+
|
36
|
+
scheduler.schedule_in("5500") do
|
37
|
+
p "after 5500 ms stopping the scheduler and exiting..."
|
38
|
+
scheduler.do_stop
|
39
|
+
end
|
40
|
+
|
41
|
+
#scheduler.schedule_at("x" do
|
42
|
+
#end
|
43
|
+
|
44
|
+
#scheduler.schedule_in("3M4h27m") do
|
45
|
+
# p "3 months, 4 hours and 27 minutes... A bit too much"
|
46
|
+
#end
|
47
|
+
#
|
48
|
+
# showing what the time strings are capable of
|
49
|
+
|
50
|
+
scheduler.join
|
51
|
+
#
|
52
|
+
# align the thread of this program to the scheduler thread
|
53
|
+
# i.e. exit program only when scheduler terminates
|
54
|
+
|
data/lib/openwfe/contextual.rb
CHANGED
@@ -38,9 +38,14 @@
|
|
38
38
|
#
|
39
39
|
# John Mettraux at openwfe.org
|
40
40
|
# Nicolas Modrzyk at openwfe.org
|
41
|
+
#
|
41
42
|
|
42
43
|
module OpenWFE
|
43
44
|
|
45
|
+
#
|
46
|
+
# This mixin helds an application_context field and provides a
|
47
|
+
# lookup method for digging into that context.
|
48
|
+
#
|
44
49
|
module Contextual
|
45
50
|
|
46
51
|
attr_accessor :application_context
|
@@ -61,8 +66,9 @@ module OpenWFE
|
|
61
66
|
end
|
62
67
|
|
63
68
|
#
|
64
|
-
#
|
69
|
+
# Use reflection to instantiate the new service,and
|
65
70
|
# add it to the application context
|
71
|
+
#
|
66
72
|
def init_service (service_name, service_class)
|
67
73
|
@application_context[service_name] = \
|
68
74
|
service_class.new(service_name,@application_context)
|
@@ -40,6 +40,8 @@
|
|
40
40
|
# Nicolas Modrzyk at openwfe.org
|
41
41
|
#
|
42
42
|
|
43
|
+
require 'logger'
|
44
|
+
|
43
45
|
require 'openwfe/workitem'
|
44
46
|
require 'openwfe/rudefinitions'
|
45
47
|
require 'openwfe/service'
|
@@ -65,44 +67,54 @@ module OpenWFE
|
|
65
67
|
|
66
68
|
@application_context[@service_name] = self
|
67
69
|
|
70
|
+
build_scheduler()
|
71
|
+
|
68
72
|
build_expression_map()
|
69
|
-
build_expression_pool()
|
70
73
|
build_expression_storage()
|
74
|
+
build_expression_pool()
|
75
|
+
|
71
76
|
build_participant_map()
|
72
|
-
build_scheduler()
|
73
77
|
|
74
|
-
|
78
|
+
$OWFE_LOG = Logger.new("engine.log") unless $LOG
|
75
79
|
end
|
76
80
|
|
77
81
|
#
|
78
82
|
# Launches a [business] process.
|
79
|
-
# The '
|
83
|
+
# The 'launch_object' param may contain either a LaunchItem instance,
|
80
84
|
# either a String containing the URL of the process definition
|
81
85
|
# to launch (with an empty LaunchItem created on the fly).
|
82
86
|
#
|
83
|
-
def launch (
|
87
|
+
def launch (launch_object)
|
84
88
|
|
85
89
|
launchitem = nil
|
86
90
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
launchitem =
|
91
|
-
|
92
|
-
#nada
|
93
|
-
elsif object.kind_of? String
|
91
|
+
if launch_object.kind_of? OpenWFE::LaunchItem
|
92
|
+
launchitem = launch_object
|
93
|
+
elsif launch_object.kind_of? Class
|
94
|
+
launchitem = LaunchItem.new(launch_object)
|
95
|
+
elsif launch_object.kind_of? String
|
94
96
|
launchitem = OpenWFE::LaunchItem.new
|
95
|
-
if
|
97
|
+
if launch_object[0] == '<'
|
96
98
|
launchitem.workflowDefinitionUrl = "field:__definition"
|
97
|
-
launchitem['definition'] =
|
99
|
+
launchitem['definition'] = launch_object
|
98
100
|
else
|
99
|
-
launchitem.workflowDefinitionUrl =
|
101
|
+
launchitem.workflowDefinitionUrl = launch_object
|
100
102
|
end
|
101
103
|
end
|
102
104
|
|
103
105
|
get_expression_pool.launch(launchitem)
|
104
106
|
end
|
105
107
|
|
108
|
+
#
|
109
|
+
# This method is used to feed a workitem back to the engine (after
|
110
|
+
# it got sent to a worklist or wherever by a participant).
|
111
|
+
# Participant implementations themselves do call this method usually.
|
112
|
+
#
|
113
|
+
def reply (workitem)
|
114
|
+
|
115
|
+
get_expression_pool.reply(workitem.last_expression_id, workitem)
|
116
|
+
end
|
117
|
+
|
106
118
|
#
|
107
119
|
# Registers a participant in this [embedded] engine.
|
108
120
|
# This method is a shortcut to the ParticipantMap method
|
@@ -113,6 +125,37 @@ module OpenWFE
|
|
113
125
|
get_participant_map.register_participant(regex, participant, &block)
|
114
126
|
end
|
115
127
|
|
128
|
+
#
|
129
|
+
# Given a participant name, returns the participant in charge
|
130
|
+
# of handling workitems for that name.
|
131
|
+
# May be useful in some embedded contexts.
|
132
|
+
#
|
133
|
+
def get_participant (participant_name)
|
134
|
+
|
135
|
+
get_participant_map.lookup_participant(participant_name)
|
136
|
+
end
|
137
|
+
|
138
|
+
#
|
139
|
+
# Stopping the engine will stop all the services in the
|
140
|
+
# application context.
|
141
|
+
#
|
142
|
+
def stop
|
143
|
+
|
144
|
+
linfo { "stop() stopping engine '#{@service_name}'" }
|
145
|
+
|
146
|
+
@application_context.each do |name, service|
|
147
|
+
next if name == self.service_name
|
148
|
+
#service.stop if service.respond_to? :stop
|
149
|
+
if service.kind_of? ServiceMixin
|
150
|
+
service.stop
|
151
|
+
linfo do
|
152
|
+
"stop() stopped service '#{service.service_name}' "+
|
153
|
+
"(#{service.class})"
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
116
159
|
protected
|
117
160
|
|
118
161
|
#
|
@@ -49,6 +49,7 @@ require 'openwfe/service'
|
|
49
49
|
require 'openwfe/logging'
|
50
50
|
require 'openwfe/rudefinitions'
|
51
51
|
require 'openwfe/flowexpressionid'
|
52
|
+
require 'openwfe/util/stoppable'
|
52
53
|
require 'openwfe/util/lru_cache'
|
53
54
|
require 'openwfe/expressions/environment'
|
54
55
|
require 'openwfe/expressions/raw_xml'
|
@@ -120,16 +121,30 @@ module OpenWFE
|
|
120
121
|
# It relies on an expression storage for actual persistence of the
|
121
122
|
# expressions.
|
122
123
|
#
|
123
|
-
class ExpressionPool
|
124
|
-
include MonitorMixin, OwfeServiceLocator
|
124
|
+
class ExpressionPool
|
125
|
+
include ServiceMixin, MonitorMixin, OwfeServiceLocator, Stoppable
|
125
126
|
|
126
127
|
@@last_given_instance_id = -1
|
127
128
|
#
|
128
129
|
# storing at class level the last workflow instance id given
|
129
130
|
|
130
|
-
def initialize (
|
131
|
-
|
131
|
+
def initialize (service_name, application_context)
|
132
|
+
|
133
|
+
super()
|
134
|
+
|
135
|
+
service_init(service_name, application_context)
|
136
|
+
|
132
137
|
@monitors = MonitorProvider.new(application_context)
|
138
|
+
|
139
|
+
reschedule_a_bit_later
|
140
|
+
end
|
141
|
+
|
142
|
+
#
|
143
|
+
# Makes sure to call the do_stop() method of the Stoppable mixin
|
144
|
+
#
|
145
|
+
def stop
|
146
|
+
# would an alias be better ?
|
147
|
+
do_stop
|
133
148
|
end
|
134
149
|
|
135
150
|
#
|
@@ -151,17 +166,28 @@ module OpenWFE
|
|
151
166
|
wi = build_workitem(launchitem)
|
152
167
|
|
153
168
|
rawExpression.apply(wi)
|
169
|
+
|
170
|
+
return wi.flow_expression_id
|
154
171
|
end
|
155
172
|
|
156
173
|
#
|
157
174
|
# launches a subprocess
|
158
175
|
#
|
159
176
|
def launch_template \
|
160
|
-
(requesting_expression,
|
177
|
+
(requesting_expression, template, workitem, params=nil)
|
178
|
+
|
179
|
+
#ldebug { "launch_template() of class #{template.class}" }
|
161
180
|
|
162
|
-
|
181
|
+
rawexp = nil
|
182
|
+
|
183
|
+
if template.kind_of? FlowExpressionId
|
184
|
+
rawexp, fei = fetch(template)
|
185
|
+
else # template is of kind RawExpression
|
186
|
+
rawexp = template
|
187
|
+
end
|
188
|
+
|
189
|
+
ldebug { "launch_template() request for #{rawexp.fei.to_debug_s}" }
|
163
190
|
|
164
|
-
rawexp, fei = fetch(template_fei)
|
165
191
|
rawexp = rawexp.dup()
|
166
192
|
rawexp.fei = rawexp.fei.dup()
|
167
193
|
|
@@ -178,6 +204,14 @@ module OpenWFE
|
|
178
204
|
rawexp.fei.workflow_instance_id = \
|
179
205
|
"#{requesting_expression.fei.workflow_instance_id}.0"
|
180
206
|
end
|
207
|
+
|
208
|
+
#ldebug do
|
209
|
+
# p = ""
|
210
|
+
# p = rawexp.parent_id.to_debug_s if rawexp.parent_id
|
211
|
+
# "launch_template()\n"+
|
212
|
+
# " rawexp.fei is #{rawexp.fei.to_debug_s}\n"+
|
213
|
+
# " rawexp.parent_id is #{p}"
|
214
|
+
#end
|
181
215
|
|
182
216
|
#ldebug do
|
183
217
|
# "launch_template() spawning wfid " +
|
@@ -193,6 +227,8 @@ module OpenWFE
|
|
193
227
|
rawexp.store_itself()
|
194
228
|
|
195
229
|
rawexp.apply(workitem)
|
230
|
+
|
231
|
+
return workitem.flow_expression_id
|
196
232
|
end
|
197
233
|
|
198
234
|
#
|
@@ -270,7 +306,13 @@ module OpenWFE
|
|
270
306
|
|
271
307
|
workitem.last_expression_id = fei
|
272
308
|
|
273
|
-
remove(exp, workitem)
|
309
|
+
#remove(exp, workitem)
|
310
|
+
remove(exp)
|
311
|
+
|
312
|
+
#
|
313
|
+
# remove all the children of the expression
|
314
|
+
|
315
|
+
exp.clean_children()
|
274
316
|
|
275
317
|
if not exp.parent_id
|
276
318
|
ldebug do
|
@@ -325,6 +367,7 @@ module OpenWFE
|
|
325
367
|
#
|
326
368
|
def fetch (exp)
|
327
369
|
synchronize do
|
370
|
+
|
328
371
|
fei = exp
|
329
372
|
if exp.kind_of? FlowExpression
|
330
373
|
fei = exp.fei
|
@@ -333,6 +376,9 @@ module OpenWFE
|
|
333
376
|
"Cannot fetch expression with key : "+
|
334
377
|
"'#{fei}' (#{fei.class})"
|
335
378
|
end
|
379
|
+
|
380
|
+
ldebug { "fetch() for #{fei.to_debug_s}" }
|
381
|
+
|
336
382
|
return get_expression_storage()[fei], fei
|
337
383
|
end
|
338
384
|
end
|
@@ -360,8 +406,6 @@ module OpenWFE
|
|
360
406
|
ee.store_itself()
|
361
407
|
end
|
362
408
|
|
363
|
-
ldebug { "fetch_engine_environment() stored new ee" }
|
364
|
-
|
365
409
|
return ee
|
366
410
|
end
|
367
411
|
end
|
@@ -370,7 +414,7 @@ module OpenWFE
|
|
370
414
|
# Removes a flow expression from the pool
|
371
415
|
# (This method is mainly called from the pool itself)
|
372
416
|
#
|
373
|
-
def remove (exp
|
417
|
+
def remove (exp)
|
374
418
|
|
375
419
|
exp, fei = fetch(exp)
|
376
420
|
|
@@ -382,8 +426,8 @@ module OpenWFE
|
|
382
426
|
|
383
427
|
@monitors.delete(fei)
|
384
428
|
|
385
|
-
#get_expression_storage().
|
386
|
-
get_expression_storage().
|
429
|
+
#get_expression_storage().remove(fei, workitem)
|
430
|
+
get_expression_storage().delete(fei)
|
387
431
|
|
388
432
|
if exp.owns_its_environment?
|
389
433
|
remove_environment(exp.environment_id)
|
@@ -392,6 +436,44 @@ module OpenWFE
|
|
392
436
|
end
|
393
437
|
end
|
394
438
|
|
439
|
+
#
|
440
|
+
# This method is called at each expool (engine) [re]start.
|
441
|
+
# It roams through the previously saved (persisted) expressions
|
442
|
+
# to reschedule ones like 'sleep' or 'cron'.
|
443
|
+
#
|
444
|
+
def reschedule
|
445
|
+
synchronize do
|
446
|
+
|
447
|
+
#if is_stopped?
|
448
|
+
# linfo { "reschedule() skipped as expool is stopped" }
|
449
|
+
# return
|
450
|
+
#end
|
451
|
+
#if get_scheduler.is_stopped?
|
452
|
+
# linfo do
|
453
|
+
# "reschedule() skipped as scheduler "+
|
454
|
+
# "#{get_scheduler.object_id} is stopped"
|
455
|
+
# end
|
456
|
+
# return
|
457
|
+
#end
|
458
|
+
|
459
|
+
ldebug { "reschedule() initiating..." }
|
460
|
+
|
461
|
+
get_expression_storage.each_of_kind(Schedulable) do |fe|
|
462
|
+
|
463
|
+
ldebug { "reschedule() for #{fe.fei.to_debug_s}..." }
|
464
|
+
|
465
|
+
fe.reschedule(get_scheduler)
|
466
|
+
end
|
467
|
+
|
468
|
+
ldebug { "reschedule() done." }
|
469
|
+
end
|
470
|
+
end
|
471
|
+
|
472
|
+
#
|
473
|
+
# Returns the unique engine_environment FlowExpressionId instance.
|
474
|
+
# There is only one such environment in an engine, hence this
|
475
|
+
# 'singleton' method.
|
476
|
+
#
|
395
477
|
def engine_environment_id ()
|
396
478
|
synchronize do
|
397
479
|
return @eei if @eei
|
@@ -411,6 +493,25 @@ module OpenWFE
|
|
411
493
|
|
412
494
|
protected
|
413
495
|
|
496
|
+
def reschedule_a_bit_later
|
497
|
+
Thread.new do
|
498
|
+
#
|
499
|
+
# Just leaving some time for the initialize() to finish
|
500
|
+
# and let the expression pool get registered in
|
501
|
+
# the application context
|
502
|
+
#
|
503
|
+
begin
|
504
|
+
sleep(0.001)
|
505
|
+
reschedule()
|
506
|
+
rescue
|
507
|
+
lwarn do
|
508
|
+
"reschedule() failed\n"+
|
509
|
+
OpenWFE::exception_to_s($!)
|
510
|
+
end
|
511
|
+
end
|
512
|
+
end
|
513
|
+
end
|
514
|
+
|
414
515
|
def evaluate_definition (raw_definition, workitem)
|
415
516
|
expression = raw_definition.instantiate(workitem)
|
416
517
|
end
|
@@ -418,7 +519,7 @@ module OpenWFE
|
|
418
519
|
def remove_environment (environment_id)
|
419
520
|
env, fei = fetch(environment_id)
|
420
521
|
env.unbind()
|
421
|
-
get_expression_storage().
|
522
|
+
get_expression_storage().delete(environment_id)
|
422
523
|
end
|
423
524
|
|
424
525
|
def build_workitem (launchitem)
|
@@ -498,6 +599,7 @@ module OpenWFE
|
|
498
599
|
end
|
499
600
|
|
500
601
|
def new_workflow_instance_id ()
|
602
|
+
|
501
603
|
synchronize do
|
502
604
|
wfid = OpenWFE::current_time_millis()
|
503
605
|
wfid = wfid + 1 if wfid == @@last_given_instance_id
|