openwferu 0.9.14 → 0.9.15

Sign up to get free protection for your applications and to get access to all the features.
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