openwferu 0.9.7 → 0.9.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. data/examples/engine_template.rb +182 -0
  2. data/examples/openwferu.rb +6 -7
  3. data/lib/openwfe/contextual.rb +8 -6
  4. data/lib/openwfe/engine/engine.rb +49 -14
  5. data/lib/openwfe/expool/expressionpool.rb +48 -17
  6. data/lib/openwfe/expool/history.rb +64 -14
  7. data/lib/openwfe/expool/journal.rb +66 -28
  8. data/lib/openwfe/expool/journal_replay.rb +190 -48
  9. data/lib/openwfe/expool/wfidgen.rb +51 -6
  10. data/lib/openwfe/expressions/condition.rb +49 -5
  11. data/lib/openwfe/expressions/environment.rb +9 -37
  12. data/lib/openwfe/expressions/expressionmap.rb +15 -1
  13. data/lib/openwfe/expressions/fe_concurrence.rb +4 -4
  14. data/lib/openwfe/expressions/fe_cron.rb +1 -5
  15. data/lib/openwfe/expressions/fe_do.rb +96 -26
  16. data/lib/openwfe/expressions/fe_equals.rb +190 -0
  17. data/lib/openwfe/expressions/fe_fqv.rb +25 -7
  18. data/lib/openwfe/expressions/fe_if.rb +262 -0
  19. data/lib/openwfe/expressions/fe_iterator.rb +3 -4
  20. data/lib/openwfe/expressions/fe_losfor.rb +0 -1
  21. data/lib/openwfe/expressions/fe_misc.rb +4 -5
  22. data/lib/openwfe/expressions/fe_participant.rb +2 -3
  23. data/lib/openwfe/expressions/fe_raw.rb +71 -31
  24. data/lib/openwfe/expressions/fe_reserve.rb +141 -0
  25. data/lib/openwfe/expressions/fe_sequence.rb +0 -1
  26. data/lib/openwfe/expressions/fe_sleep.rb +3 -58
  27. data/lib/openwfe/expressions/fe_subprocess.rb +6 -5
  28. data/lib/openwfe/expressions/fe_value.rb +20 -121
  29. data/lib/openwfe/expressions/fe_wait.rb +79 -0
  30. data/lib/openwfe/expressions/fe_when.rb +31 -96
  31. data/lib/openwfe/expressions/flowexpression.rb +112 -19
  32. data/lib/openwfe/expressions/raw_prog.rb +8 -116
  33. data/lib/openwfe/expressions/simplerep.rb +197 -0
  34. data/lib/openwfe/expressions/time.rb +266 -0
  35. data/lib/openwfe/expressions/timeout.rb +2 -2
  36. data/lib/openwfe/flowexpressionid.rb +22 -0
  37. data/lib/openwfe/listeners/socketlisteners.rb +15 -1
  38. data/lib/openwfe/participants/participantmap.rb +12 -1
  39. data/lib/openwfe/participants/participants.rb +7 -1
  40. data/lib/openwfe/rudefinitions.rb +1 -6
  41. data/lib/openwfe/service.rb +8 -0
  42. data/lib/openwfe/util/irb.rb +86 -0
  43. data/lib/openwfe/util/ometa.rb +3 -3
  44. data/lib/openwfe/util/safe.rb +26 -34
  45. data/lib/openwfe/util/scheduler.rb +133 -76
  46. data/lib/openwfe/utils.rb +1 -1
  47. data/lib/openwfe/version.rb +2 -2
  48. data/lib/openwfe/workitem.rb +38 -0
  49. data/lib/openwfe/worklist/storeparticipant.rb +27 -2
  50. data/test/console_test.rb +15 -0
  51. data/test/flowtestbase.rb +20 -28
  52. data/test/ft_12_blockparticipant.rb +24 -0
  53. data/test/ft_14b_subprocess.rb +18 -0
  54. data/test/ft_22_history.rb +22 -1
  55. data/test/ft_23_when.rb +29 -2
  56. data/test/ft_23b_when.rb +17 -0
  57. data/test/ft_23c_wait.rb +87 -0
  58. data/test/ft_2_concurrence.rb +15 -14
  59. data/test/ft_2b_concurrence.rb +4 -4
  60. data/test/ft_32_journal.rb +29 -6
  61. data/test/ft_32b_journal.rb +76 -0
  62. data/test/ft_36_subprocids.rb +96 -0
  63. data/test/ft_37_pnames.rb +55 -0
  64. data/test/ft_38_tag.rb +128 -0
  65. data/test/ft_39_reserve.rb +119 -0
  66. data/test/ft_3_equals.rb +20 -1
  67. data/test/ft_40_defined.rb +72 -0
  68. data/test/ft_41_case.rb +124 -0
  69. data/test/ft_4_misc.rb +17 -0
  70. data/test/ft_5_time.rb +15 -20
  71. data/test/ft_7_lose.rb +2 -3
  72. data/test/ft_8_forget.rb +1 -1
  73. data/test/ft_tests.rb +9 -0
  74. data/test/hparticipant_test.rb +47 -1
  75. data/test/nut_0_irb.rb +20 -0
  76. data/test/raw_prog_test.rb +6 -0
  77. data/test/safely_test.rb +31 -41
  78. data/test/wfid_test.rb +43 -0
  79. metadata +21 -4
  80. data/lib/openwfe/expressions/fe_utils.rb +0 -151
