openwferu 0.9.15 → 0.9.16

Sign up to get free protection for your applications and to get access to all the features.
Files changed (149) hide show
  1. data/README.txt +4 -2
  2. data/lib/openwfe/engine/engine.rb +143 -25
  3. data/lib/openwfe/engine/file_persisted_engine.rb +3 -3
  4. data/lib/openwfe/expool/errorjournal.rb +48 -25
  5. data/lib/openwfe/expool/expressionpool.rb +77 -106
  6. data/lib/openwfe/expool/expstorage.rb +6 -5
  7. data/lib/openwfe/expool/threadedexpstorage.rb +190 -0
  8. data/lib/openwfe/expool/yamlexpstorage.rb +5 -150
  9. data/lib/openwfe/expressions/condition.rb +6 -6
  10. data/lib/openwfe/expressions/environment.rb +7 -2
  11. data/lib/openwfe/expressions/expressionmap.rb +14 -0
  12. data/lib/openwfe/expressions/fe_command.rb +2 -1
  13. data/lib/openwfe/expressions/fe_concurrence.rb +40 -18
  14. data/lib/openwfe/expressions/fe_cron.rb +14 -11
  15. data/lib/openwfe/expressions/fe_cursor.rb +2 -3
  16. data/lib/openwfe/expressions/fe_define.rb +34 -31
  17. data/lib/openwfe/expressions/fe_equals.rb +11 -21
  18. data/lib/openwfe/expressions/fe_filter_definition.rb +0 -2
  19. data/lib/openwfe/expressions/fe_fqv.rb +1 -3
  20. data/lib/openwfe/expressions/fe_if.rb +37 -12
  21. data/lib/openwfe/expressions/fe_iterator.rb +1 -1
  22. data/lib/openwfe/expressions/fe_listen.rb +147 -28
  23. data/lib/openwfe/expressions/fe_losfor.rb +13 -1
  24. data/lib/openwfe/expressions/fe_misc.rb +70 -11
  25. data/lib/openwfe/expressions/fe_participant.rb +3 -3
  26. data/lib/openwfe/expressions/fe_reserve.rb +1 -1
  27. data/lib/openwfe/expressions/fe_save.rb +11 -12
  28. data/lib/openwfe/expressions/fe_sequence.rb +22 -29
  29. data/lib/openwfe/expressions/fe_sleep.rb +11 -7
  30. data/lib/openwfe/expressions/fe_subprocess.rb +24 -10
  31. data/lib/openwfe/expressions/fe_value.rb +35 -15
  32. data/lib/openwfe/expressions/fe_when.rb +2 -4
  33. data/lib/openwfe/expressions/flowexpression.rb +73 -37
  34. data/lib/openwfe/expressions/merge.rb +2 -4
  35. data/lib/openwfe/expressions/raw.rb +40 -31
  36. data/lib/openwfe/expressions/raw_prog.rb +18 -9
  37. data/lib/openwfe/expressions/raw_xml.rb +1 -8
  38. data/lib/openwfe/expressions/simplerep.rb +27 -5
  39. data/lib/openwfe/expressions/time.rb +45 -15
  40. data/lib/openwfe/expressions/timeout.rb +2 -1
  41. data/lib/openwfe/expressions/wtemplate.rb +2 -2
  42. data/lib/openwfe/flowexpressionid.rb +62 -16
  43. data/lib/openwfe/listeners/listener.rb +28 -37
  44. data/lib/openwfe/listeners/listeners.rb +1 -1
  45. data/lib/openwfe/listeners/socketlisteners.rb +7 -15
  46. data/lib/openwfe/logging.rb +5 -4
  47. data/lib/openwfe/{rest → orest}/controlclient.rb +3 -5
  48. data/lib/openwfe/{rest → orest}/definitions.rb +0 -2
  49. data/lib/openwfe/{rest → orest}/exception.rb +0 -0
  50. data/lib/openwfe/{rest → orest}/oldrestservlet.rb +1 -1
  51. data/lib/openwfe/{rest → orest}/osocket.rb +1 -1
  52. data/lib/openwfe/{rest → orest}/restclient.rb +0 -2
  53. data/lib/openwfe/orest/workitem.rb +206 -0
  54. data/lib/openwfe/{rest → orest}/worklistclient.rb +15 -5
  55. data/lib/openwfe/{rest → orest}/xmlcodec.rb +4 -1
  56. data/lib/openwfe/participants/enoparticipants.rb +4 -14
  57. data/lib/openwfe/participants/participantmap.rb +16 -12
  58. data/lib/openwfe/participants/participants.rb +46 -1
  59. data/lib/openwfe/participants/socketparticipants.rb +1 -6
  60. data/lib/openwfe/service.rb +15 -6
  61. data/lib/openwfe/storage/yamlcustom.rb +3 -0
  62. data/lib/openwfe/storage/yamlfilestorage.rb +3 -1
  63. data/lib/openwfe/util/dollar.rb +21 -14
  64. data/lib/openwfe/util/lru.rb +29 -10
  65. data/lib/openwfe/util/observable.rb +4 -1
  66. data/lib/openwfe/util/otime.rb +3 -0
  67. data/lib/openwfe/util/scheduler.rb +346 -114
  68. data/lib/openwfe/utils.rb +67 -13
  69. data/lib/openwfe/version.rb +1 -1
  70. data/lib/openwfe/workitem.rb +22 -165
  71. data/lib/openwfe/worklist/oldrest.rb +2 -2
  72. data/test/bm/bm_1_xml_vs_prog.rb +56 -0
  73. data/test/{ft_26_load.rb → bm/ft_26_load.rb} +0 -0
  74. data/test/{ft_26b_load.rb → bm/ft_26b_load.rb} +0 -0
  75. data/test/{ft_26c_load.rb → bm/ft_26c_load.rb} +16 -4
  76. data/test/clone_test.rb +62 -0
  77. data/test/cron_test.rb +56 -1
  78. data/test/cronline_test.rb +17 -8
  79. data/test/description_test.rb +57 -0
  80. data/test/dollar_test.rb +17 -6
  81. data/test/eno_test.rb +22 -9
  82. data/test/fe_lookup_att_test.rb +50 -0
  83. data/test/fei_test.rb +18 -9
  84. data/test/flowtestbase.rb +24 -2
  85. data/test/ft_0.rb +10 -12
  86. data/test/ft_0e_multibody.rb +34 -0
  87. data/test/ft_10_loop.rb +4 -6
  88. data/test/ft_11_ppd.rb +5 -20
  89. data/test/ft_14b_subprocess.rb +2 -2
  90. data/test/ft_15_iterator.rb +56 -4
  91. data/test/ft_15b_iterator.rb +48 -0
  92. data/test/ft_16_fqv.rb +18 -3
  93. data/test/ft_23c_wait.rb +7 -5
  94. data/test/ft_25_cancel.rb +5 -3
  95. data/test/ft_27_getflowpos.rb +14 -11
  96. data/test/ft_28_fileparticipant.rb +3 -4
  97. data/test/ft_2_concurrence.rb +8 -12
  98. data/test/ft_2b_concurrence.rb +3 -2
  99. data/test/ft_30_socketlistener.rb +5 -6
  100. data/test/ft_32c_journal.rb +2 -2
  101. data/test/ft_32d_journal.rb +5 -6
  102. data/test/ft_33_description.rb +8 -3
  103. data/test/ft_34_cancelwfid.rb +3 -3
  104. data/test/ft_38_tag.rb +7 -10
  105. data/test/ft_39_reserve.rb +4 -2
  106. data/test/ft_3_equals.rb +18 -13
  107. data/test/ft_44b_restore.rb +2 -6
  108. data/test/ft_49_condition.rb +16 -12
  109. data/test/ft_4_misc.rb +51 -12
  110. data/test/ft_50_xml_attribute.rb +1 -1
  111. data/test/ft_54_listen.rb +96 -10
  112. data/test/ft_54b_listen.rb +68 -0
  113. data/test/ft_55_ptimeout.rb +1 -2
  114. data/test/ft_58_ejournal.rb +8 -33
  115. data/test/ft_59_ps.rb +2 -3
  116. data/test/ft_59b_ps_for_pat.rb +59 -0
  117. data/test/ft_5_time.rb +45 -4
  118. data/test/ft_60_ecancel.rb +7 -7
  119. data/test/ft_61_elsub.rb +1 -1
  120. data/test/ft_64_alias.rb +1 -1
  121. data/test/ft_67_schedlaunch.rb +29 -16
  122. data/test/ft_69_cancelmissing.rb +1 -1
  123. data/test/ft_6_lambda.rb +8 -6
  124. data/test/ft_70_lookupvar.rb +2 -2
  125. data/test/ft_71_log.rb +60 -0
  126. data/test/ft_72_lookup_processes.rb +79 -0
  127. data/test/ft_73_cancel_sub.rb +144 -0
  128. data/test/ft_74_block_and_workitem_dup.rb +63 -0
  129. data/test/ft_75_ruby_attributes.rb +87 -0
  130. data/test/ft_76_merge_isolate.rb +90 -0
  131. data/test/ft_7_lose.rb +2 -1
  132. data/test/ft_tests.rb +9 -0
  133. data/test/lookup_att_test.rb +90 -0
  134. data/test/misc_test.rb +33 -50
  135. data/test/orest_test.rb +1 -1
  136. data/test/participant_test.rb +32 -8
  137. data/test/pending.rb +6 -7
  138. data/test/rake_ltest.rb +3 -0
  139. data/test/rake_qtest.rb +4 -1
  140. data/test/raw_prog_test.rb +1 -1
  141. data/test/restart_cron_test.rb +6 -6
  142. data/test/restart_sleep_test.rb +8 -8
  143. data/test/ruby_procdef_test.rb +2 -2
  144. data/test/rutest_utils.rb +9 -3
  145. data/test/scheduler_1_test.rb +88 -0
  146. data/test/scheduler_test.rb +49 -4
  147. data/test/sec_test.rb +18 -11
  148. metadata +51 -34
  149. data/test/cron_test_2.rb +0 -50
