openwferu 0.9.14 → 0.9.15

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.
data/README.txt CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  == Prerequisites
4
4
  Ruby 1.8.5 or later
5
+ RubyGems 0.9.4 or later
5
6
 
6
7
  == Installation
7
8
  Installation can be handled by Ruby gems. This will pull in any libraries
@@ -312,7 +312,7 @@ module OpenWFE
312
312
 
313
313
  def initialize (service_name, application_context)
314
314
 
315
- require 'openwfe/storage/yamlextras'
315
+ require 'openwfe/storage/yamlcustom'
316
316
 
317
317
  super
318
318
 
@@ -47,6 +47,47 @@ require 'openwfe/flowexpressionid'
47
47
 
48
48
  module OpenWFE
49
49
 
50
+ #
51
+ # This module contains the observe_expool method which binds the
52
+ # storage to the expression pool.
53
+ # It also features a to_s method for the expression storages including
54
+ # it.
55
+ #
56
+ module ExpressionStorageBase
57
+
58
+ def observe_expool
59
+
60
+ get_expression_pool.add_observer(:update) do |channel, fei, fe|
61
+ ldebug { ":update for #{fei}" }
62
+ self[fei] = fe
63
+ end
64
+ get_expression_pool.add_observer(:remove) do |channel, fei|
65
+ ldebug { ":delete for #{fei}" }
66
+ self.delete(fei)
67
+ end
68
+ end
69
+
70
+ def to_s
71
+
72
+ s = "\n\n==== #{self.class} ===="
73
+
74
+ self.each do |k, v|
75
+ s << "\n"
76
+ if v.kind_of?(RawExpression)
77
+ s << "*raw"
78
+ else
79
+ s << " "
80
+ end
81
+ #s << v.to_s
82
+ s << v.fei.to_s
83
+ s << " key/value mismatch !" if k != v.fei
84
+ end
85
+ s << "\n==== . ====\n"
86
+
87
+ s
88
+ end
89
+ end
90
+
50
91
  #
51
92
  # This cache uses a LruHash (Least Recently Used) to store expressions.
52
93
  # If an expression is not cached, the 'real storage' is consulted.
@@ -54,7 +95,9 @@ module OpenWFE
54
95
  # "expressionStorage.1"
55
96
  #
56
97
  class CacheExpressionStorage
57
- include ServiceMixin, OwfeServiceLocator
98
+ include ServiceMixin
99
+ include OwfeServiceLocator
100
+ include ExpressionStorageBase
58
101
 
59
102
  #
60
103
  # under 20 stored expressions, the unit tests for the
@@ -82,17 +125,7 @@ module OpenWFE
82
125
 
83
126
  @real_storage = nil
84
127
 
85
- #
86
- # expstorage observes expool :
87
-
88
- get_expression_pool.add_observer(:update) do |channel, fei, fe|
89
- ldebug { ":update for #{fei}" }
90
- self[fei] = fe
91
- end
92
- get_expression_pool.add_observer(:remove) do |channel, fei|
93
- ldebug { ":delete for #{fei}" }
94
- self.delete(fei)
95
- end
128
+ observe_expool
96
129
  end
97
130
 
98
131
  def [] (fei)
@@ -171,14 +204,6 @@ module OpenWFE
171
204
  get_real_storage.each(wfid_prefix, &block)
172
205
  end
173
206
 
174
- #
175
- # Displays a human-friendly view on this storage
176
- #
177
- def to_s
178
-
179
- expstorage_to_s(self)
180
- end
181
-
182
207
  protected
183
208
 
184
209
  #
@@ -201,35 +226,17 @@ module OpenWFE
201
226
  # No memory limit, puts everything in a Hash
202
227
  #
203
228
  class InMemoryExpressionStorage < Hash
204
- include ServiceMixin, OwfeServiceLocator
229
+ include ServiceMixin
230
+ include OwfeServiceLocator
231
+ include ExpressionStorageBase
205
232
 
206
233
  def initialize (service_name, application_context)
207
234
 
208
235
  service_init(service_name, application_context)