@@ -0,0 +1,182 @@
1
+
2
+ require 'rubygems'
3
+ #
4
+ # if OpenWFEru was installed via 'gem'
5
+
6
+ #
7
+ # setting up an OpenWFEru engine, step by step
8
+
9
+ require 'openwfe/engine/engine'
10
+ require 'openwfe/engine/file_persisted_engine'
11
+ require 'openwfe/expool/history'
12
+ require 'openwfe/expool/journal'
13
+ require 'openwfe/listeners/listeners'
14
+ require 'openwfe/participants/participants'
15
+
16
+
17
+ #
18
+ # === the ENGINE itself
19
+ #
20
+
21
+ #application_context = {}
22
+ #application_context[:work_directory] = "work"
23
+ #
24
+ # OpenWFEru engines take one optional argument : application_context
25
+ #
26
+ # the following engine constructions do not use this argument,
27
+ # but you can make them use it
28
+ #
29
+ # engine = OpenWFE::Engine.new(application_context)
30
+ #
31
+ # ...
32
+ #
33
+
34
+
35
+ #engine = OpenWFE::Engine.new
36
+ #
37
+ # an in-memory, totally transient engine
38
+ #
39
+ # might be ideal for an embedded workflow engine with short lived
40
+ # process definitions to run
41
+
42
+ #engine = OpenWFE::FilePersistedEngine.new
43
+ #
44
+ # a file persisted engine, slow, used only within unit tests
45
+ # do not use
46
+
47
+ engine = OpenWFE::CachedFilePersistedEngine.new
48
+ #
49
+ # a file persisted engine, with an in-memory cache.
50
+ # use that
51
+ #
52
+ # persistence is done by default under ./work/
53
+
54
+ # -- a console
55
+
56
+ #engine.enable_irb_console
57
+ #
58
+ # by enabling the IRB console, you can jump into the engine object
59
+ # with a CTRL-C hit on the terminal that runs hit.
60
+ #
61
+ # Hit CTRL-D to get out of the IRB console.
62
+
63
+ # -- process history
64
+
65
+ #engine.init_service("history", InMemoryHistory)
66
+ #
67
+ # keeps all process history in an arry in memory
68
+ # use only for test purposes !
69
+
70
+ #engine.init_service("history", FileHistory)
71
+ #
72
+ # dumps all the process history in a file name "history.log"
73
+ # in the work directory
74
+
75
+ # -- process journaling
76
+
77
+ #engine.init_service("journal", Journal)
78
+ #
79
+ # activates 'journaling',
80
+ #
81
+ # see http://openwferu.rubyforge.org/journal.html
82
+ #
83
+ #engine.application_context[:keep_journals] = true
84
+ #
85
+ # if set to true, the journal of terminated processes will be kept
86
+ # (but moved by default to ./work/journal/done/)
87
+
88
+
89
+ #
90
+ # === some LISTENERS
91
+ #
92
+ # listeners 'receive' incoming workitems (InFlowWorkItem coming back from
93
+ # participants or LaunchItem requesting the launch of a particular flow)
94
+ #
95
+
96
+ #sl = OpenWFE::SocketListener.new(
97
+ # "socket_listener", @engine.application_context, 7008)
98
+ #engine.add_workitem_listener(sl)
99
+ #
100
+ # adding a simple SocketListener on port 7008
101
+
102
+ #require 'openwfe/listeners/socketlisteners'
103
+ #
104
+ #engine.add_workitem_listener(OpenWFE::SocketListener)
105
+ #
106
+ # adding a SocketListener on the default port 7007
107
+
108
+ #engine.add_workitem_listener(OpenWFE::FileListener, "500")
109
+ #
110
+ # listening for workitems (coming as within YAML files dropped in the
111
+ # default ./work/in directory)
112
+ #
113
+ # check for new files every 500 ms
114
+
115
+ #require 'openwfe/listeners/sqslisteners'
116
+ #
117
+ #engine.add_workitem_listener(
118
+ # OpenWFE::SqsListener.new(:wiqueue, engine.application_context),
119
+ # "2s")
120
+ #
121
+ # adds a listener polling an Amazon Simple Queue Service (SQS)
122
+ # named 'wiqueue' every 2 seconds
123
+ #
124
+ # http://jmettraux.wordpress.com/2007/03/13/openwferu-over-amazon-sqs/
125
+ # http://aws.amazon.com/sqs
126
+
127
+
128
+ #
129
+ # === the PARTICIPANTS
130
+ #
131
+ # to learn more about participants :
132
+ # http://openwferu.rubyforge.org/participants.html
133
+ #
134
+
135
+ # you can use indifferently symbols or strings for participant names
136
+
137
+ # It's perhaps better to separate the participant registration and put
138
+ # it in its own .rb file, but anyway, here are some participant registration
139
+ # examples :
140
+
141
+ engine.register_participant(:toto) do |workitem|
142
+ puts "toto received a workitem..."
143
+ puts "lots of work..." if workitem.attributes.size > 3
144
+ sleep 4
145
+ puts "done."
146
+ end
147
+ #
148
+ # an example of a "block participant", binding Ruby code to a
149
+ # participant in a business process
150
+
151
+ #require 'openwfe/participants/sqsparticipants'
152
+ #
153
+ #engine.register_participant(:sqs, OpenWFE::SqsParticipant.new(:wiqueue2))
154
+ #
155
+ # registers a participant named 'sqs', workitems for it will get placed
156
+ # on the SQS queue named "wiqueue2"
157
+
158
+ #require 'openwfe/participants/socketparticipants'
159
+ #
160
+ #engine.register_participant(
161
+ # "away", OpenWFE::SocketParticipant.new("target.host.co.jp", 7009))
162
+ #
163
+ # the participant "away" listens for workitems on port 7009 of
164
+ # host 'target.host.co.jp', our SocketParticipant will dispatch
165
+ # the workitem to it over TCP
166
+
167
+
168
+ #
169
+ # === joining the engine's scheduler thread
170
+ #
171
+ # (preventing the Ruby interpreting from prematurely (immediately) exiting)
172
+ #
173
+
174
+ engine.join
175
+ #
176
+ # you don't need to 'join' if the engine uses a listener, the thread of
177
+ # the listener will prevent the Ruby interpreter from exiting.
178
+ #
179
+ # hit CTRL-C to quit (or maybe engine.enable_irb_console has been called,
180
+ # in which case CTRL-C will bring you into a IRB console within the
181
+ # engine itself).
182
+
@@ -36,14 +36,12 @@ end
36
36
  # a process definition