@@ -190,7 +190,7 @@ module OpenWFE
190
190
  # Returns the FlowExpressionId instance of the root expression of
191
191
  # the newly launched flow.
192
192
  #
193
- def launch (launchitem, options)
193
+ def launch (launchitem, options={})
194
194
 
195
195
  #
196
196
  # prepare raw expression
@@ -207,7 +207,7 @@ module OpenWFE
207
207
  # the process instance
208
208
 
209
209
  raw_expression = wrap_in_schedule(raw_expression, options) \
210
- if options and options.size > 0
210
+ if options.size > 0
211
211
 
212
212
  fei = raw_expression.fei
213
213
 
@@ -234,18 +234,24 @@ module OpenWFE
234
234
  requesting_expression, sub_id, template, params=nil)
235
235
 
236
236
  rawexp = if template.is_a?(RawExpression)
237
+
238
+ template.application_context = @application_context
237
239
  template
240
+
238
241
  elsif template.is_a?(FlowExpressionId)
239
- fetch_expression(template)
242
+
243
+ fetch_expression template
244
+
240
245
  else
241
- build_raw_expression(nil, template)
246
+
247
+ build_raw_expression nil, template
242
248
  end
243
249
 
244
250
  #raise "did not find subprocess in : #{template.to_s}" \