209
236
 
210
- #
211
- # expstorage observes expool :
212
-
213
- get_expression_pool.add_observer(:update) do |channel, fei, fe|
214
- #ldebug { ":update for #{fei}" }
215
- self[fei] = fe
216
- end
217
- get_expression_pool.add_observer(:remove) do |channel, fei|
218
- #ldebug { ":delete for #{fei}" }
219
- self.delete fei
220
- end
237
+ observe_expool
221
238
  end
222
239
 
223
- #def []= (fei, fe)
224
- # super fei.hash, fe
225
- #end
226
- #def [] (fei)
227
- # super fei.hash
228
- #end
229
- #def delete (fei)
230
- # super fei.hash
231
- #end
232
-
233
240
  alias :purge :clear
234
241
 
235
242
  #
@@ -258,37 +265,8 @@ module OpenWFE
258
265
  end
259
266
  end
260
267
 
261
- def to_s
262
- expstorage_to_s(self)
263
- end
264
-
265
268
  alias :real_each :each
266
269
 
267
270
  end
268
271
 
269
- #
270
- # a small help method for expression storages...
271
- #
272
- # TODO : put that in a module !
273
- #
274
- def expstorage_to_s (expstorage)
275
-
276
- s = "\n\n==== #{expstorage.class} ===="
277
-
278
- expstorage.each do |k, v|
279
- s << "\n"
280
- if v.kind_of?(RawExpression)
281
- s << "*raw"
282
- else
283
- s << " "
284
- end
285
- #s << v.to_s
286
- s << v.fei.to_s
287
- s << " key/value mismatch !" if k != v.fei
288
- end
289
- s << "\n==== . ====\n"
290
-
291
- s
292
- end
293
-
294
272
  end
@@ -45,7 +45,7 @@ require 'openwfe/omixins'
45
45
  require 'openwfe/rudefinitions'
46
46
  require 'openwfe/flowexpressionid'
47
47
  require 'openwfe/util/otime'
48
- require 'openwfe/storage/yamlextras'
48
+ require 'openwfe/storage/yamlcustom'
49
49
  require 'openwfe/expool/journal_replay'
50
50
 
51
51
 
@@ -39,7 +39,7 @@
39
39
  #
40
40
 
41
41
  require 'openwfe/utils'
42
- require 'openwfe/storage/yamlextras'
42
+ require 'openwfe/storage/yamlcustom'
43
43
  require 'openwfe/storage/yamlfilestorage'
44
44
 
45
45
  require 'openwfe/expressions/flowexpression'
@@ -59,12 +59,13 @@ module OpenWFE
59
59
  #
60
60
  class YamlFileExpressionStorage < YamlFileStorage
61
61
  include OwfeServiceLocator
62
+ include ExpressionStorageBase
62
63
 
63
64
  def initialize (service_name, application_context)
64
65
 
65
66
  super(service_name, application_context, '/expool')
66
67
 
67
- observe_expool()
68
+ observe_expool
68
69
  end
69
70
 
70
71
  #
@@ -146,24 +147,6 @@ module OpenWFE
146
147
 
147
148
  protected
148
149
 
149
- #
150
- # The actual binding of this storage as an observer of the
151
- # expression pool is done here.
152
- # It gives the opportunity to override this method with variants
153
- # (for example for delayed execution)
154
- #
155
- def observe_expool
156
-
157
- get_expression_pool.add_observer(:update) do |channel, fei, fe|
158
- #ldebug { ":update for #{fei.to_debug_s}" }
159
- self[fei] = fe
160
- end
161
- get_expression_pool.add_observer(:remove) do |channel, fei|
162
- #ldebug { ":remove for #{fei.to_debug_s}" }
163
- self.delete(fei)
164
- end
165
- end
166
-
167
150
  def compute_file_path (fei)
168
151
 
169
152
  return @basepath + "/engine_environment.yaml" \
@@ -198,30 +181,17 @@ module OpenWFE
198
181
  end
199
182
 
200
183
  #
