openwferu 0.9.2 → 0.9.3

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.
Files changed (63) hide show
  1. data/examples/mano_tracker.rb +165 -0
  2. data/examples/scheduler_cron_usage.rb +46 -0
  3. data/examples/scheduler_usage.rb +54 -0
  4. data/lib/openwfe/contextual.rb +7 -1
  5. data/lib/openwfe/engine/engine.rb +58 -15
  6. data/lib/openwfe/expool/expressionpool.rb +116 -14
  7. data/lib/openwfe/expool/expstorage.rb +12 -12
  8. data/lib/openwfe/expool/journalexpstorage.rb +1 -1
  9. data/lib/openwfe/expool/yamlexpstorage.rb +58 -22
  10. data/lib/openwfe/expressions/environment.rb +32 -2
  11. data/lib/openwfe/expressions/expressionmap.rb +17 -0
  12. data/lib/openwfe/expressions/fe_condition.rb +122 -0
  13. data/lib/openwfe/expressions/fe_cursor.rb +14 -5
  14. data/lib/openwfe/expressions/fe_participant.rb +55 -4
  15. data/lib/openwfe/expressions/fe_raw.rb +43 -12
  16. data/lib/openwfe/expressions/fe_subprocess.rb +10 -0
  17. data/lib/openwfe/expressions/fe_time.rb +117 -22
  18. data/lib/openwfe/expressions/fe_value.rb +27 -8
  19. data/lib/openwfe/expressions/flowexpression.rb +13 -6
  20. data/lib/openwfe/expressions/raw_prog.rb +13 -11
  21. data/lib/openwfe/expressions/timeout.rb +94 -0
  22. data/lib/openwfe/flowexpressionid.rb +17 -19
  23. data/lib/openwfe/logging.rb +35 -16
  24. data/lib/openwfe/participants/atomparticipants.rb +31 -7
  25. data/lib/openwfe/participants/enoparticipant.rb +43 -3
  26. data/lib/openwfe/participants/participant.rb +21 -1
  27. data/lib/openwfe/participants/participantmap.rb +4 -2
  28. data/lib/openwfe/participants/participants.rb +12 -17
  29. data/lib/openwfe/participants/soapparticipants.rb +15 -3
  30. data/lib/openwfe/rudefinitions.rb +3 -0
  31. data/lib/openwfe/service.rb +8 -0
  32. data/lib/openwfe/storage/yamlfilestorage.rb +85 -47
  33. data/lib/openwfe/{otime.rb → util/otime.rb} +0 -0
  34. data/lib/openwfe/util/scheduler.rb +415 -231
  35. data/lib/openwfe/util/schedulers.rb +11 -3
  36. data/lib/openwfe/util/stoppable.rb +69 -0
  37. data/lib/openwfe/utils.rb +14 -25
  38. data/lib/openwfe/workitem.rb +12 -6
  39. data/lib/openwfe/worklist/storeparticipant.rb +145 -0
  40. data/test/{atomtest.rb → atom_test.rb} +0 -0
  41. data/test/{crontest.rb → cron_test.rb} +7 -6
  42. data/test/cronline_test.rb +51 -0
  43. data/test/{dollartest.rb → dollar_test.rb} +0 -0
  44. data/test/{feitest.rb → fei_test.rb} +0 -0
  45. data/test/file_persistence_test.rb +15 -9
  46. data/test/flowtestbase.rb +11 -5
  47. data/test/ft_0.rb +8 -0
  48. data/test/ft_10_loop.rb +72 -10
  49. data/test/ft_11_ppd.rb +49 -0
  50. data/test/ft_17_condition.rb +83 -0
  51. data/test/ft_18_pname.rb +59 -0
  52. data/test/hparticipant_test.rb +96 -0
  53. data/test/{misctest.rb → misc_test.rb} +1 -1
  54. data/test/rake_qtest.rb +10 -4
  55. data/test/rake_test.rb +12 -1
  56. data/test/raw_prog_test.rb +1 -1
  57. data/test/restart_cron_test.rb +78 -0
  58. data/test/restart_test.rb +79 -0
  59. data/test/scheduler_test.rb +92 -0
  60. data/test/{timetest.rb → time_test.rb} +3 -38
  61. data/test/timeout_test.rb +73 -0
  62. metadata +26 -11
  63. 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
+
@@ -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
- # use reflection to instanciate the new service,and
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
- init_default_logging('engine.log')
78
+ $OWFE_LOG = Logger.new("engine.log") unless $LOG
75
79
  end
76
80
 
77
81
  #
78
82
  # Launches a [business] process.
79
- # The 'object' param may contain either a LaunchItem instance,
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 (object)
87
+ def launch (launch_object)
84
88
 
85
89
  launchitem = nil
86
90
 
87
- #ldebug { "launch() param is #{object.class}" }
88
-
89
- if object.kind_of? OpenWFE::LaunchItem
90
- launchitem = object
91
- #elsif object.kind_of? REXML::Element
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 object[0] == '<'
97
+ if launch_object[0] == '<'
96
98
  launchitem.workflowDefinitionUrl = "field:__definition"
97
- launchitem['definition'] = object
99
+ launchitem['definition'] = launch_object
98
100
  else
99
- launchitem.workflowDefinitionUrl = object
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 < Service
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 (serviceName, applicationContext)
131
- super(serviceName, applicationContext)
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, template_fei, workitem, params=nil)
177
+ (requesting_expression, template, workitem, params=nil)
178
+
179
+ #ldebug { "launch_template() of class #{template.class}" }
161
180
 
162
- ldebug { "launch() request for #{template_fei.to_debug_s}" }
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, workitem=nil)
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().delete(fei)
386
- get_expression_storage().remove(fei, workitem)
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().remove(environment_id, nil)
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