openwferu 0.9.3 → 0.9.4

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 (59) hide show
  1. data/examples/flowtracing.rb +22 -0
  2. data/lib/openwfe/contextual.rb +5 -2
  3. data/lib/openwfe/def.rb +47 -0
  4. data/lib/openwfe/engine/engine.rb +1 -1
  5. data/lib/openwfe/engine/file_persisted_engine.rb +3 -5
  6. data/lib/openwfe/expool/expressionpool.rb +45 -6
  7. data/lib/openwfe/expool/history.rb +117 -0
  8. data/lib/openwfe/expool/yamlexpstorage.rb +21 -4
  9. data/lib/openwfe/expressions/environment.rb +3 -0
  10. data/lib/openwfe/expressions/expressionmap.rb +1 -0
  11. data/lib/openwfe/expressions/fe_concurrence.rb +22 -12
  12. data/lib/openwfe/expressions/fe_iterator.rb +3 -1
  13. data/lib/openwfe/expressions/fe_participant.rb +1 -4
  14. data/lib/openwfe/expressions/fe_raw.rb +2 -2
  15. data/lib/openwfe/expressions/fe_time.rb +184 -10
  16. data/lib/openwfe/expressions/fe_utils.rb +10 -0
  17. data/lib/openwfe/expressions/flowexpression.rb +3 -1
  18. data/lib/openwfe/expressions/raw_prog.rb +1 -1
  19. data/lib/openwfe/expressions/timeout.rb +47 -13
  20. data/lib/openwfe/flowexpressionid.rb +9 -1
  21. data/lib/openwfe/participants/csvparticipant.rb +127 -0
  22. data/lib/openwfe/participants/participant.rb +1 -0
  23. data/lib/openwfe/participants/participants.rb +26 -3
  24. data/lib/openwfe/rest/controlclient.rb +3 -3
  25. data/lib/openwfe/rest/worklistclient.rb +6 -8
  26. data/lib/openwfe/rest/xmlcodec.rb +6 -6
  27. data/lib/openwfe/rudefinitions.rb +6 -13
  28. data/lib/openwfe/storage/yamlfilestorage.rb +1 -1
  29. data/lib/openwfe/tools/flowtracer.rb +80 -0
  30. data/lib/openwfe/util/csvtable.rb +378 -0
  31. data/lib/openwfe/util/dollar.rb +24 -7
  32. data/lib/openwfe/util/observable.rb +82 -0
  33. data/lib/openwfe/util/scheduler.rb +14 -0
  34. data/lib/openwfe/utils.rb +64 -0
  35. data/lib/openwfe/version.rb +38 -0
  36. data/lib/openwfe/workitem.rb +53 -0
  37. data/lib/openwfe/worklist/storeparticipant.rb +19 -4
  38. data/test/csv_test.rb +285 -0
  39. data/test/fei_test.rb +1 -1
  40. data/test/file_persistence_test.rb +2 -2
  41. data/test/flowtestbase.rb +10 -3
  42. data/test/ft_0.rb +0 -7
  43. data/test/ft_0d_participant.rb +29 -0
  44. data/test/ft_11_ppd.rb +26 -1
  45. data/test/ft_12_blockparticipant.rb +28 -1
  46. data/test/ft_19_csv.rb +64 -0
  47. data/test/ft_20_cron.rb +60 -0
  48. data/test/ft_21_cron.rb +48 -0
  49. data/test/ft_22_history.rb +68 -0
  50. data/test/ft_23_when.rb +50 -0
  51. data/test/ft_23b_when.rb +45 -0
  52. data/test/ft_24_def.rb +47 -0
  53. data/test/ft_9_cursor.rb +20 -0
  54. data/test/rake_qtest.rb +7 -0
  55. data/test/rake_test.rb +3 -0
  56. data/test/timeout_test.rb +46 -4
  57. data/test/wi_test.rb +66 -0
  58. metadata +21 -3
  59. data/test/rake_ptest.rb +0 -18
@@ -37,10 +37,13 @@
37
37
  # "made in Japan"
38
38
  #
39
39
 
40
+ require 'openwfe/version'
41
+
42
+
40
43
  module OpenWFE
41
44
 
42
45
  #OPENWFE_VERSION = '1.7.2pre17'
