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
data/README.txt CHANGED
@@ -1,16 +1,18 @@
1
1
  = OpenWFEru, Standard Library Documentation
2
2
 
3
3
  == Prerequisites
4
- Ruby 1.8.5 or later
5
- RubyGems 0.9.4 or later
4
+
5
+ Ruby 1.8.5 or later, RubyGems 0.9.4 or later
6
6
 
7
7
  == Installation
8
+
8
9
  Installation can be handled by Ruby gems. This will pull in any libraries
9
10
  you will need to install
10
11
 
11
12
  gem install -y openwferu
12
13
 
13
14
  == Overview
15
+
14
16
  OpenWFEru is a Ruby port of the OpenWFE workflow engine
15
17
  (http://www.openwfe.org). It is a complete rewrite in Ruby
16
18
  so does not need to use the Java-based engine from OpenWFE.
@@ -86,7 +86,7 @@ module OpenWFE
86
86
  unless $OWFE_LOG
87
87
  #puts "Creating logs in " + FileUtils.pwd
88
88
  FileUtils.mkdir("logs") unless File.exist?("logs")
89
- $OWFE_LOG = Logger.new("logs/openwferu.log", 10, 1024000)
89
+ $OWFE_LOG = Logger.new "logs/openwferu.log", 10, 1024000
90
90
  $OWFE_LOG.level = Logger::INFO
91
91
  end
92
92
 
@@ -95,37 +95,37 @@ module OpenWFE
95
95
  # especially for the expstorage which 'observes' the expression
96
96
  # pool and thus needs to be instantiated after it.
97
97
 
98
- build_scheduler()
98
+ build_scheduler
99
99
  #
100
100
  # for delayed or repetitive executions (it's the engine's clock)
101
101
  # see http://openwferu.rubyforge.org/scheduler.html
102
102
 
103
- build_expression_map()
103
+ build_expression_map
104
104
  #
105
105
  # mapping expression names ('sequence', 'if', 'concurrence',
106
106
  # 'when'...) to their implementations (SequenceExpression,
107
107
  # IfExpression, ConcurrenceExpression, ...)
108
108
 
109
- build_wfid_generator()
109
+ build_wfid_generator
110
110
  #
111
111
  # the workflow instance (process instance) id generator
112
112
  # making sure each process instance has a unique identifier
113
113
 
114
- build_expression_pool()
114
+ build_expression_pool
115
115
  #
116
116
  # the core (hairy ball) of the engine
117
117
 
118
- build_expression_storage()
118
+ build_expression_storage
119
119
  #
120
120
  # the engine persistence (persisting the expression instances
121
121
  # that make up process instances)
122
122
 
123
- build_participant_map()
123
+ build_participant_map
124
124
  #
125
125
  # building the services that maps participant names to
126
126
  # participant implementations / instances.
127
127
 
128
- build_error_journal()
128
+ build_error_journal
129
129
  #
130
130
  # builds the error journal (keeping track of failures
131
131
  # in business process executions, and an opportunity to
@@ -212,22 +212,50 @@ module OpenWFE
212
212
  #
213
213
  # This method also accepts LaunchItem instances.
214
214
  #
215
+ # Since OpenWFEru 0.9.16, this reply method accepts InFlowWorkitem
216
+ # that don't belong to a process instance (ie whose flow_expression_id
217
+ # is nil). It will simply notify the participant_map of the reply
218
+ # for the given participant_name. If there is no participant_name
219
+ # specified for this orphan workitem, an exception will be raised.
220
+ #
215
221
  def reply (workitem)
216
222
 
217
- if workitem.kind_of?(InFlowWorkItem)
223
+ if workitem.is_a?(InFlowWorkItem)
218
224
 
219
- get_expression_pool.reply workitem.flow_expression_id, workitem
225
+ if workitem.flow_expression_id
226
+ #
227
+ # vanilla case, workitem coming back
228
+ # (from listener probably)
220
229
 
221
- elsif workitem.kind_of?(LaunchItem)
230
+ return get_expression_pool.reply(
231
+ workitem.flow_expression_id, workitem)
232
+ end
222
233
 
223
- get_expression_pool.launch workitem
234
+ if workitem.participant_name
235
+ #
236
+ # a workitem that doesn't belong to a process instance
237
+ # but bears a participant name.
238
+ # Notify, there may be something listening on
239
+ # this channel (see the 'listen' expression).
224
240
 
225
- else
241
+ return get_participant_map.onotify(
242
+ workitem.participant_name, :reply, workitem)
243
+ end
226
244
 
227
245
  raise \
228
- "engine.reply() " +
229
- "cannot handle instances of #{workitem.class}"
246
+ "InFlowWorkitem doesn't belong to a process instance" +
247
+ " nor to a participant"
230
248
  end
249
+
250
+ return get_expression_pool.launch(workitem) \
251
+ if workitem.is_a?(LaunchItem)
252
+ #
253
+ # launchitem coming from listener
254
+ # let's attempt to launch a new process instance
255
+
256
+ raise \
257
+ "engine.reply() " +
258
+ "cannot handle instances of #{workitem.class}"
231
259
  end
232
260
 
233
261
  alias :forward :reply
@@ -254,7 +282,7 @@ module OpenWFE
254
282
  #
255
283
  def get_participant (participant_name)
256
284
 
257
- get_participant_map.lookup_participant(participant_name)
285
+ get_participant_map.lookup_participant participant_name
258
286
  end
259
287
 
260
288
  #
@@ -263,7 +291,7 @@ module OpenWFE
263
291
  #
264
292
  def unregister_participant (participant_name)
265
293
 
266
- get_participant_map.unregister_participant(participant_name)
294
+ get_participant_map.unregister_participant participant_name
267
295
  end
268
296
 
269
297
  #
@@ -568,7 +596,11 @@ module OpenWFE
568
596
  #
569
597
  def pause_process (wfid)
570
598
 
571
- get_expression_pool.pause_process(wfid)
599
+ wfid = extract_wfid(wfid)
600
+
601
+ root_expression = get_expression_pool.fetch_root(wfid)
602
+
603
+ root_expression.set_variable(VAR_PAUSED, true)
572
604
  end
573
605
 
574
606
  #
@@ -578,7 +610,47 @@ module OpenWFE
578
610
  #
579
611
  def resume_process (wfid)
580
612
 
581
- get_expression_pool.resume_process(wfid)
613
+ wfid = extract_wfid wfid
614
+
615
+ root_expression = get_expression_pool.fetch_root wfid
616
+
617
+ #
618
+ # remove 'paused' flag
619
+
620
+ root_expression.unset_variable(VAR_PAUSED)
621
+
622
+ #
623
+ # replay
624
+ #
625
+ # select PausedError instances in separate list
626
+
627
+ errors = get_error_journal.get_error_log wfid
628
+ error_class = PausedError.name
629
+ paused_errors = errors.select { |e| e.error_class == error_class }
630
+
631
+ return if paused_errors.size < 1
632
+
633
+ # replay select PausedError instances
634
+
635
+ paused_errors.each do |e|
636
+ replay_at_error e
637
+ end
638
+ end
639
+
640
+ #
641
+ # Takes care of removing an error from the error journal and
642
+ # they replays its process at that point.
643
+ #
644
+ def replay_at_error (error)
645
+
646
+ get_error_journal.remove_errors(
647
+ error.fei.parent_wfid,
648
+ error)
649
+
650
+ get_expression_pool.queue_work(
651
+ error.message,
652
+ error.fei,
653
+ error.workitem)
582
654
  end
583
655
 
584
656
  #
@@ -605,6 +677,46 @@ module OpenWFE
605
677
  exp.lookup_variable var_name
606
678
  end
607
679
 
680
+ #
681
+ # Returns an array of wfid (workflow instance ids) whose root
682
+ # environment containes the given variable
683
+ #
684
+ # If there are no matches, an empty array will be returned.
685
+ #
686
+ # Regular expressions are accepted as values.
687
+ #
688
+ # If no value is given, all processes with the given variable name
689
+ # set will be returned.
690
+ #
691
+ def lookup_processes (var_name, value=nil)
692
+
693
+ # TODO : maybe this would be better in the ExpressionPool
694
+
695
+ result = []
696
+
697
+ regexp = if value
698
+ if value.is_a?(Regexp)
699
+ value
700
+ else
701
+ Regexp.compile(value.to_s)
702
+ end
703
+ else
704
+ nil
705
+ end
706
+
707
+ get_expression_storage.each_of_kind(Environment) do |fei, env|
708
+
709
+ val = env.variables[var_name]
710
+
711
+ next unless val
712
+ next if regexp and (not regexp.match(val))
713
+
714
+ result.push env.fei.wfid
715
+ end
716
+
717
+ result
718
+ end
719
+
608
720
  protected
609
721
 
610
722
  #--
@@ -649,7 +761,7 @@ module OpenWFE
649
761
  #
650
762
  def build_expression_pool
651
763
 
652
- init_service(S_EXPRESSION_POOL, ExpressionPool)
764
+ init_service S_EXPRESSION_POOL, ExpressionPool
653
765
  end
654
766
 
655
767
  #
@@ -661,7 +773,7 @@ module OpenWFE
661
773
  #
662
774
  def build_expression_storage
663
775
 
664
- init_service(S_EXPRESSION_STORAGE, InMemoryExpressionStorage)
776
+ init_service S_EXPRESSION_STORAGE, InMemoryExpressionStorage
665
777
  end
666
778
 
667
779
  #
@@ -671,7 +783,7 @@ module OpenWFE
671
783
  #
672
784
  def build_participant_map
673
785
 
674
- init_service(S_PARTICIPANT_MAP, ParticipantMap)
786
+ init_service S_PARTICIPANT_MAP, ParticipantMap
675
787
  end
676
788
 
677
789
  #
@@ -680,7 +792,7 @@ module OpenWFE
680
792
  #
681
793
  def build_scheduler
682
794
 
683
- init_service(S_SCHEDULER, SchedulerService)
795
+ init_service S_SCHEDULER, SchedulerService
684
796
  end
685
797
 
686
798
  #
@@ -689,7 +801,7 @@ module OpenWFE
689
801
  #
690
802
  def build_error_journal
691
803
 
692
- init_service(S_ERROR_JOURNAL, InMemoryErrorJournal)
804
+ init_service S_ERROR_JOURNAL, InMemoryErrorJournal
693
805
  end
694
806
 
695
807
  #
@@ -756,10 +868,16 @@ module OpenWFE
756
868
  #
757
869
  attr_reader :errors
758
870
 
871
+ #
872
+ # The time at which the process got launched.
873
+ #
874
+ attr_reader :launch_time
875
+
759
876
  def initialize
760
877
  @wfid = nil
761
878
  @expressions = []
762
879
  @errors = {}
880
+ @launch_time = nil
763
881
  end
764
882
 
765
883
  #
@@ -806,7 +924,7 @@ module OpenWFE
806
924
 
807
925
  set_wfid fexp.fei.parent_wfid
808
926
 
809
- #@expressions << fexp
927
+ @launch_time = fexp.apply_time if fexp.fei.expid == '0'
810
928
 
811
929
  exps = @expressions
812
930
  @expressions = []
@@ -62,7 +62,7 @@ module OpenWFE
62
62
  #
63
63
  def build_expression_storage ()
64
64
 
65
- init_service(S_EXPRESSION_STORAGE, YamlFileExpressionStorage)
65
+ init_service S_EXPRESSION_STORAGE, YamlFileExpressionStorage
66
66
  end
67
67
 
68
68
  #
@@ -70,7 +70,7 @@ module OpenWFE
70
70
  #
71
71
  def build_error_journal ()
72
72
 
73
- init_service(S_ERROR_JOURNAL, YamlErrorJournal)
73
+ init_service S_ERROR_JOURNAL, YamlErrorJournal
74
74
  end
75
75
  end
76
76
 
@@ -88,7 +88,7 @@ module OpenWFE
88
88
 
89
89
  def build_expression_storage ()
90
90
 
91
- @application_context[:expression_cache_size] = 1000
91
+ @application_context[:expression_cache_size] ||= 1000
92
92
 
93
93
  init_service(
94
94
  S_EXPRESSION_STORAGE,
@@ -42,6 +42,7 @@ require 'fileutils'
42
42
 
43
43
  require 'openwfe/service'
44
44
  require 'openwfe/omixins'
45
+ require 'openwfe/rudefinitions'
45
46
 
46
47
 
47
48
  module OpenWFE
@@ -151,9 +152,9 @@ module OpenWFE
151
152
 
152
153
  super
153
154
 
154
- get_expression_pool.add_observer(:error) do |event, *args|
155
+ get_expression_pool.add_observer :error do |event, *args|
155
156
  #
156
- # logs each error occuring in the expression pool
157
+ # logs each error occurring in the expression pool
157
158
 
158
159
  begin
159
160
 
@@ -163,6 +164,16 @@ module OpenWFE
163
164
  lwarn { "*** process error : \n" + args.join("\n") }
164
165
  end
165
166
  end
167
+
168
+ get_expression_pool.add_observer :terminate do |event, *args|
169
+ #
170
+ # removes error log when a process terminates
171
+
172
+ fei = args[0].fei
173
+
174
+ remove_error_log fei.wfid \
175
+ if fei.is_in_parent_process?
176
+ end
166
177
  end
167
178
 
168
179
  #
@@ -174,6 +185,9 @@ module OpenWFE
174
185
  get_error_log(wfid).size > 0
175
186
  end
176
187
 
188
+ #--
189
+ #
190
+ # Commented out : has no real value
177
191
  #
178
192
  # Replays the given process instance (wfid or fei) at its last
179
193
  # recorded error.
@@ -185,32 +199,30 @@ module OpenWFE
185
199
  #
186
200
  # Will replay a given process instance at its 1 to last error.
187
201
  #
188
- def replay_at_last_error (wfid, offset=0)
189
-
190
- wfid = to_wfid(wfid)
191
-
192
- log = get_error_log(wfid)
193
-
194
- index = (-1 - offset)
195
-
196
- error = log[index]
197
-
198
- raise "no error for process '#{wfid}' at offset #{offset}" \
199
- unless error
200
-
201
- replay_at_error error
202
- end
202
+ #def replay_at_last_error (wfid, offset=0)
203
+ # wfid = to_wfid(wfid)
204
+ # log = get_error_log(wfid)
205
+ # index = (-1 - offset)
206
+ # error = log[index]
207
+ # raise "no error for process '#{wfid}' at offset #{offset}" \
208
+ # unless error
209
+ # replay_at_error error
210
+ #end
211
+ #++
203
212
 
213
+ #--
214
+ #
215
+ # Moved to the engine itself.
204
216
  #
205
217
  # Replays at a specific error (fetched with read_error_log()).
206
218
  #
207
- def replay_at_error (error)
208
-
209
- get_expression_pool.queue_work(
210
- error.message,
211
- error.fei,
212
- error.workitem)
213
- end
219
+ #def replay_at_error (error)
220
+ # get_expression_pool.queue_work(
221
+ # error.message,
222
+ # error.fei,
223
+ # error.workitem)
224
+ #end
225
+ #++
214
226
 
215
227
  #
216
228
  # A utility method : given a list of errors, will make sure that for
@@ -276,8 +288,12 @@ module OpenWFE
276
288
  #
277
289
  # Removes a list of errors from the error journal.
278
290
  #
291
+ # The 'errors' parameter may be a single error (instead of an array).
292
+ #
279
293
  def remove_errors (wfid, errors)
280
294
 
295
+ errors = Array(errors)
296
+
281
297
  log = get_error_log wfid
282
298
 
283
299
  errors.each do |e|
@@ -313,6 +329,9 @@ module OpenWFE
313
329
  def initialize (service_name, application_context)
314
330
 
315
331
  require 'openwfe/storage/yamlcustom'
332
+ # making sure this file has been required at this point
333
+ # this yamlcustom thing prevents the whole OpenWFE ecosystem
334
+ # to get serialized :)
316
335
 
317
336
  super
318
337
 
@@ -373,7 +392,9 @@ module OpenWFE
373
392
  #
374
393
  def remove_error_log (wfid)
375
394
 
376
- File.delete(get_path(wfid))
395
+ path = get_path wfid
396
+
397
+ File.delete(path) if File.exist?(path)
377
398
  end
378
399
 
379
400
  #
@@ -381,6 +402,8 @@ module OpenWFE
381
402
  #
382
403
  def remove_errors (wfid, errors)
383
404
 
405
+ errors = Array(errors)
406
+
384
407
  # load all errors
385
408
 
386
409
  log = get_error_log wfid