37
37
 
38
38
  class TheProcessDefinition0 < OpenWFE::ProcessDefinition
39
- def make
40
- sequence do
41
- concurrence do
42
- participant :alice
43
- participant :bob
44
- end
45
- participant :summarize
39
+ sequence do
40
+ concurrence do
41
+ participant :alice
42
+ participant :bob
46
43
  end
44
+ participant :summarize
47
45
  end
48
46
  end
49
47
 
@@ -55,3 +53,4 @@ li = OpenWFE::LaunchItem.new(TheProcessDefinition0)
55
53
  li.initial_comment = "please give your impressions about http://ruby-lang.org"
56
54
 
57
55
  engine.launch(li)
56
+
@@ -58,13 +58,15 @@ module OpenWFE
58
58
  # class is returned.
59
59
  #
60
60
  def lookup (key)
61
+
61
62
  if key.kind_of? Class
62
63
  @application_context.each do |k, value|
63
64
  return value if value.class == key
64
65
  end
65
66
  return nil
66
67
  end
67
- return @application_context[key]
68
+
69
+ @application_context[key]
68
70
  end
69
71
 
70
72
  #
@@ -77,12 +79,12 @@ module OpenWFE
77
79
 
78
80
  s = service_class.new(service_name, @application_context)
79
81
 