201
- # With this extension of YmalFileExpressionStorage, persistence occurs
202
- # in a separate thread, for a snappier response.
184
+ # This mixin gathers all the logic for a threaded expression storage,
185
+ # one that doesn't immediately stores workitems (removes overriding
186
+ # operations).
187
+ # Using this threaded storage brings a very important perf benefit.
203
188
  #
204
- class ThreadedYamlFileExpressionStorage < YamlFileExpressionStorage
189
+ module ThreadedStorageMixin
205
190
 
206
- FREQ = "400" # milliseconds
191
+ THREADED_FREQ = "427" # milliseconds
207
192
  #
208
193
  # the frequency at which the event queue should be processed
209
194
 
210
- #
211
- # TODO : make this configurable (param in the apcontext ?)
212
-
213
- def initialize (service_name, application_context)
214
-
215
- super
216
-
217
- @events = {}
218
- @op_count = 0
219
-
220
- start_processing_thread()
221
- #
222
- # which sets @thread_id
223
- end
224
-
225
195
  #
226
196
  # Will take care of stopping the 'queue processing' thread.
227
197
  #
@@ -263,8 +233,11 @@ module OpenWFE
263
233
  #
264
234
  def start_processing_thread
265
235
 
266
- @thread_id = get_scheduler.schedule_every(FREQ) do
267
- process_queue()
236
+ @events = {}
237
+ @op_count = 0
238
+
239
+ @thread_id = get_scheduler.schedule_every THREADED_FREQ do
240
+ process_queue
268
241
  end
269
242
  end
270
243
 
@@ -352,4 +325,21 @@ module OpenWFE
352
325
  end
353
326
  end
354
327
  end
328
+
329
+ #
330
+ # With this extension of YmalFileExpressionStorage, persistence occurs
331
+ # in a separate thread, for a snappier response.
332
+ #
333
+ class ThreadedYamlFileExpressionStorage < YamlFileExpressionStorage
334
+ include ThreadedStorageMixin
335
+
336
+ def initialize (service_name, application_context)
337
+
338
+ super
339
+
340
+ start_processing_thread()
341
+ #
342
+ # which sets @thread_id
343
+ end
344
+ end
355
345
  end
@@ -62,13 +62,54 @@ module OpenWFE
62
62
  class FlowExpression < ObjectWithMeta
63
63
  include Contextual, Logging, OwfeServiceLocator
64
64
 
65
- attr_accessor \
66
- :fei,
67
- :parent_id,
68
- :environment_id,
69
- :attributes,
70
- :children,
71
- :apply_time
65
+ #
66
+ # The 'flow expression id' the unique identifier within a
67
+ # workflow instance for this expression instance.
68
+ #
69
+ attr_accessor :fei
70
+
71
+ #
72
+ # The 'flow expression id' of the parent expression.
73
+ # Will yield 'nil' if this expression is the root of its process
74
+ # instance.
75
+ #
76
+ attr_accessor :parent_id
77
+
78
+ #
79
+ # The 'flow expression id' of the environment this expression works
80
+ # with.
81
+ #
82
+ attr_accessor :environment_id
83
+
84
+ #
85
+ # The attributes of the expression, as found in the process definition.
86
+ #
87
+ # <participant ref='toto' timeout='1d10h' />
88
+ #
89
+ # The attributes will be ref => "toto" and timeout => "1d10h" (yes,
90
+ # 'attributes' contains a hash.
91
+ #
92
+ attr_accessor :attributes
93
+
94
+ #
95
+ # An array of 'flow expression id' instances. These are the ids of
96
+ # the expressions children to this one.
97
+ #
98
+ # <sequence>
99
+ # <participant ref="toto" />
100
+ # <participant ref="bert" />
101
+ # </sequence>
102
+ #
103
+ # The expression instance for 'sequence' will hold the feis of toto and
104
+ # bert in its children array.
105
+ #
106
+ attr_accessor :children
107
+
108
+ #
109
+ # When the FlowExpression instance is applied, this time stamp is set
110
+ # to the current date.
111
+ #
112
+ attr_accessor :apply_time
72
113
 