43
- OPENWFE_VERSION = '0.9.2'
46
+ #OPENWFE_VERSION = '0.9.4'
44
47
 
45
48
  #
46
49
  # service names
@@ -64,20 +67,10 @@ module OpenWFE
64
67
 
65
68
  EN_ENVIRONMENT = 'environment'
66
69
 
67
- #
68
- # some expression attribute names
69
-
70
- #A_FORGET = 'forget'
71
- # replaced by a symbol
72
-
73
- A_SYNC = 'sync'
74
- A_COUNT = 'count'
75
- A_REMAINING = 'remaining'
76
- REM_CANCEL = 'cancel'
77
-
78
70
  #
79
71
  # some file storage default values
80
- DEFAULT_FILE_STORAGE_PATH = "./work"
72
+
73
+ DEFAULT_WORK_DIRECTORY = './work'
81
74
 
82
75
  #
83
76
  # A mixin for easy OpenWFE service lookup
@@ -189,7 +189,7 @@ module OpenWFE
189
189
  end
190
190
 
191
191
  def compute_file_path (fei)
192
- raise "this should be implemented in a subclass"
192
+ raise NotImplementedError.new
193
193
  end
194
194
 
195
195
  end
@@ -0,0 +1,80 @@
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: workitem.rb 3556 2006-11-13 04:15:52Z jmettraux $
34
+ #
35
+
36
+ #
37
+ # Made in Japan
38
+ #
39
+ # John Mettraux at OpenWFE dot org
40
+ #
41
+
42
+ require 'openwfe/workitem'
43
+ require 'openwfe/engine/engine'
44
+
45
+ include OpenWFE
46
+
47
+
48
+ module OpenWFE
49
+
50
+ def trace_flow (process_definition)
51
+ li = LaunchItem.new(process_definition)
52
+
53
+ engine = Engine.new()
54
+
55
+ i = 0
56
+
57
+ engine.register_participant(".*") do |workitem|
58
+
59
+ puts "-- #{i} ------------------------------------------------------------------------"
60
+ puts
61
+ puts " participant '#{workitem.participant_name}' received workitem :"
62
+ puts
63
+ puts workitem.to_s
64
+ puts
65
+ puts "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"
66
+ puts
67
+ puts " expression pool state :"
68
+ #puts
69
+ puts engine.get_expression_storage.to_s
70
+ puts
71
+ #puts
72
+
73
+ i = i + 1
74
+ end
75
+
76
+ engine.launch(li)
77
+ end
78
+
79
+ end
80
+
@@ -0,0 +1,378 @@
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$
34
+ #
35
+
36
+ #
37
+ # "made in Japan"
38
+ #
39
+ # John Mettraux at openwfe.org
40
+ #
41
+
42
+ require 'csv'
43
+
44
+ require 'openwfe/utils'
45
+ require 'openwfe/util/dollar'
46
+
47
+ include OpenWFE
48
+
49
+
50
+ module OpenWFE
51
+
52
+ #
53
+ # A 'CsvTable' is called a 'decision table' in OpenWFEja (the initial
54
+ # Java implementation of OpenWFE).
55
+ #
56
+ # A csv table is a description of a set of rules as a CSV (comma
57
+ # separated values) file. Such a file can be edited / generated by
58
+ # a spreadsheet (Excel, Google spreadsheets, Gnumeric, ...)
59
+ #
60
+ # The following CSV file
61
+ #
62
+ # in:topic,in:region,out:team_member
63
+ # sports,europe,Alice
64
+ # sports,,Bob
65
+ # finance,america,Charly
66
+ # finance,europe,Donald
67
+ # finance,,Ernest
68
+ # politics,asia,Fujio
69
+ # politics,america,Gilbert
70
+ # politics,,Henry
71
+ # ,,Zach
72
+ #
73
+ # embodies a rule for distributing items (piece of news) labelled with a
74
+ # topic and a region to various members of a team.
75
+ # For example, all news about finance from Europe are to be routed to
76
+ # Donald.
77
+ #
78
+ # Evaluation occurs row by row. The "in out" row states which field
79
+ # is considered at input and which are to be modified if the "ins" do
80
+ # match.
81
+ #
82
+ # The default behaviour is to change the value of the "outs" if all the
83
+ # "ins" match and then terminate.
84
+ # An empty "in" cell means "matches any".
85
+ #
86
+ # Enough words, some code :
87
+ #
88
+ # table = CsvTable.new("""
89
+ # in:topic,in:region,out:team_member
90
+ # sports,europe,Alice
91
+ # sports,,Bob
92
+ # finance,america,Charly
93
+ # finance,europe,Donald
94
+ # finance,,Ernest
95
+ # politics,asia,Fujio
96
+ # politics,america,Gilbert
97
+ # politics,,Henry
98
+ # ,,Zach
99
+ # """)
100
+ #
101
+ # h = {}
102
+ # h["topic"] = "politics"
103
+ #
104
+ # table.transform(h)
105
+ #
106
+ # puts h["team_member"]
107
+ # # will yield "Henry" who takes care of all the politics stuff,
108
+ # # except for Asia and America
109
+ #
110
+ # Disclaimer : the decision / CSV table system is no replacement for
111
+ # full rule engines with forward and backward chaining, RETE implementation
112
+ # and the like...
113
+ #
114
+ #
115
+ # Options :
116
+ #
117
+ # You can put options on their own in a cell BEFORE the line containing
118
+ # "in:xxx" and "out:yyy" (ins and outs).
119
+ #
120
+ # Currently, two options are supported, "ignorecase" and "through".
121
+ #
122
+ # "ignorecase", if found by the CsvTable will make any match (in the "in"
123
+ # columns) case unsensitive.
124
+ #
125
+ # "through", will make sure that EVERY row is evaluated and potentially
126
+ # applied. The default behaviour (without "through"), is to stop the
127
+ # evaluation after applying the results of the first matching row.
128
+ #
129
+ #
130
+ # CSV Tables are available to workflows as CsvParticipant.
131
+ #
132
+ #
133
+ # See also :
134
+ #
135
+ # http://jmettraux.wordpress.com/2007/02/11/ruby-decision-tables/
136
+ # http://rubyforge.org/viewvc/trunk/openwfe-ruby/test/csv_test.rb?root=openwferu&view=co
137
+ #
138
+ class CsvTable
139
+
140
+ attr_accessor \
141
+ :first_match,
142
+ :ignore_case,
143
+ :header,
144
+ :rows
145
+
146
+ #
147
+ # The constructor for CsvTable, you can pass a String, an Array
148
+ # (of arrays), a File object. The CSV parser coming with Ruby will take
149
+ # care of it and a CsvTable instance will be built.
150
+ #
151
+ def initialize (csv_data)
152
+
153
+ @first_match = true
154
+ @ignore_case = false
155
+
156
+ @header = nil
157
+ @rows = []
158
+
159
+ csv_array = to_csv_array(csv_data)
160
+
161
+ csv_array.each do |row|
162
+
163
+ next if empty_row? row
164
+
165
+ if @header
166
+ #@rows << row
167
+ @rows << row.collect { |c| c.strip if c }
168
+ else
169
+ parse_header_row(row)
170
+ end
171
+ end
172
+ end
173
+
174
+ #
175
+ # Returns the workitem massaged by the csv table
176
+ #
177
+ def transform_wi (flow_expression, workitem)
178
+
179
+ @rows.each do |row|
180
+
181
+ if matches?(row, flow_expression, workitem)
182
+ apply(row, flow_expression, workitem)
183
+ break if @first_match
184
+ end
185
+ end
186
+
187
+ return workitem
188
+ end
189
+
190
+ #
191
+ # Passes a simple Hash instance though the csv table
192
+ #
193
+ def transform (hash)
194
+ wi = InFlowWorkItem.new()
195
+ wi.attributes = hash
196
+ return transform_wi(nil, wi).attributes
197
+ end
198
+
199
+ protected
200
+
201
+ def to_csv_array (csv_data)
202
+
203
+ return csv_data if csv_data.kind_of? Array
204
+ return CSV::Reader.parse(csv_data)
205
+ end
206
+
207
+ def matches? (row, fexp, wi)
208
+
209
+ return false if empty_row? row
210
+
211
+ #puts
212
+ #puts "__row match ?"
213
+ #require 'pp'
214
+ #pp row
215
+
216
+ @header.ins.each_with_index do |in_header, icol|
217
+
218
+ in_header = resolve_in_header(in_header)
219
+
220
+ value = OpenWFE::dosub(in_header, fexp, wi)
221
+
222
+ cell = row[icol]
223
+
224
+ next if not cell
225
+
226
+ cell = cell.strip
227
+
228
+ next if cell.length < 1
229
+
230
+ cell = OpenWFE::dosub(cell, fexp, wi)
231
+
232
+ modifiers = 0
233
+ modifiers += Regexp::IGNORECASE if @ignore_case
234
+
235
+ #puts "__does '#{value}' match '#{cell}' ?"
236
+
237
+ rcell = Regexp.new(cell, modifiers)
238
+ return false unless rcell.match(value)
239
+ end
240
+
241
+ #puts "__row matches"
242
+
243
+ return true
244
+ end
245
+
246
+ def resolve_in_header (in_header)
247
+
248
+ in_header = "f:#{in_header}" \
249
+ if points_to_nothing? in_header
250
+
251
+ return "${#{in_header}}"
252
+ end
253
+
254
+ def apply (row, fexp, wi)
255
+
256
+ #puts "__ apply() wi.class : #{wi.class.name}"
257
+
258
+ @header.outs.each_with_index do |out_header, icol|
259
+
260
+ next unless out_header
261
+
262
+ value = row[icol]
263
+
264
+ next unless value
265
+ #next unless value.strip.length > 0
266
+ next unless value.length > 0
267
+
268
+ value = OpenWFE::dosub(value, fexp, wi)
269
+
270
+ #puts "___ value:'#{value}'"
271
+ #puts "___ value:'"+value+"'"
272
+
273
+ type, target = points_at(out_header)
274
+
275
+ #puts "___ t:'#{type}' target:'#{target}'"
276
+
277
+ if type == "v"
278
+ fexp.set_variable(target, value) if fexp
279
+ elsif type == "f"
280
+ wi.set_attribute(target, value)
281
+ elsif type == "r"
282
+ instance_eval(value)
283
+ end
284
+ end
285
+ end
286
+
287
+ def parse_header_row (row)
288
+
289
+ row.each_with_index do |cell, icol|
290
+
291
+ next unless cell
292
+
293
+ cell = cell.strip
294
+ s = cell.downcase
295
+
296
+ if s == "ignorecase" or s == "ignore_case"
297
+ @ignore_case = true
298
+ next
299
+ end
300
+
301
+ if s == "through"
302
+ @first_match = false
303
+ next
304
+ end
305
+
306
+ if OpenWFE::starts_with(cell, "in:") or OpenWFE::starts_with(cell, "out:")
307
+ @header = Header.new unless @header
308
+ @header.add cell, icol
309
+ end
310
+ end
311
+ end
312
+
313
+ def empty_row? (row)
314
+ return true unless row
315
+ return true if (row.length == 1 and not row[0])
316
+ row.each do |cell|
317
+ return false if cell
318
+ end
319
+ return true
320
+ end
321
+
322
+ def points_to_nothing? (label)
323
+ (not points_to_variable? label) and \
324
+ (not points_to_field? label) and \
325
+ (not points_to_ruby? label)
326
+ end
327
+ def points_at (label)
328
+ v = points_to_variable? label
329
+ return "v", v if v
330
+ r = points_to_ruby? label
331
+ return "r", r if r
332
+ f = points_to_field? label
333
+ return "f", f if f
334
+ return "f", label # else
335
+ end
336
+ def points_to_variable? (label)
337
+ points_to?(label, [ "v", "var", "variable" ])
338
+ end
339
+ def points_to_field? (label)
340
+ points_to?(label, [ "f", "field" ])
341
+ end
342
+ def points_to_ruby? (label)
343
+ points_to?(label, [ "r", "ruby", "reval" ])
344
+ end
345
+ def points_to? (label, names)
346
+ i = label.index(":")
347
+ return nil unless i
348
+ s = label[0..i-1]
349
+ names.each do |name|
350
+ return label[i+1..-1] if s == name
351
+ end
352
+ return nil
353
+ end
354
+
355
+ class Header
356
+
357
+ attr_accessor :ins, :outs
358
+
359
+ def initialize
360
+ @ins = []
361
+ @outs = []
362
+ end
363
+
364
+ def add (cell, icol)
365
+ if OpenWFE::starts_with(cell, "in:")
366
+ @ins[icol] = cell[3..-1]
367
+ #puts "i added #{@ins[icol]}"
368
+ elsif OpenWFE::starts_with(cell, "out:")
369
+ @outs[icol] = cell[4..-1]
370
+ #puts "o added #{@outs[icol]}"
371
+ end
372
+ # else don't add
373
+ end
374
+ end
375
+ end
376
+
377
+ end
378
+
@@ -50,6 +50,9 @@ module OpenWFE
50
50
  def OpenWFE.dsub (text, dict)