80
- s.service_name = "#{service_class.name}::#{s.object_id}" \
81
- unless service_name
82
-
83
- @application_context[s.service_name.to_s] = s
82
+ unless service_name
83
+ s.service_name = "#{service_class.name}::#{s.object_id}"
84
+ @application_context[s.service_name.to_s] = s
85
+ end
84
86
 
85
- return s
87
+ s
86
88
  end
87
89
 
88
90
  end
@@ -45,6 +45,7 @@ require 'logger'
45
45
  require 'openwfe/workitem'
46
46
  require 'openwfe/rudefinitions'
47
47
  require 'openwfe/service'
48
+ require 'openwfe/util/irb'
48
49
  require 'openwfe/util/scheduler'
49
50
  require 'openwfe/util/schedulers'
50
51
  require 'openwfe/expool/wfidgen'
@@ -66,11 +67,12 @@ module OpenWFE
66
67
  #
67
68
  # Builds an OpenWFEru engine.
68
69
  #
69
- def initialize ()
70
-
71
- super(S_ENGINE, {})
70
+ # Accepts an optional initial application_context (containing
71
+ # initialization params for services for example).
72
+ #
73
+ def initialize (application_context={})
72
74
 
73
- @application_context[@service_name] = self
75
+ super(S_ENGINE, application_context)
74
76
 
75
77
  $OWFE_LOG = Logger.new("engine.log") unless $OWFE_LOG
76
78
 
@@ -237,7 +239,7 @@ module OpenWFE
237
239
 
238
240
  if listener.kind_of? Class
239
241
 
240
- listener = init_service(nil, listener)
242
+ listener = init_service nil, listener
241
243
 
242
244
  name = listener.service_name
243
245
  else
@@ -285,6 +287,30 @@ module OpenWFE
285
287
  get_scheduler.join
286
288
  end
287
289
 
290
+ #
291
+ # Enabling the console means that hitting CTRL-C on the window /
292
+ # term / dos box / whatever does run the OpenWFEru engine will
293
+ # open an IRB interactive console for directly manipulating the
294
+ # engine instance.
295
+ #
296
+ # Hit CTRL-D to get out of the console.
297
+ #
298
+ def enable_irb_console
299
+
300
+ OpenWFE::trap_int_irb(binding)
301
+ end
302
+
303
+ #
304
+ # Makes sure that hitting CTRL-C will actually kill the engine VM and
305
+ # not open an IRB console.
306
+ #
307
+ #def disable_irb_console
308
+ # $openwfe_irb = nil
309
+ # trap 'INT' do
310
+ # exit 0
311
+ # end
312
+ #end
313
+
288
314
  #
289
315
  # Stopping the engine will stop all the services in the
290
316
  # application context.
@@ -307,6 +333,8 @@ module OpenWFE
307
333
  end
308
334
  end
309
335
  end
336
+
337
+ nil
310
338
  end
311
339
 
312
340
  #
@@ -377,7 +405,7 @@ module OpenWFE
377
405
  # see for example file_persisted_engine.rb
378
406
  #
379
407
 
