ruote 0.9.18
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 +24 -0
- data/bin/validate-workflow.rb +89 -0
- data/examples/about_state.rb +81 -0
- data/examples/bigflow.rb +19 -0
- data/examples/csv_weather.rb +23 -0
- data/examples/engine_template.rb +247 -0
- data/examples/flowtracing.rb +24 -0
- data/examples/homeworkreview.rb +68 -0
- data/examples/kotoba.rb +22 -0
- data/examples/mano_tracker.rb +172 -0
- data/examples/openwferu.rb +58 -0
- data/examples/quotereporter.rb +157 -0
- data/examples/scheduler_cron_usage.rb +48 -0
- data/examples/scheduler_usage.rb +56 -0
- data/lib/openwfe.rb +41 -0
- data/lib/openwfe/contextual.rb +111 -0
- data/lib/openwfe/def.rb +46 -0
- data/lib/openwfe/engine.rb +37 -0
- data/lib/openwfe/engine/engine.rb +756 -0
- data/lib/openwfe/engine/expool_methods.rb +172 -0
- data/lib/openwfe/engine/file_persisted_engine.rb +105 -0
- data/lib/openwfe/engine/participant_methods.rb +133 -0
- data/lib/openwfe/engine/status_methods.rb +353 -0
- data/lib/openwfe/engine/update_exp_methods.rb +112 -0
- data/lib/openwfe/exceptions.rb +51 -0
- data/lib/openwfe/expool/errorjournal.rb +476 -0
- data/lib/openwfe/expool/expressionpool.rb +1144 -0
- data/lib/openwfe/expool/expstorage.rb +403 -0
- data/lib/openwfe/expool/history.rb +174 -0
- data/lib/openwfe/expool/journal.rb +224 -0
- data/lib/openwfe/expool/journal_replay.rb +321 -0
- data/lib/openwfe/expool/parser.rb +242 -0
- data/lib/openwfe/expool/representation.rb +121 -0
- data/lib/openwfe/expool/threadedexpstorage.rb +188 -0
- data/lib/openwfe/expool/wfidgen.rb +388 -0
- data/lib/openwfe/expool/yamlexpstorage.rb +224 -0
- data/lib/openwfe/expressions/condition.rb +244 -0
- data/lib/openwfe/expressions/environment.rb +246 -0
- data/lib/openwfe/expressions/expressionmap.rb +258 -0
- data/lib/openwfe/expressions/fe_cancel.rb +109 -0
- data/lib/openwfe/expressions/fe_command.rb +241 -0
- data/lib/openwfe/expressions/fe_concurrence.rb +662 -0
- data/lib/openwfe/expressions/fe_cron.rb +259 -0
- data/lib/openwfe/expressions/fe_cursor.rb +259 -0
- data/lib/openwfe/expressions/fe_define.rb +192 -0
- data/lib/openwfe/expressions/fe_do.rb +168 -0
- data/lib/openwfe/expressions/fe_equals.rb +291 -0
- data/lib/openwfe/expressions/fe_filter.rb +129 -0
- data/lib/openwfe/expressions/fe_filter_definition.rb +168 -0
- data/lib/openwfe/expressions/fe_fqv.rb +250 -0
- data/lib/openwfe/expressions/fe_if.rb +303 -0
- data/lib/openwfe/expressions/fe_iterator.rb +145 -0
- data/lib/openwfe/expressions/fe_listen.rb +371 -0
- data/lib/openwfe/expressions/fe_losfor.rb +111 -0
- data/lib/openwfe/expressions/fe_misc.rb +421 -0
- data/lib/openwfe/expressions/fe_participant.rb +269 -0
- data/lib/openwfe/expressions/fe_reserve.rb +212 -0
- data/lib/openwfe/expressions/fe_save.rb +274 -0
- data/lib/openwfe/expressions/fe_sequence.rb +117 -0
- data/lib/openwfe/expressions/fe_set.rb +139 -0
- data/lib/openwfe/expressions/fe_sleep.rb +166 -0
- data/lib/openwfe/expressions/fe_step.rb +159 -0
- data/lib/openwfe/expressions/fe_subprocess.rb +168 -0
- data/lib/openwfe/expressions/fe_timeout.rb +127 -0
- data/lib/openwfe/expressions/fe_wait.rb +78 -0
- data/lib/openwfe/expressions/fe_when.rb +142 -0
- data/lib/openwfe/expressions/filter.rb +104 -0
- data/lib/openwfe/expressions/flowexpression.rb +847 -0
- data/lib/openwfe/expressions/iterator.rb +221 -0
- data/lib/openwfe/expressions/merge.rb +84 -0
- data/lib/openwfe/expressions/raw.rb +547 -0
- data/lib/openwfe/expressions/rprocdef.rb +375 -0
- data/lib/openwfe/expressions/time.rb +333 -0
- data/lib/openwfe/expressions/timeout.rb +178 -0
- data/lib/openwfe/expressions/value.rb +126 -0
- data/lib/openwfe/filterdef.rb +259 -0
- data/lib/openwfe/flowexpressionid.rb +357 -0
- data/lib/openwfe/listeners/listener.rb +97 -0
- data/lib/openwfe/listeners/listeners.rb +139 -0
- data/lib/openwfe/listeners/socketlisteners.rb +272 -0
- data/lib/openwfe/logging.rb +122 -0
- data/lib/openwfe/omixins.rb +95 -0
- data/lib/openwfe/orest/controlclient.rb +119 -0
- data/lib/openwfe/orest/definitions.rb +113 -0
- data/lib/openwfe/orest/exception.rb +60 -0
- data/lib/openwfe/orest/oldrestservlet.rb +279 -0
- data/lib/openwfe/orest/osocket.rb +148 -0
- data/lib/openwfe/orest/restclient.rb +176 -0
- data/lib/openwfe/orest/workitem.rb +206 -0
- data/lib/openwfe/orest/worklistclient.rb +272 -0
- data/lib/openwfe/orest/xmlcodec.rb +670 -0
- data/lib/openwfe/participants.rb +38 -0
- data/lib/openwfe/participants/enoparticipants.rb +230 -0
- data/lib/openwfe/participants/participant.rb +141 -0
- data/lib/openwfe/participants/participantmap.rb +249 -0
- data/lib/openwfe/participants/participants.rb +407 -0
- data/lib/openwfe/participants/soapparticipants.rb +135 -0
- data/lib/openwfe/participants/socketparticipants.rb +202 -0
- data/lib/openwfe/participants/storeparticipants.rb +254 -0
- data/lib/openwfe/rudefinitions.rb +130 -0
- data/lib/openwfe/service.rb +103 -0
- data/lib/openwfe/storage/yamlcustom.rb +106 -0
- data/lib/openwfe/storage/yamlfilestorage.rb +245 -0
- data/lib/openwfe/tools/flowtracer.rb +81 -0
- data/lib/openwfe/util/dollar.rb +217 -0
- data/lib/openwfe/util/irb.rb +86 -0
- data/lib/openwfe/util/observable.rb +144 -0
- data/lib/openwfe/util/ometa.rb +62 -0
- data/lib/openwfe/util/workqueue.rb +124 -0
- data/lib/openwfe/util/xml.rb +418 -0
- data/lib/openwfe/utils.rb +554 -0
- data/lib/openwfe/version.rb +37 -0
- data/lib/openwfe/workitem.rb +499 -0
- data/lib/openwfe/worklist/oldrest.rb +244 -0
- data/lib/openwfe/worklist/storelocks.rb +293 -0
- data/lib/openwfe/worklist/storeparticipant.rb +44 -0
- data/lib/openwfe/worklist/worklist.rb +297 -0
- data/test/README.txt +27 -0
- data/test/back_0916_test.rb +111 -0
- data/test/bm/bm_1_xml_vs_prog.rb +56 -0
- data/test/bm/bm_2_step.rb +109 -0
- data/test/bm/ft_0f_5ms.rb +35 -0
- data/test/bm/ft_26_load.rb +210 -0
- data/test/bm/ft_26b_load.rb +86 -0
- data/test/bm/ft_26c_load.rb +97 -0
- data/test/bm/ft_26d_load.rb +97 -0
- data/test/bm/ft_recu.rb +71 -0
- data/test/clone_test.rb +122 -0
- data/test/concurrence_test.rb +77 -0
- data/test/condition_test.rb +155 -0
- data/test/console_test.rb +12 -0
- data/test/cron_ltest.rb +15 -0
- data/test/description_test.rb +87 -0
- data/test/eno_test.rb +76 -0
- data/test/expmap_test.rb +54 -0
- data/test/expool_20031219_0916.tgz +0 -0
- data/test/fe_lookup_att_test.rb +62 -0
- data/test/fei_test.rb +181 -0
- data/test/file_persisted_engine_test.rb +64 -0
- data/test/file_persistence_test.rb +134 -0
- data/test/filep_cancel_test.rb +123 -0
- data/test/filter_test.rb +109 -0
- data/test/flowtestbase.rb +351 -0
- data/test/ft_0.rb +68 -0
- data/test/ft_0b_sequence.rb +36 -0
- data/test/ft_0c_testname.rb +33 -0
- data/test/ft_0d_participant.rb +30 -0
- data/test/ft_0e_multibody.rb +34 -0
- data/test/ft_10_loop.rb +134 -0
- data/test/ft_11_ppd.rb +415 -0
- data/test/ft_11b_ppd.rb +54 -0
- data/test/ft_12_blockparticipant.rb +97 -0
- data/test/ft_13_eno.rb +52 -0
- data/test/ft_14_subprocess.rb +88 -0
- data/test/ft_14b_subprocess.rb +192 -0
- data/test/ft_14c_subprocess.rb +68 -0
- data/test/ft_15_iterator.rb +216 -0
- data/test/ft_15b_iterator.rb +74 -0
- data/test/ft_16_fqv.rb +73 -0
- data/test/ft_17_condition.rb +84 -0
- data/test/ft_18_pname.rb +56 -0
- data/test/ft_1_unset.rb +175 -0
- data/test/ft_1b_unset.rb +39 -0
- data/test/ft_20_cron.rb +53 -0
- data/test/ft_21_cron.rb +87 -0
- data/test/ft_21b_cron_pause.rb +82 -0
- data/test/ft_22_history.rb +74 -0
- data/test/ft_23_when.rb +77 -0
- data/test/ft_23b_when.rb +70 -0
- data/test/ft_23c_wait.rb +80 -0
- data/test/ft_23d_cww.rb +58 -0
- data/test/ft_24_def.rb +44 -0
- data/test/ft_25_cancel.rb +89 -0
- data/test/ft_27_getflowpos.rb +147 -0
- data/test/ft_28_fileparticipant.rb +63 -0
- data/test/ft_29_httprb.rb +106 -0
- data/test/ft_2_concurrence.rb +135 -0
- data/test/ft_2b_concurrence.rb +188 -0
- data/test/ft_2c_concurrence.rb +64 -0
- data/test/ft_30_socketlistener.rb +203 -0
- data/test/ft_31_flowname.rb +40 -0
- data/test/ft_32_journal.rb +91 -0
- data/test/ft_32c_journal.rb +102 -0
- data/test/ft_32d_journal.rb +84 -0
- data/test/ft_33_description.rb +107 -0
- data/test/ft_34_cancelwfid.rb +80 -0
- data/test/ft_35_localdefs.rb +75 -0
- data/test/ft_36_subprocids.rb +97 -0
- data/test/ft_37_pnames.rb +70 -0
- data/test/ft_38_tag.rb +127 -0
- data/test/ft_38b_tag.rb +161 -0
- data/test/ft_38c_tag.rb +100 -0
- data/test/ft_39_reserve.rb +63 -0
- data/test/ft_39b_reserve.rb +84 -0
- data/test/ft_3_equals.rb +170 -0
- data/test/ft_3b_lookup_vf.rb +83 -0
- data/test/ft_40_defined.rb +61 -0
- data/test/ft_41_case.rb +110 -0
- data/test/ft_42_environments.rb +75 -0
- data/test/ft_43_pat10.rb +85 -0
- data/test/ft_44_save.rb +70 -0
- data/test/ft_44b_restore.rb +212 -0
- data/test/ft_45_citerator.rb +214 -0
- data/test/ft_46_pparams.rb +62 -0
- data/test/ft_47_filter.rb +160 -0
- data/test/ft_48_fe_filter.rb +88 -0
- data/test/ft_49_condition.rb +126 -0
- data/test/ft_4_misc.rb +237 -0
- data/test/ft_50_xml_attribute.rb +155 -0
- data/test/ft_51_stack.rb +55 -0
- data/test/ft_52_obs_participant.rb +123 -0
- data/test/ft_53_null_noop_participant.rb +62 -0
- data/test/ft_54_listen.rb +288 -0
- data/test/ft_54b_listen.rb +66 -0
- data/test/ft_54c_listen.rb +99 -0
- data/test/ft_55_ptimeout.rb +59 -0
- data/test/ft_56_timeout.rb +59 -0
- data/test/ft_57_a.rb +145 -0
- data/test/ft_58_ejournal.rb +151 -0
- data/test/ft_59_ps.rb +150 -0
- data/test/ft_59b_ps_for_pat.rb +58 -0
- data/test/ft_5_time.rb +118 -0
- data/test/ft_60_ecancel.rb +161 -0
- data/test/ft_61_elsub.rb +51 -0
- data/test/ft_62_procparticipant.rb +71 -0
- data/test/ft_63_pause.rb +124 -0
- data/test/ft_64_alias.rb +102 -0
- data/test/ft_64_clone.rb +69 -0
- data/test/ft_65_stringlaunch.rb +59 -0
- data/test/ft_66_subforget.rb +70 -0
- data/test/ft_67_schedlaunch.rb +116 -0
- data/test/ft_68_ifparticipant.rb +70 -0
- data/test/ft_69_cancelmissing.rb +51 -0
- data/test/ft_6_lambda.rb +64 -0
- data/test/ft_70_lookupvar.rb +55 -0
- data/test/ft_71_log.rb +60 -0
- data/test/ft_72_lookup_processes.rb +76 -0
- data/test/ft_73_cancel_sub.rb +139 -0
- data/test/ft_74_block_and_workitem_dup.rb +63 -0
- data/test/ft_75_ruby_attributes.rb +87 -0
- data/test/ft_76_merge_isolate.rb +88 -0
- data/test/ft_77_segments.rb +35 -0
- data/test/ft_78_eval.rb +150 -0
- data/test/ft_79_tticket.rb +187 -0
- data/test/ft_79b_tticket.rb +172 -0
- data/test/ft_79c_outcome.rb +56 -0
- data/test/ft_7_lose.rb +104 -0
- data/test/ft_7b_lose.rb +78 -0
- data/test/ft_80_spname.rb +91 -0
- data/test/ft_81_exp.rb +60 -0
- data/test/ft_82_trecu.rb +46 -0
- data/test/ft_83_badpause.rb +58 -0
- data/test/ft_84_updateexp.rb +198 -0
- data/test/ft_85_dolhash.rb +43 -0
- data/test/ft_86_dollar_fv.rb +68 -0
- data/test/ft_87_define.rb +74 -0
- data/test/ft_8_forget.rb +44 -0
- data/test/ft_9_cursor.rb +145 -0
- data/test/ft_9b_cursor.rb +105 -0
- data/test/ft_tests.rb +124 -0
- data/test/hash_test.rb +75 -0
- data/test/hparticipant_test.rb +164 -0
- data/test/lookup_att_test.rb +90 -0
- data/test/lookup_vf_test.rb +94 -0
- data/test/misc_test.rb +90 -0
- data/test/nut_0_irb.rb +20 -0
- data/test/obs_test.rb +142 -0
- data/test/orest_test.rb +251 -0
- data/test/param_test.rb +290 -0
- data/test/participant_test.rb +101 -0
- data/test/pending.rb +23 -0
- data/test/ps_representation.rb +133 -0
- data/test/rake_ltest.rb +38 -0
- data/test/rake_qtest.rb +68 -0
- data/test/raw_prog_test.rb +412 -0
- data/test/restart_cron_test.rb +136 -0
- data/test/restart_paused_test.rb +98 -0
- data/test/restart_sleep_test.rb +140 -0
- data/test/restart_tests.rb +18 -0
- data/test/restart_when_test.rb +112 -0
- data/test/ruby_procdef_test.rb +132 -0
- data/test/rutest_utils.rb +63 -0
- data/test/sec_test.rb +205 -0
- data/test/slock_test.rb +80 -0
- data/test/storage_test.rb +44 -0
- data/test/test.rb +3 -0
- data/test/timeout_test.rb +105 -0
- data/test/util_xml_test.rb +112 -0
- data/test/wfid_test.rb +175 -0
- data/test/wi_test.rb +75 -0
- metadata +433 -0
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
#
|
|
2
|
+
#--
|
|
3
|
+
# Copyright (c) 2007-2008, 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 'thread'
|
|
41
|
+
|
|
42
|
+
require 'rufus/mnemo'
|
|
43
|
+
|
|
44
|
+
require 'openwfe/service'
|
|
45
|
+
require 'openwfe/rudefinitions'
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
module OpenWFE
|
|
49
|
+
|
|
50
|
+
#
|
|
51
|
+
# This default wfid generator outputs a long integer as a String.
|
|
52
|
+
# The last given id (in order to prevent clocks being put back) is
|
|
53
|
+
# stored in the work directory in the file "wfidgen.last"
|
|
54
|
+
#
|
|
55
|
+
class DefaultWfidGenerator < Service
|
|
56
|
+
|
|
57
|
+
def initialize (service_name, application_context)
|
|
58
|
+
|
|
59
|
+
super
|
|
60
|
+
|
|
61
|
+
@last = -1
|
|
62
|
+
@mutex = Mutex.new
|
|
63
|
+
|
|
64
|
+
@last_fn = get_work_directory + '/wfidgen.last'
|
|
65
|
+
|
|
66
|
+
load_last()
|
|
67
|
+
|
|
68
|
+
ensure_last_f
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
#
|
|
72
|
+
# Returns a new workflow instance id
|
|
73
|
+
#
|
|
74
|
+
# The launchitem parameter is not used by this generator.
|
|
75
|
+
#
|
|
76
|
+
def generate (launchitem=nil)
|
|
77
|
+
|
|
78
|
+
wfid = nil
|
|
79
|
+
|
|
80
|
+
@mutex.synchronize do
|
|
81
|
+
wfid = now
|
|
82
|
+
wfid = @last + 1 if wfid <= @last
|
|
83
|
+
@last = wfid
|
|
84
|
+
save_last
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
to_string(wfid)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
#
|
|
91
|
+
# The actual job of turning the numeric result into a String.
|
|
92
|
+
# This method is overriden in extension of this class.
|
|
93
|
+
#
|
|
94
|
+
def to_string (numeric_id)
|
|
95
|
+
|
|
96
|
+
numeric_id.to_s
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
#
|
|
100
|
+
# Is a simple call to OpenWFE::split_wfid()
|
|
101
|
+
#
|
|
102
|
+
def split_wfid (wfid)
|
|
103
|
+
|
|
104
|
+
OpenWFE.split_wfid(wfid)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
#
|
|
108
|
+
# This method is called by OpenWFE::split_wfid() when it has detected
|
|
109
|
+
# a wfid following this 'defaut' scheme.
|
|
110
|
+
#
|
|
111
|
+
def self.split_wfid (wfid)
|
|
112
|
+
|
|
113
|
+
r = []
|
|
114
|
+
0.upto(wfid.length-1) do |i|
|
|
115
|
+
r << wfid[i, 1]
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
r
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
#
|
|
122
|
+
# Stops this service.
|
|
123
|
+
# In this particular implementation, makes sure the "wfidgen.last"
|
|
124
|
+
# file is closed.
|
|
125
|
+
#
|
|
126
|
+
def stop
|
|
127
|
+
|
|
128
|
+
#linfo { "stop() stopping '#{@service_name}'" }
|
|
129
|
+
@last_f.close if @last_f
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
protected
|
|
133
|
+
|
|
134
|
+
def ensure_last_f
|
|
135
|
+
if (not @last_f) or @last_f.closed?
|
|
136
|
+
begin
|
|
137
|
+
@last_f = File.open(@last_fn, "w+")
|
|
138
|
+
rescue Exception => e
|
|
139
|
+
lwarn do
|
|
140
|
+
"new() failed to open #{@last_fn}, "+
|
|
141
|
+
"continuing anyway...\n"+
|
|
142
|
+
OpenWFE::exception_to_s(e)
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def now
|
|
149
|
+
wfid = Time.now.to_f * 1000 * 10
|
|
150
|
+
wfid.to_i
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def save_last
|
|
154
|
+
return unless @last_f
|
|
155
|
+
ensure_last_f()
|
|
156
|
+
@last_f.pos = 0
|
|
157
|
+
@last_f.puts @last
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def load_last
|
|
161
|
+
@mutex.synchronize do
|
|
162
|
+
|
|
163
|
+
if File.exist?(@last_fn)
|
|
164
|
+
begin
|
|
165
|
+
s = File.open(@last_fn, "r") do |f|
|
|
166
|
+
f.readline
|
|
167
|
+
end
|
|
168
|
+
@last = Integer(s)
|
|
169
|
+
#puts @last
|
|
170
|
+
rescue Exception => e
|
|
171
|
+
#puts
|
|
172
|
+
#puts e.to_s
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
n = now
|
|
177
|
+
|
|
178
|
+
@last = n if (not @last) or (@last < n)
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
#
|
|
184
|
+
# This extension of DefaultWfidGenerator produces ids like
|
|
185
|
+
# "20070318-jonowoguya" or "20071224-jesoshimoha" that are a bit
|
|
186
|
+
# easier to grasp than full integer wfids.
|
|
187
|
+
#
|
|
188
|
+
# Now relying on the 'rufus-mnemo' gem.
|
|
189
|
+
#
|
|
190
|
+
class KotobaWfidGenerator < DefaultWfidGenerator
|
|
191
|
+
|
|
192
|
+
#
|
|
193
|
+
# Overrides the to_string() method of the DefaultWfidGenerator,
|
|
194
|
+
#
|
|
195
|
+
def to_string (numeric_id)
|
|
196
|
+
|
|
197
|
+
self.class.to_string(numeric_id)
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
#
|
|
201
|
+
# That's here that the numeric wfid gets turned into a 'kotoba'.
|
|
202
|
+
# A static method easily accessible by any.
|
|
203
|
+
#
|
|
204
|
+
def self.to_string (numeric_id)
|
|
205
|
+
|
|
206
|
+
i = numeric_id % (10 * 1000 * 60 * 60 * 24)
|
|
207
|
+
t = Time.now.gmtime
|
|
208
|
+
|
|
209
|
+
s = sprintf "%4d%02d%02d", t.year, t.month, t.day
|
|
210
|
+
s << "-"
|
|
211
|
+
s << Rufus::Mnemo::from_integer(i)
|
|
212
|
+
s
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
#
|
|
216
|
+
# This method is called by OpenWFE::split_wfid() when it has detected
|
|
217
|
+
# a wfid following the 'kotoba' scheme.
|
|
218
|
+
# Returns the 'kotoba' wfid split into its syllables
|
|
219
|
+
#
|
|
220
|
+
def self.split_wfid (wfid)
|
|
221
|
+
|
|
222
|
+
Rufus::Mnemo::split(wfid[9..-1])
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
#
|
|
226
|
+
# Turns a KotobaWfidGenerator produced wfid into a UTC date.
|
|
227
|
+
#
|
|
228
|
+
def self.to_time (wfid)
|
|
229
|
+
|
|
230
|
+
year = wfid[0, 4]
|
|
231
|
+
month = wfid[4, 2]
|
|
232
|
+
day = wfid[6, 2]
|
|
233
|
+
|
|
234
|
+
s = wfid[9..-1]
|
|
235
|
+
|
|
236
|
+
i = Rufus::Mnemo::to_integer(s)
|
|
237
|
+
|
|
238
|
+
hour = (i / (10000 * 60 * 60)) % 24
|
|
239
|
+
min = (i / (10000 * 60)) % 60
|
|
240
|
+
sec = (i / 10000) % 60
|
|
241
|
+
usec = (i * 100) % 1000000
|
|
242
|
+
|
|
243
|
+
#puts "hms #{hour} #{min} #{sec} #{usec}"
|
|
244
|
+
|
|
245
|
+
Time.utc(year, month, day, hour, min, sec, usec)
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
def self.from_time (t)
|
|
249
|
+
|
|
250
|
+
to_string(t.to_f * 10 * 1000).to_i
|
|
251
|
+
end
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
#
|
|
255
|
+
# This wfid generator returns as wfid the value found in a given
|
|
256
|
+
# field of the launchitem (if any).
|
|
257
|
+
#
|
|
258
|
+
# If there is no launchitem or no field, a Kotoba wfid is returned.
|
|
259
|
+
#
|
|
260
|
+
# This generator is useful for engines that have to use workflow
|
|
261
|
+
# instance ids generated by other systems.
|
|
262
|
+
#
|
|
263
|
+
class FieldWfidGenerator < KotobaWfidGenerator
|
|
264
|
+
|
|
265
|
+
def initialize (service_name, application_context, field_name)
|
|
266
|
+
|
|
267
|
+
super service_name, application_context
|
|
268
|
+
|
|
269
|
+
@field_name = field_name
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
def generate (launchitem=nil)
|
|
273
|
+
|
|
274
|
+
return super unless launchitem
|
|
275
|
+
|
|
276
|
+
wfid = launchitem.attributes[@field_name]
|
|
277
|
+
|
|
278
|
+
return wfid.to_s if wfid
|
|
279
|
+
|
|
280
|
+
super
|
|
281
|
+
#
|
|
282
|
+
# if the field is not present in the launchitem, will
|
|
283
|
+
# return a Kotoba wfid
|
|
284
|
+
end
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
#
|
|
288
|
+
# A wfid generator that uses any underlying "uuidgen" command it might
|
|
289
|
+
# find.
|
|
290
|
+
# By default, it favours "uuidgen -t".
|
|
291
|
+
#
|
|
292
|
+
# You can specifying a command by passing a :uuid_command param in the
|
|
293
|
+
# application context, or simply by overriding the generate() method.
|
|
294
|
+
#
|
|
295
|
+
class UuidWfidGenerator < Service
|
|
296
|
+
|
|
297
|
+
COMMANDS = [
|
|
298
|
+
"uuidgen -t",
|
|
299
|
+
"uuidgen"
|
|
300
|
+
]
|
|
301
|
+
|
|
302
|
+
def initialize (service_name, application_context)
|
|
303
|
+
|
|
304
|
+
super
|
|
305
|
+
|
|
306
|
+
@command = @application_context[:uuid_command] \
|
|
307
|
+
if @application_context
|
|
308
|
+
|
|
309
|
+
unless @command
|
|
310
|
+
COMMANDS.each do |c|
|
|
311
|
+
c = "#{c} 2> /dev/null"
|
|
312
|
+
s = `#{c}`
|
|
313
|
+
h = s[0, 8].hex
|
|
314
|
+
if h > 0
|
|
315
|
+
@command = c
|
|
316
|
+
break
|
|
317
|
+
end
|
|
318
|
+
end
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
raise "no command found for generating an uuid found..." \
|
|
322
|
+
unless @command
|
|
323
|
+
|
|
324
|
+
linfo { "new() command that will be used : '#{@command}'" }
|
|
325
|
+
end
|
|
326
|
+
|
|
327
|
+
#
|
|
328
|
+
# Generates a brand new UUID
|
|
329
|
+
#
|
|
330
|
+
# The launchitem parameter is not used by this generator.
|
|
331
|
+
#
|
|
332
|
+
def generate (launchitem=nil)
|
|
333
|
+
|
|
334
|
+
`#{@command}`.chomp
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
#
|
|
338
|
+
# Is a simple call to OpenWFE::split_wfid()
|
|
339
|
+
#
|
|
340
|
+
def split_wfid (wfid)
|
|
341
|
+
|
|
342
|
+
OpenWFE.split_wfid(wfid)
|
|
343
|
+
end
|
|
344
|
+
|
|
345
|
+
#
|
|
346
|
+
# This method is called by OpenWFE::split_wfid() when it has detected
|
|
347
|
+
# a wfid that is a UUID.
|
|
348
|
+
#
|
|
349
|
+
# Splits the first part of the uuid (will be used for the
|
|
350
|
+
# expression storage directory structure).
|
|
351
|
+
#
|
|
352
|
+
def self.split_wfid (wfid)
|
|
353
|
+
|
|
354
|
+
s = wfid[0, 8]
|
|
355
|
+
a = []
|
|
356
|
+
4.times do |i|
|
|
357
|
+
a << s[i*2, 2]
|
|
358
|
+
end
|
|
359
|
+
a
|
|
360
|
+
end
|
|
361
|
+
end
|
|
362
|
+
|
|
363
|
+
#
|
|
364
|
+
# "module methods"
|
|
365
|
+
#
|
|
366
|
+
|
|
367
|
+
SPLIT_MAP = {
|
|
368
|
+
"[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}" => UuidWfidGenerator,
|
|
369
|
+
"[0-9]{8}-[a-z]*" => KotobaWfidGenerator
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
#
|
|
373
|
+
# This method should be able to split any wfid whose scheme is implemented
|
|
374
|
+
# here.
|
|
375
|
+
#
|
|
376
|
+
def OpenWFE.split_wfid (wfid)
|
|
377
|
+
|
|
378
|
+
SPLIT_MAP.each do |regex, clazz|
|
|
379
|
+
return clazz.split_wfid(wfid) if wfid.match(regex)
|
|
380
|
+
end
|
|
381
|
+
#
|
|
382
|
+
# else
|
|
383
|
+
#
|
|
384
|
+
DefaultWfidGenerator.split_wfid(wfid)
|
|
385
|
+
end
|
|
386
|
+
|
|
387
|
+
end
|
|
388
|
+
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
#
|
|
2
|
+
#--
|
|
3
|
+
# Copyright (c) 2006-2008, Nicolas Modryzk 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 Japan"
|
|
36
|
+
#
|
|
37
|
+
# Nicolas Modrzyk at openwfe.org
|
|
38
|
+
# John Mettraux at openwfe.org
|
|
39
|
+
#
|
|
40
|
+
|
|
41
|
+
require 'openwfe/utils'
|
|
42
|
+
require 'openwfe/storage/yamlcustom'
|
|
43
|
+
require 'openwfe/storage/yamlfilestorage'
|
|
44
|
+
require 'openwfe/expool/threadedexpstorage'
|
|
45
|
+
|
|
46
|
+
require 'openwfe/expressions/flowexpression'
|
|
47
|
+
#require 'openwfe/expressions/raw_xml'
|
|
48
|
+
#--
|
|
49
|
+
# making sure classes in those files are loaded
|
|
50
|
+
# before their yaml persistence is tuned
|
|
51
|
+
# (else the reopening of the class is interpreted as
|
|
52
|
+
# a definition of the class...)
|
|
53
|
+
#++
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
module OpenWFE
|
|
57
|
+
|
|
58
|
+
#
|
|
59
|
+
# YAML expression storage. Expressions (atomic pieces of process instances)
|
|
60
|
+
# are stored in a hierarchy of YAML files.
|
|
61
|
+
#
|
|
62
|
+
class YamlFileExpressionStorage < YamlFileStorage
|
|
63
|
+
include OwfeServiceLocator
|
|
64
|
+
include ExpressionStorageBase
|
|
65
|
+
|
|
66
|
+
def initialize (service_name, application_context)
|
|
67
|
+
|
|
68
|
+
super service_name, application_context, '/expool'
|
|
69
|
+
|
|
70
|
+
observe_expool
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
#
|
|
74
|
+
# Find expressions matching various criteria.
|
|
75
|
+
# (See Engine#list_process_status for an explanation)
|
|
76
|
+
#
|
|
77
|
+
def find_expressions (options)
|
|
78
|
+
|
|
79
|
+
wfid_prefix = options[:wfid_prefix]
|
|
80
|
+
wfid_regex = nil
|
|
81
|
+
wfid_regex = Regexp.new("^"+wfid_prefix) if wfid_prefix
|
|
82
|
+
|
|
83
|
+
options.delete :wfid_prefix
|
|
84
|
+
# no need to check this in further does_match? calls
|
|
85
|
+
|
|
86
|
+
result = []
|
|
87
|
+
|
|
88
|
+
each_object_path do |path|
|
|
89
|
+
|
|
90
|
+
unless path[-23..-1] == 'engine_environment.yaml'
|
|
91
|
+
|
|
92
|
+
a = self.class.split_file_path path
|
|
93
|
+
|
|
94
|
+
next unless a
|
|
95
|
+
# not an expression file
|
|
96
|
+
|
|
97
|
+
wfid = a[0]
|
|
98
|
+
|
|
99
|
+
next if wfid_regex and (not wfid_regex.match(wfid))
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
fexp = load_object path
|
|
103
|
+
|
|
104
|
+
next unless does_match?(options, fexp)
|
|
105
|
+
|
|
106
|
+
result << fexp
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
result
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def fetch_root (wfid)
|
|
113
|
+
|
|
114
|
+
fei = FlowExpressionId.new
|
|
115
|
+
fei.wfid = wfid
|
|
116
|
+
fei.expid = "0"
|
|
117
|
+
fei.expression_name = "process-definition"
|
|
118
|
+
|
|
119
|
+
root = self[fei]
|
|
120
|
+
|
|
121
|
+
return root if root
|
|
122
|
+
|
|
123
|
+
#
|
|
124
|
+
# direct hit missed, scanning...
|
|
125
|
+
|
|
126
|
+
each_object_path(compute_dir_path(wfid)) do |p|
|
|
127
|
+
|
|
128
|
+
a = self.class.split_file_path p
|
|
129
|
+
next unless a
|
|
130
|
+
|
|
131
|
+
next unless a[0] == wfid
|
|
132
|
+
|
|
133
|
+
fexp = load_object p
|
|
134
|
+
|
|
135
|
+
return fexp if fexp.is_a?(DefineExpression)
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
nil
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
#
|
|
142
|
+
# Returns a human-readable list of the current YAML file paths.
|
|
143
|
+
# (one expression per path).
|
|
144
|
+
#
|
|
145
|
+
def to_s
|
|
146
|
+
|
|
147
|
+
s = "\n\n==== #{self.class} ===="
|
|
148
|
+
s << "\n"
|
|
149
|
+
each_object_path do |path|
|
|
150
|
+
s << path
|
|
151
|
+
s << "\n"
|
|
152
|
+
end
|
|
153
|
+
s << "==== . ====\n"
|
|
154
|
+
s
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
#
|
|
158
|
+
# Returns nil (if the path doesn't match an stored expression path)
|
|
159
|
+
# or an array [ workflow_instance_id, expression_id, expression_name ].
|
|
160
|
+
#
|
|
161
|
+
# This is a class method (not an instance one).
|
|
162
|
+
#
|
|
163
|
+
def self.split_file_path (path)
|
|
164
|
+
|
|
165
|
+
md = path.match %r{.*/(.*)__([\d.]*)_(.*).yaml}
|
|
166
|
+
return nil unless md
|
|
167
|
+
[ md[1], md[2], md[3] ]
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
protected
|
|
171
|
+
|
|
172
|
+
def compute_dir_path (wfid)
|
|
173
|
+
|
|
174
|
+
wfid = FlowExpressionId.to_parent_wfid wfid
|
|
175
|
+
|
|
176
|
+
a_wfid = get_wfid_generator.split_wfid wfid
|
|
177
|
+
|
|
178
|
+
@basepath + a_wfid[-2] + "/" + a_wfid[-1] + "/"
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def compute_file_path (fei)
|
|
182
|
+
|
|
183
|
+
return @basepath + "/engine_environment.yaml" \
|
|
184
|
+
if fei.workflow_instance_id == "0"
|
|
185
|
+
|
|
186
|
+
wfid = fei.parent_workflow_instance_id
|
|
187
|
+
|
|
188
|
+
compute_dir_path(wfid) +
|
|
189
|
+
fei.workflow_instance_id + "__" +
|
|
190
|
+
fei.expression_id + "_" +
|
|
191
|
+
fei.expression_name + ".yaml"
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
#--
|
|
195
|
+
# Returns true if the path points to a file containing an
|
|
196
|
+
# expression whose name is in the list of expression names
|
|
197
|
+
# corresponding to the given kind (class) of expressions.
|
|
198
|
+
#
|
|
199
|
+
#def matches (path, kind)
|
|
200
|
+
# exp_names = get_expression_map.get_expression_names(kind)
|
|
201
|
+
# exp_names.each do |exp_name|
|
|
202
|
+
# return true \
|
|
203
|
+
# if OpenWFE::ends_with(path, "_#{exp_name}.yaml")
|
|
204
|
+
# end
|
|
205
|
+
# false
|
|
206
|
+
#end
|
|
207
|
+
#++
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
#
|
|
211
|
+
# With this extension of YmalFileExpressionStorage, persistence occurs
|
|
212
|
+
# in a separate thread, for a snappier response.
|
|
213
|
+
#
|
|
214
|
+
class ThreadedYamlFileExpressionStorage < YamlFileExpressionStorage
|
|
215
|
+
include ThreadedStorageMixin
|
|
216
|
+
|
|
217
|
+
def initialize (service_name, application_context)
|
|
218
|
+
|
|
219
|
+
super
|
|
220
|
+
|
|
221
|
+
start_queue
|
|
222
|
+
end
|
|
223
|
+
end
|
|
224
|
+
end
|