51
51
 
52
52
  #puts "### text is >#{text}<"
53
+ #puts "### dict is of class #{dict.class.name}"
54
+
55
+ #return nil unless text
53
56
 
54
57
  j = text.index("}")
55
58
 
@@ -122,13 +125,18 @@ module OpenWFE
122
125
 
123
126
  return '' if k == ''
124
127
 
125
- return @workitem.attributes[k] if p == 'f'
126
- return @flow_expression.lookup_variable(k) if p == 'v'
128
+ return @workitem.lookup_attribute(k) if p == 'f'
129
+
130
+ if p == 'v'
131
+ return '' unless @flow_expression
132
+ return @flow_expression.lookup_variable(k)
133
+ end
134
+
127
135
  return call_function(k) if p == 'c'
128
136
  return call_ruby(k) if p == 'r'
129
137
  # TODO : implement constant lookup
130
138
 
131
- return @workitem.attributes[key]
139
+ return @workitem.lookup_attribute(key)
132
140
  end
133
141
 
134
142
  def has_key? (key)
@@ -136,13 +144,18 @@ module OpenWFE
136
144
 
137
145
  return false if k == ''
138
146
 
139
- return @workitem.attributes.has_key?(k) if p == 'f'
140
- return (@flow_expression.lookup_variable(k) != nil) if p == 'v'
147
+ return @workitem.has_attribute?(k) if p == 'f'
148
+
149
+ if p == 'v'
150
+ return false unless @flow_expression
151
+ return (@flow_expression.lookup_variable(k) != nil)
152
+ end
153
+
141
154
  return true if p == 'c'