380
- def build_expression_map ()
408
+ def build_expression_map
381
409
 
382
410
  @application_context[S_EXPRESSION_MAP] = ExpressionMap.new
383
411
  #
@@ -391,29 +419,36 @@ module OpenWFE
391
419
  #end
392
420
  end
393
421
 
394
- def build_wfid_generator ()
422
+ def build_wfid_generator
423
+
424
+ #init_service S_WFID_GENERATOR, DefaultWfidGenerator
425
+ #init_service S_WFID_GENERATOR, UuidWfidGenerator
426
+ init_service S_WFID_GENERATOR, KotobaWfidGenerator
395
427
 
396
- #init_service(S_WFID_GENERATOR, DefaultWfidGenerator)
397
- #init_service(S_WFID_GENERATOR, UuidWfidGenerator)
398
- init_service(S_WFID_GENERATOR, KotobaWfidGenerator)
428
+ #g = FieldWfidGenerator.new(
429
+ # S_WFID_GENERATOR, @application_context, "wfid")
430
+ #
431
+ # showing how to initialize a FieldWfidGenerator that
432
+ # will take as workflow instance id the value found in
433
+ # the field "wfid" of the LaunchItem.
399
434
  end
400
435
 
401
- def build_expression_pool ()
436
+ def build_expression_pool
402
437
 
403
438
  init_service(S_EXPRESSION_POOL, ExpressionPool)
404
439
  end
405
440
 
406
- def build_expression_storage ()
441
+ def build_expression_storage
407
442
 
408
443
  init_service(S_EXPRESSION_STORAGE, InMemoryExpressionStorage)
409
444
  end
410
445
 
411
- def build_participant_map ()
446
+ def build_participant_map
412
447
 
413
448
  init_service(S_PARTICIPANT_MAP, ParticipantMap)
414
449
  end
415
450
 
416
- def build_scheduler ()
451
+ def build_scheduler
417
452
 
418
453
  init_service(S_SCHEDULER, SchedulerService)
419
454
  end
@@ -55,6 +55,7 @@ require 'openwfe/util/observable'
55
55
  require 'openwfe/expressions/environment'
56
56
  require 'openwfe/expressions/raw_xml'
57
57
  require 'openwfe/expressions/raw_prog'
58
+ require 'openwfe/expressions/simplerep'
58
59
 
59
60
  include OpenWFE
60
61
 
@@ -190,7 +191,7 @@ module OpenWFE
190
191
  raise "didn't find process definition at '#{wfdurl}'" \
191
192
  unless definition
192
193
 
193
- raw_expression = build_raw_expression(wfdurl, definition)
194
+ raw_expression = build_raw_expression(launchitem, definition)
194
195
 
195
196
  raw_expression.check_parameters(launchitem)
196
197
  #
@@ -255,7 +256,7 @@ module OpenWFE
255
256
  elsif template.is_a? FlowExpressionId
256
257
  fetch_expression(template)
257
258
  else
258
- build_raw_expression("no-url", template)
259
+ build_raw_expression(nil, template)
259
260
  end
260
261
 
261
262
  #raise "did not find expression at #{template.to_s}" \
@@ -387,7 +388,7 @@ module OpenWFE
387
388
  inflowitem = exp.cancel()
388
389
  remove(exp)
389
390
 
390
- return inflowitem
391
+ inflowitem
391
392
  end
392
393
 
393
394
  #
@@ -422,7 +423,7 @@ module OpenWFE
422
423
  #
423
424
  # Replies to the parent of the given expression.
424
425
  #
425
- def reply_to_parent (exp, workitem)
426
+ def reply_to_parent (exp, workitem, remove=true)
426
427
 
427
428
  ldebug { "reply_to_parent() for #{exp.fei.to_debug_s}" }
428
429
 
@@ -430,12 +431,27 @@ module OpenWFE
430
431
 
431
432
  onotify :reply_to_parent, exp.fei, workitem
432
433
 
433
- remove(exp)
434
+ if remove
435
+
436
+ remove(exp)
437
+ #
438
+ # remove the expression itself
439
+
440
+ exp.clean_children()
441
+ #
442
+ # remove all the children of the expression
443
+ end
434
444
 