245
251
  # unless rawexp
246
252
 
247
- rawexp = rawexp.dup()
248
- rawexp.fei = rawexp.fei.dup()
253
+ rawexp = rawexp.dup
254
+ rawexp.fei = rawexp.fei.dup
249
255
 
250
256
  if requesting_expression == nil
251
257
 
@@ -276,11 +282,11 @@ module OpenWFE
276
282
  # "#{rawexp.fei.workflow_instance_id.to_s}"
277
283
  #end
278
284
 
279
- env = rawexp.new_environment(params)
285
+ env = rawexp.new_environment params
280
286
  #
281
287
  # the new scope gets its own environment
282
288
 
283
- rawexp.store_itself()
289
+ rawexp.store_itself
284
290
 
285
291
  rawexp
286
292
  end
@@ -303,22 +309,22 @@ module OpenWFE
303
309
  rawexp.fei
304
310
  end
305
311
 
306
- #
312
+ #--
307
313
  # Evaluates a raw definition expression and
308
314
  # returns its body fei
309
315
  #
310
- def evaluate (rawExpression, workitem)
311
-
312
- exp = rawExpression.instantiate_real_expression workitem
313
- fei = exp.evaluate workitem
314
-
315
- #remove(rawExpression)
316
- #
317
- # not necessary, the raw expression gets overriden by
318
- # the real expression
319
-
320
- fei
321
- end
316
+ #def evaluate (rawExpression, workitem)
317
+ # #rawExpression = fetch_expression(rawExpression) \
318
+ # # if rawExpression.is_a?(FlowExpressionId)
319
+ # exp = rawExpression.instantiate_real_expression workitem
320
+ # fei = exp.evaluate workitem
321
+ # #remove(rawExpression)
322
+ # #
323
+ # # not necessary, the raw expression gets overriden by
324
+ # # the real expression
325
+ # fei
326
+ #end
327
+ #++
322
328
 