142
155
  return true if p == 'r'
143
156
  # TODO : implement constant lookup
144
157
 
145
- return @workitem.attributes.has_key?(key)
158
+ return @workitem.has_attribute?(key)
146
159
  end
147
160
 
148
161
  protected
@@ -159,7 +172,11 @@ module OpenWFE
159
172
  end
160
173
 
161
174
  def call_ruby (ruby_code)
162
- eval(ruby_code, @flow_expression.get_binding).to_s
175
+
176
+ binding = nil
177
+ binding = @flow_expression.get_binding if @flow_expression
178
+
179
+ eval(ruby_code, binding).to_s
163
180
  end
164
181
  end
165
182
 
@@ -0,0 +1,82 @@
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
+ module OpenWFE
43
+
44
+ #
45
+ # A classic : this mixin gathers observability methods. It assumes
46
+ # that customer classes will have a @observers instance variable
47
+ # available.
48
+ # This mixin is chiefly used by the ExpressionPool class.
49
+ #
50
+ module Observable
51
+
52
+ #
53
+ # Observers will register themselves to the Observable via
54
+ # this method.
55
+ #
56
+ def add_observer (channel, &callback)
57
+ (@observers[channel] ||= []) << callback
58
+ end
59
+
60
+ protected
61
+
62
+ #
63
+ # Observable classes do call this method to notify their
64
+ # observers
65
+ #
66
+ def onotify (channel, *args)
67
+ do_notify(channel, channel, *args)
68
+ do_notify(:all, channel, *args)
69
+ end
70
+
71
+ private
72
+
73
+ def do_notify (target_channel, channel, *args)
74
+ if @observers[target_channel]
75
+ @observers[target_channel].each do |obs|
76
+ obs.call channel, *args
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
82
+
@@ -306,6 +306,20 @@ module OpenWFE
306
306
  return nil
307
307
  end
308
308
 
309
+ #
310
+ # Returns the number of currently pending jobs in this scheduler.
311
+ #
312
+ def pending_job_count
313
+ @pending_jobs.size
314
+ end
315
+
316
+ #
317
+ # Returns the number of cron jobs currently active in this scheduler.
318
+ #
319
+ def cron_job_count
320
+ @cron_entries.size
321
+ end
322
+
309
323
  protected
310
324
 
311
325
  def to_block (schedulable, params, &block)