openwferu-extras 0.9.15 → 0.9.16

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