323
329
  #
324
330
  # Applies a given expression (id or expression)
@@ -370,9 +376,9 @@ module OpenWFE
370
376
  #
371
377
  def cancel_expression (exp)
372
378
 
373
- exp = fetch_expression(exp)
379
+ exp = fetch_expression exp
374
380
 
375
- wi = cancel(exp)
381
+ wi = cancel exp
376
382
 
377
383
  if wi
378
384
  reply_to_parent(exp, wi, false)
@@ -418,58 +424,6 @@ module OpenWFE
418
424
  ldebug { "forget() forgot #{fei}" }
419
425
  end
420
426
 
421
- #
422
- # Pauses a process (sets its '/__paused__' variable to true).
423
- #
424
- def pause_process (wfid)
425
-
426
- wfid = extract_wfid(wfid)
427
-
428
- root_expression = fetch_root(wfid)
429
-
430
- root_expression.set_variable(VAR_PAUSED, true)
431
- end
432
-
433
- #
434
- # Restarts a process : removes its 'paused' flag (variable) and makes
435
- # sure to 'replay' events (replies) that came for it while it was
436
- # in pause.
437
- #
438
- def resume_process (wfid)
439
-
440
- wfid = extract_wfid(wfid)
441
-
442
- root_expression = fetch_root(wfid)
443
-
444
- #
445
- # remove 'paused' flag
446
-
447
- root_expression.unset_variable(VAR_PAUSED)
448
-
449
- #
450
- # replay
451
-
452
- journal = get_error_journal
453
-
454
- # select PausedError instances in separate list
455
-
456
- errors = journal.get_error_log(wfid)
457
- error_class = PausedError.name
458
- paused_errors = errors.select { |e| e.error_class == error_class }
459
-
460
- return if paused_errors.size < 1
461
-
462
- # remove them from current error journal
463
-
464
- journal.remove_errors wfid, paused_errors
465
-
466
- # replay select PausedError instances
467
-
468
- paused_errors.each do |e|
469
- journal.replay_at_error e
470
- end
471
- end
472
-
473
427
  #
474
428
  # Replies to the parent of the given expression.
475
429
  #
@@ -538,16 +492,16 @@ module OpenWFE
538
492
  #
539
493
  def update (flow_expression)
540
494
 
541
- #ldebug { "update() for #{flow_expression.fei.to_debug_s}" }
495
+ ldebug { "update() for #{flow_expression.fei.to_debug_s}" }
542
496
 
543
- t = Timer.new
497
+ #t = Timer.new
544
498
 
545
499
  onotify :update, flow_expression.fei, flow_expression
546
500
 
547
- ldebug do
548
- "update() took #{t.duration} ms " +
549
- "#{flow_expression.fei.to_debug_s}"
550
- end
501
+ #ldebug do
502
+ # "update() took #{t.duration} ms " +
503
+ # "#{flow_expression.fei.to_debug_s}"
504
+ #end
551
505
 
552
506
  flow_expression
553
507
  end
@@ -562,16 +516,21 @@ module OpenWFE
562
516
  def fetch (exp)
563
517
  synchronize do
564
518
 