73
114
 
74
115
  def initialize (fei, parent_id, env_id, app_context, attributes)
@@ -30,8 +30,6 @@
30
30
  # POSSIBILITY OF SUCH DAMAGE.
31
31
  #++
32
32
  #
33
- # $Id: definitions.rb 2725 2006-06-02 13:26:32Z jmettraux $
34
- #
35
33
 
36
34
  #
37
35
  # "made in Japan"
@@ -48,13 +48,24 @@ module OpenWFE
48
48
  # The 'participant' concept is displayed as a module, so that
49
49
  # other pieces of code may easily 'mix it in'.
50
50
  #
51
+ # Participant extensions should at least provide a consume(workitem)
52
+ # method.
53
+ # As an option, it can provide a cancel(cancelitem) method.
54
+ #
55
+ # The engine will transmit instances of OpenWFE:WorkItem via the
56
+ # consume method.
57
+ #
58
+ # If there is a cancel method available and an OpenWFE::CancelItem instance
59
+ # is emitted (cancelling a process or part of it), it will be fed to
60
+ # the participant only via the cancel method.
61
+ #
62
+ # If there is no cancel method, the participant will not get notified
63
+ # of the cancellation.
64
+ #
51
65
  module Participant
52
66
 
53
67
  #
54
- # A participant will be receiving workitems via this method.
55
- # It may also receive cancelitems via this method.
56
- # If the participant provides a cancel(cancelitem) method, cancel
57
- # items will be fed to this cancel() and not to consume().
68
+ # A Participant will be receiving OpenWFE::WorkItem's via this method.
58
69
  #
59
70
  def consume (workitem)
60
71
 
@@ -57,7 +57,8 @@ module OpenWFE
57
57
  :participants
58
58
 
59
59
  def initialize (service_name, application_context)
60
- super(service_name, application_context)
60
+
61
+ super
61
62
 
62
63
  @participants = []
63
64
 
@@ -184,15 +185,8 @@ module OpenWFE
184
185
 
185
186
  workitem.participant_name = participant_name
186
187
 
187
- if (workitem.kind_of?(CancelItem) and
188
- participant.respond_to?(:cancel))
189
-
190
- participant.cancel(workitem)
191
-
192
- onotify :dispatch, :cancel, workitem
193
-
194
- return
195
- end
188
+ return cancel(participant, workitem) \
189
+ if workitem.is_a?(CancelItem)
196
190
 
197
191
  onotify :dispatch, :before_consume, workitem
198
192
 
@@ -209,6 +203,24 @@ module OpenWFE
209
203
  # and replies.
210
204
  #
211
205
  public :onotify
206
+
207
+ protected
208
+
209
+ #
210
+ # Will call the cancel method of the participant if it has
211
+ # one, or will simply discard the cancel item else.
212
+ #
213
+ def cancel (participant, cancel_item)
214
+
215
+ participant.cancel(cancel_item) \
216
+ if participant.respond_to?(:cancel)
217
+
218
+ onotify :dispatch, :cancel, cancel_item
219
+ #
220
+ # maybe it'd be better to specifically log that
221
+ # a participant has no cancel() method, but it's OK
222
+ # like that for now.
223
+ end
212
224
  end
213
225
 
214
226
  end
