openwferu 0.9.2 → 0.9.3

Sign up to get free protection for your applications and to get access to all the features.
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