565
- fei = exp
566
-
567
519
  #ldebug { "fetch() exp is of kind #{exp.class}" }
568
520
 
569
- if exp.kind_of?(FlowExpression)
570
- fei = exp.fei
521
+ fei = if exp.kind_of?(FlowExpression)
522
+
523
+ exp.fei
524
+
571
525
  elsif not exp.kind_of?(FlowExpressionId)
526
+
572
527
  raise \
573
528
  "Cannot fetch expression with key : "+
574
529
  "'#{fei}' (#{fei.class})"
530
+
531
+ else
532
+
533
+ exp
575
534
  end
576
535
 
577
536
  #ldebug { "fetch() for #{fei.to_debug_s}" }
@@ -588,7 +547,7 @@ module OpenWFE
588
547
  #
589
548
  def fetch_expression (exp)
590
549
 
591
- exp, _fei = fetch(exp)
550
+ exp, fei = fetch(exp)
592
551
  exp
593
552
  end
594
553
 
@@ -598,6 +557,8 @@ module OpenWFE
598
557
  #
599
558
  def fetch_root (exp_or_wfid)
600
559
 
560
+ ldebug { "fetch_root() '#{exp_or_wfid.to_s}'" }
561
+
601
562
  return fetch_expression_with_wfid(exp_or_wfid) \
602
563
  if exp_or_wfid.is_a?(String)
603
564
 
@@ -638,7 +599,7 @@ module OpenWFE
638
599
  def remove (exp)
639
600
 
640
601
  exp, _fei = fetch(exp) \
641
- if exp.kind_of?(FlowExpressionId)
602
+ if exp.is_a?(FlowExpressionId)
642
603
 
643
604
  return unless exp
644
605
 
@@ -670,12 +631,12 @@ module OpenWFE
670
631
 
671
632
  linfo { "reschedule() initiating..." }
672
633
 
673
- get_expression_storage.each_of_kind(Schedulable) do |fe|
634
+ get_expression_storage.each_of_kind(Schedulable) do |fei, fe|
674
635
 
675
- #linfo { "reschedule() for #{fe.fei.to_debug_s}..." }
676
- linfo { "reschedule() for #{fe.fei.to_s}..." }
636
+ #linfo { "reschedule() for #{fei.to_debug_s}..." }
637
+ linfo { "reschedule() for #{fei.to_s}..." }
677
638
 
678
- onotify :reschedule, fe.fei
639
+ onotify :reschedule, fei
679
640
 
680
641
  fe.reschedule(get_scheduler)
681
642
  end
@@ -762,7 +723,9 @@ module OpenWFE
762
723
 
763
724
  get_expression_storage.real_each(wfid_prefix) do |fei, fexp|
764
725
 
765
- next unless fexp.is_a? DefineExpression
726
+ #ldebug { "list_processes() class is #{fexp.class.name}" }
727
+
728
+ next unless fexp.is_a?(DefineExpression)
766
729
 
767
730
  next if not consider_subprocesses and fei.wfid.index(".")
768
731
 
@@ -779,7 +742,15 @@ module OpenWFE
779
742
  #
780
743
  def fetch_expression_with_wfid (wfid)
781
744
 
782
- list_processes(false, wfid)[0]
745
+ #list_processes(false, wfid)[0]
746
+
747
+ ps = list_processes(false, wfid)
748
+
749
+ ldebug do
750
+ "fetch_expression_with_wfid() '#{wfid}' found #{ps.size} items"
751
+ end
752
+
753
+ ps[0]
783
754
  end
784
755
 
785
756
  #
@@ -851,31 +822,29 @@ module OpenWFE
851
822
  #
852
823
  def do_apply (exp, workitem)
853
824
 
854
- exp, fei = fetch(exp) if exp.kind_of?(FlowExpressionId)
825
+ exp, _fei = fetch(exp) if exp.is_a?(FlowExpressionId)
855
826
 
856
827
  check_if_paused exp
857
828
 
858
- #ldebug { "apply() '#{fei}' (#{fei.class})" }
829
+ #ldebug { "apply() '#{_fei}'" }
859
830
 
860
831
  if not exp
861
832
 
