openwferu-extras 0.9.15 → 0.9.16

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.
@@ -0,0 +1,100 @@
1
+ #
2
+ #--
3
+ # Copyright (c) 2007, Tomaso Tosolini and 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 Italy"
36
+ #
37
+ # Tomaso Tosolini
38
+ # John Mettraux at openwfe.org
39
+ #
40
+
41
+ require 'openwfe/engine/engine'
42
+ require 'openwfe/extras/expool/dbexpstorage'
43
+ require 'openwfe/extras/expool/dberrorjournal'
44
+
45
+
46
+ module OpenWFE::Extras
47
+
48
+ #
49
+ # A simple DbPersistedEngine, pure storage, no caching, no optimization.
50
+ # For tests only.
51
+ #
52
+ class DbPersistedEngine < Engine
53
+
54
+ protected
55
+
56
+ #
57
+ # Overrides the method already found in Engine with a persisted
58
+ # expression storage
59
+ #
60
+ def build_expression_storage
61
+
62
+ init_service S_EXPRESSION_STORAGE, DbExpressionStorage
63
+ end
64
+
65
+ #
66
+ # Uses a file persisted error journal.
67
+ #
68
+ def build_error_journal
69
+
70
+ init_service S_ERROR_JOURNAL, DbErrorJournal
71
+ end
72
+ end
73
+
74
+ #
75
+ # This OpenWFEru engine features database persistence (thanks to
76
+ # ActiveRecord), with a cache (for faster read operations) and a
77
+ # threaded wrapper (for buffering out unecessary write operations),
78
+ # hence it's fast (of course its's slower than in-memory storage.
79
+ #
80
+ class CachedDbPersistedEngine < DbPersistedEngine
81
+
82
+ protected
83
+
84
+ def build_expression_storage ()
85
+
86
+ @application_context[:expression_cache_size] ||= 1000
87
+
88
+ init_service(
89
+ S_EXPRESSION_STORAGE,
90
+ CacheExpressionStorage)
91
+
92
+ #init_service(
93
+ # S_EXPRESSION_STORAGE + ".1",
94
+ # DbExpressionStorage)
95
+ init_service(
96
+ S_EXPRESSION_STORAGE + ".1",
97
+ ThreadedDbExpressionStorage)
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,190 @@
1
+ #
2
+ #--
3
+ # Copyright (c) 2007, Tomaso Tosolini, 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 Italy"
36
+ #
37
+ # Tomaso Tosolini
38
+ # John Mettraux
39
+ #
40
+
41
+ require 'rubygems'
42
+
43
+ #require_gem 'activerecord'
44
+ gem 'activerecord'
45
+ require 'active_record'
46
+
47
+ require 'openwfe/omixins'
48
+ require 'openwfe/expool/errorjournal'
49
+
50
+
51
+ module OpenWFE::Extras
52
+
53
+ #
54
+ # A migration for creating/dropping the "process errors" table, the
55
+ # content of this table makes up for an error journal.
56
+ #
57
+ # There is one record per process error, the log journal can be
58
+ # easily rebuilt by doing find_all_by_wfid().
59
+ #
60
+ class ProcessErrorTables < ActiveRecord::Migration
61
+
62
+ def self.up
63
+
64
+ create_table :process_errors do |t|
65
+
66
+ t.column :wfid, :string, :null => false
67
+ t.column :svalue, :text, :null => false
68
+ # 'value' could be reserved, using 'svalue' instead
69
+ # It stands for 'serialized value'.
70
+ end
71
+ add_index :process_errors, :wfid
72
+ end
73
+
74
+ def self.down
75
+
76
+ drop_table :process_errors
77
+ end
78
+ end
79
+
80
+ #
81
+ # The active record for process errors. Not much to say.
82
+ #
83
+ class ProcessError < ActiveRecord::Base
84
+
85
+ serialize :svalue
86
+
87
+ #
88
+ # Returns the OpenWFE process error, as serialized
89
+ # (but takes care of setting its db_id)
90
+ #
91
+ def owfe_error
92
+
93
+ result = svalue
94
+ class << result
95
+ attr_accessor :db_id
96
+ end
97
+ result.db_id = id
98
+ result
99
+ end
100
+ end
101
+
102
+ #
103
+ # A database backed error journal.
104
+ #
105
+ # (no synchronization needed it seems)
106
+ #
107
+ class DbErrorJournal < OpenWFE::ErrorJournal
108
+ include FeiMixin
109
+
110
+ def initialize (service_name, application_context)
111
+
112
+ require 'openwfe/storage/yamlcustom'
113
+ # making sure this file has been required at this point
114
+ # this yamlcustom thing prevents the whole OpenWFE ecosystem
115
+ # to get serialized :)
116
+
117
+ super
118
+ end
119
+
120
+ #
121
+ # Returns the error log for a given workflow/process instance,
122
+ # the older error first.
123
+ #
124
+ def get_error_log (wfid)
125
+
126
+ wfid = to_wfid wfid
127
+ errors = ProcessError.find_all_by_wfid wfid, :order => "id asc"
128
+ errors.collect { |e| e.owfe_error }
129
+ end
130
+
131
+ #
132
+ # Erases all the errors for one given workflow/process instance.
133
+ #
134
+ def remove_error_log (wfid)
135
+
136
+ ProcessError.destroy_all ["wfid = ?", wfid]
137
+ end
138
+
139
+ #
140
+ # Returns a map wfid => error log, ie returns 1 error log for
141
+ # each workflow/process instance that encountered an error.
142
+ #
143
+ def get_error_logs
144
+
145
+ errors = ProcessError.find :all
146
+
147
+ result = {}
148
+
149
+ errors.each do |e|
150
+ (result[e.wfid] ||= []) << e.owfe_error
151
+ end
152
+
153
+ result
154
+ end
155
+
156
+ #
157
+ # Removes a set of errors. This is used by the expool when
158
+ # resuming a previously broken process instance.
159
+ #
160
+ def remove_errors (wfid, errors)
161
+
162
+ errors = Array(errors)
163
+
164
+ errors.each do |e|
165
+ ProcessError.delete e.db_id
166
+ end
167
+ end
168
+
169
+ protected
170
+
171
+ #
172
+ # This is the inner method used by the error journal to
173
+ # record a process error (instance of OpenWFE::ProcessError)
174
+ # that it observed in the expression pool.
175
+ #
176
+ # This method will throw an exception in case of trouble with
177
+ # the database.
178
+ #
179
+ def record_error (process_error)
180
+
181
+ e = ProcessError.new
182
+
183
+ e.wfid = process_error.wfid
184
+ e.svalue = process_error
185
+
186
+ e.save!
187
+ end
188
+ end
189
+ end
190
+
@@ -0,0 +1,267 @@
1
+ #
2
+ #--
3
+ # Copyright (c) 2007, Tomaso Tosolini, 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 Italy"
36
+ #
37
+ # Tomaso Tosolini
38
+ # John Mettraux
39
+ #
40
+
41
+ require 'rubygems'
42
+
43
+ #require_gem 'activerecord'
44
+ gem 'activerecord'
45
+ require 'active_record'
46
+
47
+ require 'monitor'
48
+
49
+
50
+ require 'openwfe/service'
51
+ require 'openwfe/rudefinitions'
52
+ require 'openwfe/expool/expstorage'
53
+ require 'openwfe/expool/threadedexpstorage'
54
+
55
+
56
+ module OpenWFE::Extras
57
+
58
+ #
59
+ # A migration for creating/dropping the "expressions" table.
60
+ # 'expressions' are atomic pieces of running process instances.
61
+ #
62
+ class ExpressionTables < ActiveRecord::Migration
63
+
64
+ def self.up
65
+
66
+ create_table :expressions do |t|
67
+
68
+ t.column :fei, :string, :null => false
69
+ t.column :wfid, :string, :null => false
70
+ #t.column :wfname, :string, :null => false
71
+ t.column :exp_class, :string, :null => false
72
+ t.column :svalue, :text, :null => false
73
+ # 'value' could be reserved, using 'svalue' instead
74
+ end
75
+ add_index :expressions, :fei
76
+ add_index :expressions, :wfid
77
+ #add_index :expressions, :wfname
78
+ add_index :expressions, :exp_class
79
+ end
80
+
81
+ def self.down
82
+
83
+ drop_table :expressions
84
+ end
85
+ end
86
+
87
+ #
88
+ # The ActiveRecord wrapper for an OpenWFEru FlowExpression instance.
89
+ #
90
+ class Expression < ActiveRecord::Base
91
+
92
+ serialize :svalue
93
+ end
94
+
95
+ #
96
+ # Storing OpenWFE flow expressions in a database.
97
+ #
98
+ class DbExpressionStorage
99
+ include MonitorMixin
100
+ include OpenWFE::ServiceMixin
101
+ include OpenWFE::OwfeServiceLocator
102
+ include OpenWFE::ExpressionStorageBase
103
+
104
+ #
105
+ # Constructor.
106
+ #
107
+ def initialize (service_name, application_context)
108
+
109
+ require 'openwfe/storage/yamlcustom'
110
+ # making sure this file has been required at this point
111
+ # this yamlcustom thing prevents the whole OpenWFE ecosystem
112
+ # to get serialized :)
113
+
114
+ super() # absolutely necessary as we include MonitorMixin
115
+ service_init service_name, application_context
116
+
117
+ observe_expool
118
+ end
119
+
120
+ #
121
+ # Stores an expression.
122
+ #
123
+ def []= (fei, flow_expression)
124
+
125
+ ldebug { "[]= storing #{fei.to_s}" }
126
+
127
+ synchronize do
128
+
129
+ e = Expression.find_by_fei fei.to_s
130
+
131
+ unless e
132
+ e = Expression.new
133
+ e.fei = fei.to_s
134
+ e.wfid = fei.wfid
135
+ #e.wfname = fei.wfname
136
+ end
137
+
138
+ e.exp_class = flow_expression.class.name
139
+ e.svalue = flow_expression
140
+
141
+ e.save!
142
+ end
143
+ end
144
+
145
+ #
146
+ # Retrieves a flow expression.
147
+ #
148
+ def [] (fei)
149
+
150
+ e = Expression.find_by_fei fei.to_s
151
+ return nil unless e
152
+
153
+ as_owfe_expression e
154
+ end
155
+
156
+ #
157
+ # Returns true if there is a FlowExpression stored with the given id.
158
+ #
159
+ def has_key? (fei)
160
+
161
+ (Expression.find_by_fei(fei.to_s) != nil)
162
+ end
163
+
164
+ #
165
+ # Deletes a flow expression.
166
+ #
167
+ def delete (fei)
168
+
169
+ synchronize do
170
+ Expression.delete_all ["fei = ?", fei.to_s]
171
+ end
172
+ end
173
+
174
+ #
175
+ # Returns the count of expressions currently stored.
176
+ #
177
+ def size
178
+
179
+ Expression.count
180
+ end
181
+
182
+ alias :length :size
183
+
184
+ #
185
+ # Danger ! Will remove all the expressions in the database.
186
+ #
187
+ def purge
188
+
189
+ Expression.delete_all
190
+ end
191
+
192
+ #
193
+ # Given an expression class (Schedulable or ParticipantExpression for
194
+ # example), calls the passed block for each expression of that class.
195
+ #
196
+ def each_of_kind (kind, &block)
197
+
198
+ classes = get_expression_map.get_expression_classes(kind)
199
+ classes = classes.collect { |c| c.name }
200
+
201
+ exps = Expression.find_all_by_exp_class(classes)
202
+
203
+ exp_each exps, &block
204
+ end
205
+
206
+ #
207
+ # Calls the block for each expression stored. If a wfid prefix is
208
+ # passed, only the expressions whose workflow instance id begins
209
+ # with it will be iterated over.
210
+ #
211
+ def each (wfid_prefix=nil, &block)
212
+
213
+ params = {}
214
+
215
+ params[:conditions] = [ "wfid LIKE ?", "#{wfid_prefix}%" ] \
216
+ if wfid_prefix
217
+
218
+ exps = Expression.find(:all, params)
219
+
220
+ exp_each exps, &block
221
+ end
222
+
223
+ alias :real_each :each
224
+
225
+ protected
226
+
227
+ #
228
+ # Used by each() and each_of_kind().
229
+ #
230
+ def exp_each (expressions, &block)
231
+
232
+ expressions.each do |exp|
233
+ fexp = as_owfe_expression(exp)
234
+ block.call fexp.fei, fexp
235
+ end
236
+ end
237
+
238
+ #
239
+ # Extracts the OpenWFE FlowExpression instance from the
240
+ # active record and makes sure its application_context is set.
241
+ #
242
+ def as_owfe_expression (record)
243
+
244
+ fe = record.svalue
245
+ fe.application_context = @application_context
246
+ fe
247
+ end
248
+ end
249
+
250
+ #
251
+ # A DbExpressionStorage that does less work, for more performance,
252
+ # thanks to the ThreadedStorageMixin.
253
+ #
254
+ class ThreadedDbExpressionStorage < DbExpressionStorage
255
+ include OpenWFE::ThreadedStorageMixin
256
+
257
+ def initialize (service_name, application_context)
258
+
259
+ super
260
+
261
+ start_processing_thread()
262
+ #
263
+ # which sets @thread_id
264
+ end
265
+ end
266
+ end
267
+
@@ -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"
@@ -116,7 +114,7 @@ module Extras
116
114
 
117
115
  o = decode_object(msg)
118
116
 
119
- handle_object(o)
117
+ handle_item o
120
118
 
121
119
  msg.delete
122
120