@@ -0,0 +1,113 @@
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 'yaml'
41
+
42
+
43
+ module OpenWFE
44
+
45
+ #
46
+ # reopening some classes in order to facilitate their
47
+ # yaml serialization
48
+ #
49
+
50
+ #
51
+ # opening for tuning yaml persistence
52
+ #
53
+ class FlowExpression
54
+
55
+ def to_yaml_properties
56
+
57
+ l = super()
58
+
59
+ l.delete("@application_context")
60
+
61
+ #l.delete("@timeout_job_id")
62
+ #l.delete("@scheduler_job_id")
63
+ # scheduler ids should not get persisted
64
+
65
+ l
66
+ end
67
+ end
68
+
69
+ #
70
+ # making sure that the FlowExpressionId is serialized as a unique String
71
+ #
72
+ class FlowExpressionId
73
+
74
+ yaml_as "tag:ruby.yaml.org,2002:#{self}"
75
+
76
+ #def to_yaml (opts={})
77
+ # @s = to_s
78
+ # super
79
+ #end
80
+ #def to_yaml_properties
81
+ # [ "@s" ]
82
+ #end
83
+
84
+ def to_yaml (opts={})
85
+ YAML::quick_emit(self.object_id, opts) do |out|
86
+ out.map(taguri) do |map|
87
+ map.add("s", to_s)
88
+ end
89
+ end
90
+ end
91
+
92
+ def FlowExpressionId.yaml_new (klass, tag, val)
93
+ s = val["s"]
94
+ begin
95
+ FlowExpressionId.to_fei(s)
96
+ rescue Exception => e
97
+ raise "failed to decode FlowExpressionId out of '#{s}'"
98
+ end
99
+ end
100
+ end
101
+
102
+ #
103
+ # opening for tuning yaml persistence
104
+ #
105
+ class XmlRawExpression
106
+ def to_yaml_properties
107
+ l = super()
108
+ l.delete("@raw_representation")
109
+ l
110
+ end
111
+ end
112
+ end
113
+
@@ -30,8 +30,6 @@
30
30
  # POSSIBILITY OF SUCH DAMAGE.
31
31
  #++
32
32
  #
33
- # $Id: otime.rb 3509 2006-10-21 12:00:52Z jmettraux $
34
- #
35
33
 
36
34
  #
37
35
  # "hecho en Costa Rica"
@@ -32,5 +32,5 @@
32
32
  #
33
33
 
34
34
  module OpenWFE
35
- OPENWFERU_VERSION = '0.9.14'
35
+ OPENWFERU_VERSION = '0.9.15'
36
36
  end
data/test/ft_26b_load.rb CHANGED
@@ -50,7 +50,6 @@ class FlowTest26b < Test::Unit::TestCase
50
50
  n = 1000
51
51
  n.times do |i|
52
52
  @engine.launch(LaunchItem.new(TestDefinition0))
53
-
54
53
  end
55
54
 
56
55
  puts "launched #{n} items"
@@ -76,11 +75,11 @@ class FlowTest26b < Test::Unit::TestCase
76
75
  end
77
76
 
78
77
  def join_until_idle ()
79
- storage = @engine.get_expression_storage
80
- while storage.size > 1
81
- sleep 1
82
- puts "storage.size:#{storage.size}"
83
- end
78
+ storage = @engine.get_expression_storage
79
+ while storage.size > 1
80
+ sleep 1
81
+ puts "storage.size:#{storage.size}"
82
+ end
84
83
  end
85
84
 
86
85
  end
data/test/obs_test.rb CHANGED
@@ -25,7 +25,7 @@ class ObsTest < Test::Unit::TestCase
25
25
  #end
26
26
 
27
27
  class Observed
28
- include OpenWFE::Observable
28
+ include OpenWFE::OwfeObservable
29
29
 
30
30
  attr_reader :observers
31
31
 
metadata CHANGED
@@ -1,10 +1,10 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.9.0
2
+ rubygems_version: 0.9.4
3
3
  specification_version: 1
4
4
  name: openwferu
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.9.14
7
- date: 2007-09-18 00:00:00 +09:00
6
+ version: 0.9.15
7
+ date: 2007-09-24 00:00:00 +09:00
8
8
  summary: an open source ruby workflow and bpm engine
9
9
  require_paths:
10
10
  - lib
@@ -122,6 +122,7 @@ files:
122
122
  - lib/openwfe/rest/restclient.rb
123
123
  - lib/openwfe/rest/worklistclient.rb
124
124
  - lib/openwfe/rest/xmlcodec.rb
125
+ - lib/openwfe/storage/yamlcustom.rb
125
126
  - lib/openwfe/storage/yamlfilestorage.rb
126
127
  - lib/openwfe/tools/flowtracer.rb
127
128
  - lib/openwfe/util/dollar.rb