862
- lwarn { "apply() cannot apply missing #{fei.to_debug_s}" }
833
+ lwarn do
834
+ "do_apply() cannot apply missing #{_fei.to_debug_s}"
835
+ end
836
+
863
837
  return
864
838
 
865
- #raise "apply() cannot apply missing #{fei.to_debug_s}"
839
+ #raise "apply() cannot apply missing #{_fei.to_debug_s}"
840
+ # not very helpful anyway
866
841
  end
867
842
 
868
- #ldebug { "apply() #{fei.to_debug_s}" }
869
-
870
- #exp.apply_time = OpenWFE::now()
871
- #
872
- # this is done in RawExpression
873
-
874
843
  workitem.flow_expression_id = exp.fei
875
844
 
876
845
  onotify :apply, exp, workitem
877
846
 
878
- exp.apply(workitem)
847
+ exp.apply workitem
879
848
  end
880
849
 
881
850
  #
@@ -941,10 +910,11 @@ module OpenWFE
941
910
  else #oin
942
911
  { "for" => oin }
943
912
  end
913
+ att["scheduler-tags"] = "scheduled-launch"
944
914
 
945
915
  sle = get_expression_map.get_class(:sleep)
946
916
  sle = sle.new(fei.dup, fei, nil, application_context, att)
947
- sle.fei.expression_id = "0.1"
917
+ sle.fei.expression_id = "0.0"
948
918
  sle.fei.expression_name = "sleep"
949
919
  seq.children << sle.fei
950
920
  seq.children << raw_expression.fei
@@ -968,6 +938,7 @@ module OpenWFE
968
938
  { "every" => oevery }
969
939
  end
970
940
  att["name"] = "//cron_launch__#{fei.wfid}"
941
+ att["scheduler-tags"] = "scheduled-launch"
971
942
 
972
943
  cro = get_expression_map.get_class(:cron)
973
944
  cro = cro.new(fei, nil, nil, application_context, att)
@@ -1128,7 +1099,7 @@ module OpenWFE
1128
1099
  #
1129
1100
  def build_raw_expression (launchitem, param)
1130
1101
 
1131
- procdef = determine_representation(param)
1102
+ procdef = determine_representation param
1132
1103
 
1133
1104
  #return procdef if procdef.is_a? RawExpression
1134
1105
 
@@ -38,13 +38,13 @@
38
38
  # John Mettraux at openwfe.org
39
39
  #
40
40
 
41
- #require 'monitor'
42
41
  require 'fileutils'
43
42
 
44
43
  require 'openwfe/service'
45
44
  require 'openwfe/util/lru'
46
45
  require 'openwfe/flowexpressionid'
47
46
 
47
+
48
48
  module OpenWFE
49
49
 
50
50
  #
@@ -136,7 +136,7 @@ module OpenWFE
136
136
  fe = @cache[fei.hash]
137
137
  return fe if fe
138
138
 
139
- ldebug { "[] (reload) for #{fei.to_debug_s}" }
139
+ #ldebug { "[] (reload) for #{fei.to_debug_s}" }
140
140
 
141
141
  fe = get_real_storage[fei]
142
142
 
@@ -151,6 +151,9 @@ module OpenWFE
151
151
  end
152
152
 
153
153
  def []= (fei, fe)
154
+
155
+ #linfo { "[]= caching #{fei}" }
156
+
154
157
  @cache[fei.hash] = fe
155
158
  end
156
159
 
@@ -244,10 +247,8 @@ module OpenWFE
244
247
  #
245
248
  def each_of_kind (kind, &block)
246
249
 
247
- return unless block
248
-
249
250
  self.each_value do |fexp|
250
- block.call(fexp) if fexp.kind_of?(kind)
251
+ block.call(fexp.fei, fexp) if fexp.kind_of?(kind)
251
252
  end
252
253
  end
253
254
 