435
445
  #
436
- # remove all the children of the expression
446
+ # manage tag, have to remove it so it can get 'redone' or 'undone'
447
+ # (preventing abuse)
448
+
449
+ tagname = exp.attributes["tag"] if exp.attributes
437
450
 
438
- exp.clean_children()
451
+ exp.delete_variable(tagname) if tagname
452
+
453
+ #
454
+ # flow terminated ?
439
455
 
440
456
  if not exp.parent_id
441
457
  ldebug do
@@ -448,6 +464,9 @@ module OpenWFE
448
464
  return
449
465
  end
450
466
 
467
+ #
468
+ # else, gone parent ?
469
+
451
470
  if exp.parent_id == GONE_PARENT_ID
452
471
  ldebug do
453
472
  "reply_to_parent() parent is gone for " +
@@ -457,6 +476,9 @@ module OpenWFE
457
476
  return
458
477
  end
459
478
 
479
+ #
480
+ # parent still present, reply to it
481
+
460
482
  reply(exp.parent_id, workitem)
461
483
  end
462
484
 
@@ -492,7 +514,10 @@ module OpenWFE
492
514
 
493
515
  onotify :update, flow_expression.fei, flow_expression
494
516
 
495
- ldebug { "update() took #{t.duration} ms" }
517
+ ldebug do
518
+ "update() took #{t.duration} ms " +
519
+ "#{flow_expression.fei.to_debug_s}"
520
+ end
496
521
 
497
522
  flow_expression
498
523
  end
@@ -519,7 +544,7 @@ module OpenWFE
519
544
  "'#{fei}' (#{fei.class})"
520
545
  end
521
546
 
522
- ldebug { "fetch() for #{fei.to_debug_s}" }
547
+ #ldebug { "fetch() for #{fei.to_debug_s}" }
523
548
 
524
549
  return get_expression_storage()[fei], fei
525
550
  end
@@ -790,7 +815,7 @@ module OpenWFE
790
815
  # "param of class #{param.class.name}"
791
816
  #end
792
817
 
793
- return param if param.is_a? ProgExpRepresentation
818
+ return param if param.is_a? SimpleExpRepresentation
794
819
  return param.make if param.is_a? ProcessDefinition
795
820
  return param.do_make if param.is_a? Class
796
821
 
@@ -829,17 +854,23 @@ module OpenWFE
829
854
  # Builds a FlowExpressionId instance for process being
830
855
  # launched.
831
856
  #
832
- def new_fei (flow_url, flow_name, flow_revision, exp_name)
857
+ def new_fei (launchitem, flow_name, flow_revision, exp_name)
858
+
859
+ url = if launchitem
860
+ launchitem.workflow_definition_url
861
+ else
862
+ "no-url"
863
+ end
833
864
 
834
865
  fei = FlowExpressionId.new
835
866
 
836
867
  fei.owfe_version = OPENWFERU_VERSION
837
868
  fei.engine_id = OpenWFE::stu get_engine.service_name
838
869
  fei.initial_engine_id = OpenWFE::stu fei.engine_id
839
- fei.workflow_definition_url = OpenWFE::stu flow_url
870
+ fei.workflow_definition_url = OpenWFE::stu url
840
871
  fei.workflow_definition_name = OpenWFE::stu flow_name
841
872
  fei.workflow_definition_revision = OpenWFE::stu flow_revision
842
- fei.workflow_instance_id = get_wfid_generator.generate
873
+ fei.wfid = get_wfid_generator.generate launchitem
843
874
  fei.expression_id = "0"
844
875
  fei.expression_name = exp_name
845
876
  return fei
@@ -849,10 +880,10 @@ module OpenWFE
849
880
  # Builds the RawExpression instance at the root of the flow
850
881
  # being launched.
851
882
  #
852
- # The param can be a LaunchItem, an URI, anything accepted
853
- # by the determine_representation() method.
883
+ # The param can be a template or a definition (anything
884
+ # accepted by the determine_representation() method).
854
885
  #