@@ -0,0 +1,190 @@
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
+
34
+ #
35
+ # "made in Japan"
36
+ #
37
+ # John Mettraux at openwfe.org
38
+ #
39
+
40
+ #require 'openwfe/flowexpressionid'
41
+
42
+
43
+ module OpenWFE
44
+
45
+ #
46
+ # This mixin gathers all the logic for a threaded expression storage,
47
+ # one that doesn't immediately stores workitems (removes overriding
48
+ # operations).
49
+ # Using this threaded storage brings a very important perf benefit.
50
+ #
51
+ module ThreadedStorageMixin
52
+
53
+ THREADED_FREQ = "427" # milliseconds
54
+ #
55
+ # the frequency at which the event queue should be processed
56
+
57
+ #
58
+ # Will take care of stopping the 'queue processing' thread.
59
+ #
60
+ def stop
61
+
62
+ get_scheduler.unschedule(@thread_id) if @thread_id
63
+
64
+ process_queue()
65
+ #
66
+ # flush every remaining events (especially the :delete ones)
67
+ end
68
+
69
+ #
70
+ # calls process_queue() before the call the super class each_of_kind()
71
+ # method
72
+ #
73
+ def each_of_kind (kind, &block)
74
+
75
+ #ldebug { "each_of_kind()" }
76
+
77
+ process_queue()
78
+ super
79
+ end
80
+
81
+ #
82
+ # calls process_queue() before the call the super class each()
83
+ # method
84
+ #
85
+ def each (wfid_prefix=nil, &block)
86
+
87
+ process_queue()
88
+ super
89
+ end
90
+
91
+ protected
92
+
93
+ #
94
+ # starts the thread that does the actual persistence.
95
+ #
96
+ def start_processing_thread
97
+
98
+ @events = {}
99
+ @op_count = 0
100
+
101
+ @thread_id = get_scheduler.schedule_every THREADED_FREQ do
102
+ process_queue
103
+ end
104
+ end
105
+
106
+ #
107
+ # queues an event for later (well within a second) persistence
108
+ #
109
+ def queue (event, fei, fe=nil)
110
+ synchronize do
111
+
112
+ old_size = @events.size
113
+ @op_count += 1
114
+
115
+ @events[fei] = [ event, fei, fe ]
116
+
117
+ ldebug do
118
+ "queue() ops #{@op_count} "+
119
+ "size #{old_size} -> #{@events.size}"
120
+ end
121
+ end
122
+ end
123
+
124
+ #
125
+ # the actual "do persist" order
126
+ #
127
+ def process_queue
128
+
129
+ return unless @events.size > 0
130
+ #
131
+ # trying to exit as quickly as possible
132
+
133
+ ldebug do
134
+ "process_queue() #{@events.size} events #{@op_count} ops"
135
+ end
136
+
137
+ synchronize do
138
+ @events.each_value do |v|
139
+ event = v[0]
140
+ begin
141
+ if event == :update
142
+ self[v[1]] = v[2]
143
+ else
144
+ safe_delete(v[1])
145
+ end
146
+ rescue Exception => e
147
+ lwarn do
148
+ "process_queue() ':#{event}' exception\n" +
149
+ OpenWFE::exception_to_s(e)
150
+ end
151
+ end
152
+ end
153
+ @op_count = 0
154
+ @events.clear
155
+ end
156
+ end
157
+
158
+ #
159
+ # a call to delete that tolerates missing .yaml files
160
+ #
161
+ def safe_delete (fei)
162
+ begin
163
+ self.delete(fei)
164
+ rescue Exception => e
165
+ # lwarn do
166
+ # "safe_delete() exception\n" +
167
+ # OpenWFE::exception_to_s(e)
168
+ # end
169
+ end
170
+ end
171
+
172
+ #
173
+ # Adds the queue() method as an observer to the update and remove
174
+ # events of the expression pool.
175
+ # :update and :remove mean changes to expressions in the persistence
176
+ # that's why they are observed.
177
+ #
178
+ def observe_expool
179
+
180
+ get_expression_pool.add_observer(:update) do |event, fei, fe|
181
+ ldebug { ":update for #{fei.to_debug_s}" }
182
+ queue(event, fei, fe)
183
+ end
184
+ get_expression_pool.add_observer(:remove) do |event, fei|
185
+ ldebug { ":remove for #{fei.to_debug_s}" }
186
+ queue(event, fei)
187
+ end
188
+ end
189
+ end
190
+ end