855
- def build_raw_expression (url, param)
886
+ def build_raw_expression (launchitem, param)
856
887
 
857
888
  procdef = determine_representation(param)
858
889
 
@@ -862,7 +893,7 @@ module OpenWFE
862
893
  flow_revision = procdef.attributes['revision']
863
894
  exp_name = procdef.name
864
895
 
865
- fei = new_fei(url, flow_name, flow_revision, exp_name)
896
+ fei = new_fei(launchitem, flow_name, flow_revision, exp_name)
866
897
 
867
898
  #puts procdef.raw_expression_class
868
899
  #puts procdef.raw_expression_class.public_methods
@@ -48,7 +48,7 @@ require 'openwfe/rudefinitions'
48
48
  module OpenWFE
49
49
 
50
50
  #
51
- # The base implementation for History modules
51
+ # A Mixin for history modules
52
52
  #
53
53
  module HistoryMixin
54
54
  include ServiceMixin, OwfeServiceLocator
@@ -69,14 +69,9 @@ module OpenWFE
69
69
  end
70
70
 
71
71
  #
72
- # The simplest implementation, stores all history entries in memory.
73
- #
74
- # DO NOT USE IN PRODUCTION, it will trigger an 'out of memory' error
75
- # sooner or later.
76
- #
77
- # Is only used for unit testing purposes.
72
+ # A base implementation for InMemoryHistory and FileHistory.
78
73
  #
79
- class InMemoryHistory
74
+ class BaseHistory
80
75
  include HistoryMixin
81
76
 
82
77
  attr_reader :entries
@@ -85,15 +80,14 @@ module OpenWFE
85
80
 
86
81
  super()
87
82
 
88
- @entries = []
89
-
90
83
  service_init(service_name, application_context)
91
84
  end
92
85
 
93
86
  def log (event, *args)
94
87
 
95
- return if event == :stop
88
+ return if event == :update
96
89
  return if event == :reschedule
90
+ return if event == :stop
97
91
 
98
92
  msg = "#{Time.now.to_s} -- "
99
93
 
@@ -105,18 +99,74 @@ module OpenWFE
105
99
  #msg << " #{args[1].to_s}" \
106
100
  # if args.length > 1
107
101
 
108
- @entries << msg
102
+ @output << msg + "\n"
109
103
  end
104
+ end
110
105
 
106
+ #
107
+ # The simplest implementation, stores all history entries in memory.
108
+ #
109
+ # DO NOT USE IN PRODUCTION, it will trigger an 'out of memory' error
110
+ # sooner or later.
111
+ #
112
+ # Is only used for unit testing purposes.
113
+ #
114
+ class InMemoryHistory < BaseHistory
115
+
116
+ def initialize (service_name, application_context)
117
+ super
118
+
119
+ @output = []
120
+ end
121
+
122
+ #
123
+ # Returns the array of entries.
124
+ #
125
+ def entries
126
+ @output
127
+ end
128
+
129
+ #
130
+ # Returns all the entries as a String.
131
+ #
111
132
  def to_s
112
133
  s = ""
113
- @entries.each do |entry|
134
+ @output.each do |entry|
114
135
  s << entry.to_s
115
- s << "\n"
116
136
  end
117
137
  s
118
138
  end
119
139
  end
120
140
 
141
+ #
142
+ # Simply dumps the history in the work directory in a file named
143
+ # "history.log"
144
+ # Warning : no fancy rotation or compression implemented here.
145
+ #
146
+ class FileHistory < BaseHistory
147
+
148
+ def initialize (service_name, application_context)
149
+
150
+ super
151
+
152
+ @output = OpenWFE::get_work_directory + "/history.log"
153
+ @output = File.open(@output, "w+")
154
+
155
+ linfo { "new() outputting history to #{@output.path}" }
156
+ end
157
+
158
+ #
159
+ # Returns a handle on the output file instance used by this
160
+ # FileHistory.
161
+ #
162
+ def output_file
163
+ @output
164
+ end
165
+
166
+ def stop
167
+ @output.close
168
+ end
169
+ end
170
+
121
171
  end
122
172