ruote-maestrodev 2.2.1
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/CHANGELOG.txt +290 -0
- data/CREDITS.txt +99 -0
- data/LICENSE.txt +21 -0
- data/README.rdoc +88 -0
- data/Rakefile +108 -0
- data/TODO.txt +488 -0
- data/lib/ruote.rb +7 -0
- data/lib/ruote/context.rb +194 -0
- data/lib/ruote/engine.rb +1062 -0
- data/lib/ruote/engine/process_error.rb +122 -0
- data/lib/ruote/engine/process_status.rb +448 -0
- data/lib/ruote/exp/command.rb +87 -0
- data/lib/ruote/exp/commanded.rb +69 -0
- data/lib/ruote/exp/condition.rb +227 -0
- data/lib/ruote/exp/fe_add_branches.rb +138 -0
- data/lib/ruote/exp/fe_apply.rb +154 -0
- data/lib/ruote/exp/fe_cancel_process.rb +78 -0
- data/lib/ruote/exp/fe_command.rb +156 -0
- data/lib/ruote/exp/fe_concurrence.rb +321 -0
- data/lib/ruote/exp/fe_concurrent_iterator.rb +219 -0
- data/lib/ruote/exp/fe_cron.rb +141 -0
- data/lib/ruote/exp/fe_cursor.rb +324 -0
- data/lib/ruote/exp/fe_define.rb +112 -0
- data/lib/ruote/exp/fe_echo.rb +60 -0
- data/lib/ruote/exp/fe_equals.rb +115 -0
- data/lib/ruote/exp/fe_error.rb +82 -0
- data/lib/ruote/exp/fe_filter.rb +648 -0
- data/lib/ruote/exp/fe_forget.rb +88 -0
- data/lib/ruote/exp/fe_given.rb +154 -0
- data/lib/ruote/exp/fe_if.rb +127 -0
- data/lib/ruote/exp/fe_inc.rb +205 -0
- data/lib/ruote/exp/fe_iterator.rb +234 -0
- data/lib/ruote/exp/fe_let.rb +75 -0
- data/lib/ruote/exp/fe_listen.rb +304 -0
- data/lib/ruote/exp/fe_lose.rb +110 -0
- data/lib/ruote/exp/fe_noop.rb +45 -0
- data/lib/ruote/exp/fe_once.rb +215 -0
- data/lib/ruote/exp/fe_participant.rb +287 -0
- data/lib/ruote/exp/fe_read.rb +69 -0
- data/lib/ruote/exp/fe_redo.rb +82 -0
- data/lib/ruote/exp/fe_ref.rb +152 -0
- data/lib/ruote/exp/fe_registerp.rb +110 -0
- data/lib/ruote/exp/fe_reserve.rb +126 -0
- data/lib/ruote/exp/fe_restore.rb +102 -0
- data/lib/ruote/exp/fe_save.rb +72 -0
- data/lib/ruote/exp/fe_sequence.rb +59 -0
- data/lib/ruote/exp/fe_set.rb +154 -0
- data/lib/ruote/exp/fe_subprocess.rb +211 -0
- data/lib/ruote/exp/fe_that.rb +92 -0
- data/lib/ruote/exp/fe_undo.rb +67 -0
- data/lib/ruote/exp/fe_unregisterp.rb +69 -0
- data/lib/ruote/exp/fe_wait.rb +95 -0
- data/lib/ruote/exp/flowexpression.rb +886 -0
- data/lib/ruote/exp/iterator.rb +81 -0
- data/lib/ruote/exp/merge.rb +118 -0
- data/lib/ruote/exp/ro_attributes.rb +212 -0
- data/lib/ruote/exp/ro_filters.rb +136 -0
- data/lib/ruote/exp/ro_persist.rb +154 -0
- data/lib/ruote/exp/ro_variables.rb +189 -0
- data/lib/ruote/exp/ro_vf.rb +68 -0
- data/lib/ruote/fei.rb +260 -0
- data/lib/ruote/id/mnemo_wfid_generator.rb +43 -0
- data/lib/ruote/id/wfid_generator.rb +81 -0
- data/lib/ruote/log/default_history.rb +122 -0
- data/lib/ruote/log/pretty.rb +176 -0
- data/lib/ruote/log/storage_history.rb +159 -0
- data/lib/ruote/log/test_logger.rb +208 -0
- data/lib/ruote/log/wait_logger.rb +64 -0
- data/lib/ruote/part/block_participant.rb +137 -0
- data/lib/ruote/part/code_participant.rb +81 -0
- data/lib/ruote/part/engine_participant.rb +189 -0
- data/lib/ruote/part/local_participant.rb +138 -0
- data/lib/ruote/part/no_op_participant.rb +60 -0
- data/lib/ruote/part/null_participant.rb +54 -0
- data/lib/ruote/part/rev_participant.rb +169 -0
- data/lib/ruote/part/smtp_participant.rb +116 -0
- data/lib/ruote/part/storage_participant.rb +392 -0
- data/lib/ruote/part/template.rb +84 -0
- data/lib/ruote/participant.rb +7 -0
- data/lib/ruote/reader.rb +278 -0
- data/lib/ruote/reader/json.rb +49 -0
- data/lib/ruote/reader/radial.rb +290 -0
- data/lib/ruote/reader/ruby_dsl.rb +186 -0
- data/lib/ruote/reader/xml.rb +99 -0
- data/lib/ruote/receiver/base.rb +212 -0
- data/lib/ruote/storage/base.rb +364 -0
- data/lib/ruote/storage/composite_storage.rb +121 -0
- data/lib/ruote/storage/fs_storage.rb +139 -0
- data/lib/ruote/storage/hash_storage.rb +211 -0
- data/lib/ruote/svc/dispatch_pool.rb +158 -0
- data/lib/ruote/svc/dollar_sub.rb +298 -0
- data/lib/ruote/svc/error_handler.rb +138 -0
- data/lib/ruote/svc/expression_map.rb +97 -0
- data/lib/ruote/svc/participant_list.rb +397 -0
- data/lib/ruote/svc/tracker.rb +172 -0
- data/lib/ruote/svc/treechecker.rb +141 -0
- data/lib/ruote/tree_dot.rb +85 -0
- data/lib/ruote/util/filter.rb +525 -0
- data/lib/ruote/util/hashdot.rb +79 -0
- data/lib/ruote/util/look.rb +128 -0
- data/lib/ruote/util/lookup.rb +127 -0
- data/lib/ruote/util/misc.rb +167 -0
- data/lib/ruote/util/ometa.rb +71 -0
- data/lib/ruote/util/serializer.rb +103 -0
- data/lib/ruote/util/subprocess.rb +88 -0
- data/lib/ruote/util/time.rb +100 -0
- data/lib/ruote/util/tree.rb +58 -0
- data/lib/ruote/version.rb +29 -0
- data/lib/ruote/worker.rb +386 -0
- data/lib/ruote/workitem.rb +394 -0
- data/phil.txt +14 -0
- data/ruote.gemspec +44 -0
- data/test/bm/ci.rb +55 -0
- data/test/bm/ici.rb +71 -0
- data/test/bm/juuman.rb +54 -0
- data/test/bm/launch_bench.rb +37 -0
- data/test/bm/load_26c.rb +97 -0
- data/test/bm/mega.rb +64 -0
- data/test/bm/seq_thousand.rb +31 -0
- data/test/bm/t.rb +35 -0
- data/test/functional/base.rb +247 -0
- data/test/functional/concurrent_base.rb +98 -0
- data/test/functional/crunner.rb +31 -0
- data/test/functional/ct_0_concurrence.rb +65 -0
- data/test/functional/ct_1_iterator.rb +67 -0
- data/test/functional/ct_2_cancel.rb +81 -0
- data/test/functional/eft_0_process_definition.rb +65 -0
- data/test/functional/eft_10_cancel_process.rb +46 -0
- data/test/functional/eft_11_wait.rb +109 -0
- data/test/functional/eft_12_listen.rb +500 -0
- data/test/functional/eft_13_iterator.rb +342 -0
- data/test/functional/eft_14_cursor.rb +456 -0
- data/test/functional/eft_15_loop.rb +69 -0
- data/test/functional/eft_16_if.rb +183 -0
- data/test/functional/eft_17_equals.rb +55 -0
- data/test/functional/eft_18_concurrent_iterator.rb +410 -0
- data/test/functional/eft_19_reserve.rb +136 -0
- data/test/functional/eft_1_echo.rb +68 -0
- data/test/functional/eft_20_save.rb +116 -0
- data/test/functional/eft_21_restore.rb +61 -0
- data/test/functional/eft_22_noop.rb +28 -0
- data/test/functional/eft_23_apply.rb +168 -0
- data/test/functional/eft_24_add_branches.rb +98 -0
- data/test/functional/eft_25_command.rb +28 -0
- data/test/functional/eft_26_error.rb +77 -0
- data/test/functional/eft_27_inc.rb +280 -0
- data/test/functional/eft_28_once.rb +135 -0
- data/test/functional/eft_29_cron.rb +64 -0
- data/test/functional/eft_2_sequence.rb +58 -0
- data/test/functional/eft_30_ref.rb +155 -0
- data/test/functional/eft_31_registerp.rb +130 -0
- data/test/functional/eft_32_lose.rb +93 -0
- data/test/functional/eft_33_let.rb +31 -0
- data/test/functional/eft_34_given.rb +123 -0
- data/test/functional/eft_35_filter.rb +375 -0
- data/test/functional/eft_36_read.rb +95 -0
- data/test/functional/eft_3_participant.rb +149 -0
- data/test/functional/eft_4_set.rb +296 -0
- data/test/functional/eft_5_subprocess.rb +163 -0
- data/test/functional/eft_6_concurrence.rb +304 -0
- data/test/functional/eft_7_forget.rb +61 -0
- data/test/functional/eft_8_undo.rb +114 -0
- data/test/functional/eft_9_redo.rb +138 -0
- data/test/functional/ft_0_worker.rb +65 -0
- data/test/functional/ft_10_dollar.rb +304 -0
- data/test/functional/ft_11_recursion.rb +109 -0
- data/test/functional/ft_12_launchitem.rb +43 -0
- data/test/functional/ft_13_variables.rb +151 -0
- data/test/functional/ft_14_re_apply.rb +324 -0
- data/test/functional/ft_15_timeout.rb +226 -0
- data/test/functional/ft_16_participant_params.rb +98 -0
- data/test/functional/ft_17_conditional.rb +102 -0
- data/test/functional/ft_18_kill.rb +138 -0
- data/test/functional/ft_19_participant_code.rb +67 -0
- data/test/functional/ft_1_process_status.rb +796 -0
- data/test/functional/ft_20_storage_participant.rb +543 -0
- data/test/functional/ft_21_forget.rb +153 -0
- data/test/functional/ft_22_process_definitions.rb +90 -0
- data/test/functional/ft_23_load_defs.rb +79 -0
- data/test/functional/ft_24_block_participant.rb +235 -0
- data/test/functional/ft_25_receiver.rb +207 -0
- data/test/functional/ft_26_participant_rtimeout.rb +179 -0
- data/test/functional/ft_27_var_indirection.rb +128 -0
- data/test/functional/ft_28_null_noop_participants.rb +51 -0
- data/test/functional/ft_29_part_template.rb +60 -0
- data/test/functional/ft_2_errors.rb +380 -0
- data/test/functional/ft_30_smtp_participant.rb +122 -0
- data/test/functional/ft_31_part_blocking.rb +72 -0
- data/test/functional/ft_33_participant_subprocess_priority.rb +32 -0
- data/test/functional/ft_34_cursor_rewind.rb +101 -0
- data/test/functional/ft_35_add_service.rb +56 -0
- data/test/functional/ft_36_storage_history.rb +150 -0
- data/test/functional/ft_37_default_history.rb +109 -0
- data/test/functional/ft_38_participant_more.rb +193 -0
- data/test/functional/ft_39_wait_for.rb +136 -0
- data/test/functional/ft_3_participant_registration.rb +574 -0
- data/test/functional/ft_40_wait_logger.rb +62 -0
- data/test/functional/ft_41_participants.rb +91 -0
- data/test/functional/ft_42_storage_copy.rb +71 -0
- data/test/functional/ft_43_participant_on_reply.rb +87 -0
- data/test/functional/ft_44_var_participant.rb +35 -0
- data/test/functional/ft_45_participant_accept.rb +64 -0
- data/test/functional/ft_46_launch_single.rb +83 -0
- data/test/functional/ft_47_wfid_generator.rb +54 -0
- data/test/functional/ft_48_lose.rb +112 -0
- data/test/functional/ft_49_engine_on_error.rb +201 -0
- data/test/functional/ft_4_cancel.rb +132 -0
- data/test/functional/ft_50_engine_config.rb +22 -0
- data/test/functional/ft_51_misc.rb +67 -0
- data/test/functional/ft_52_case.rb +134 -0
- data/test/functional/ft_53_engine_on_terminate.rb +95 -0
- data/test/functional/ft_54_patterns.rb +104 -0
- data/test/functional/ft_55_engine_participant.rb +303 -0
- data/test/functional/ft_56_filter_attribute.rb +259 -0
- data/test/functional/ft_57_rev_participant.rb +252 -0
- data/test/functional/ft_58_workitem.rb +69 -0
- data/test/functional/ft_59_pause.rb +343 -0
- data/test/functional/ft_5_on_error.rb +384 -0
- data/test/functional/ft_60_code_participant.rb +45 -0
- data/test/functional/ft_61_trailing_fields.rb +34 -0
- data/test/functional/ft_62_exp_name_and_dollar_substitution.rb +35 -0
- data/test/functional/ft_6_on_cancel.rb +221 -0
- data/test/functional/ft_7_tags.rb +177 -0
- data/test/functional/ft_8_participant_consumption.rb +124 -0
- data/test/functional/ft_9_subprocesses.rb +146 -0
- data/test/functional/restart_base.rb +34 -0
- data/test/functional/rt_0_wait.rb +55 -0
- data/test/functional/rt_1_listen.rb +56 -0
- data/test/functional/rt_2_errors.rb +56 -0
- data/test/functional/rt_3_once.rb +70 -0
- data/test/functional/rt_4_cron.rb +64 -0
- data/test/functional/rt_5_timeout.rb +60 -0
- data/test/functional/rtest.rb +8 -0
- data/test/functional/storage_helper.rb +93 -0
- data/test/functional/test.rb +44 -0
- data/test/functional/vertical.rb +46 -0
- data/test/path_helper.rb +15 -0
- data/test/test.rb +13 -0
- data/test/test_helper.rb +28 -0
- data/test/unit/storage.rb +428 -0
- data/test/unit/storages.rb +37 -0
- data/test/unit/test.rb +28 -0
- data/test/unit/ut_0_ruby_reader.rb +223 -0
- data/test/unit/ut_11_lookup.rb +122 -0
- data/test/unit/ut_13_serializer.rb +65 -0
- data/test/unit/ut_14_is_uri.rb +28 -0
- data/test/unit/ut_15_util.rb +57 -0
- data/test/unit/ut_16_reader.rb +225 -0
- data/test/unit/ut_18_engine.rb +47 -0
- data/test/unit/ut_19_part_template.rb +86 -0
- data/test/unit/ut_1_fei.rb +165 -0
- data/test/unit/ut_20_composite_storage.rb +74 -0
- data/test/unit/ut_21_svc_participant_list.rb +46 -0
- data/test/unit/ut_22_filter.rb +1094 -0
- data/test/unit/ut_23_svc_tracker.rb +48 -0
- data/test/unit/ut_24_radial_reader.rb +332 -0
- data/test/unit/ut_25_merge.rb +113 -0
- data/test/unit/ut_3_wait_logger.rb +39 -0
- data/test/unit/ut_4_expmap.rb +20 -0
- data/test/unit/ut_5_tree.rb +54 -0
- data/test/unit/ut_6_condition.rb +303 -0
- data/test/unit/ut_7_workitem.rb +99 -0
- data/test/unit/ut_8_tree_to_dot.rb +72 -0
- data/test/unit/ut_9_xml_reader.rb +61 -0
- metadata +504 -0
@@ -0,0 +1,43 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2005-2011, John Mettraux, jmettraux@gmail.com
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
|
+
# of this software and associated documentation files (the "Software"), to deal
|
6
|
+
# in the Software without restriction, including without limitation the rights
|
7
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
# copies of the Software, and to permit persons to whom the Software is
|
9
|
+
# furnished to do so, subject to the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be included in
|
12
|
+
# all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
17
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
20
|
+
# THE SOFTWARE.
|
21
|
+
#
|
22
|
+
# Made in Japan.
|
23
|
+
#++
|
24
|
+
|
25
|
+
require 'rufus/mnemo' # gem install rufus-mnemo
|
26
|
+
require 'ruote/id/wfid_generator'
|
27
|
+
|
28
|
+
|
29
|
+
module Ruote
|
30
|
+
|
31
|
+
class MnemoWfidGenerator < WfidGenerator
|
32
|
+
|
33
|
+
def generate
|
34
|
+
|
35
|
+
raw = get_raw
|
36
|
+
|
37
|
+
m = ((raw.to_f % 60 * 60 * 24) * 1000).to_i
|
38
|
+
|
39
|
+
"#{raw.strftime('%Y%m%d')}-#{Rufus::Mnemo.from_integer(m)}"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
@@ -0,0 +1,81 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2005-2011, John Mettraux, jmettraux@gmail.com
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
|
+
# of this software and associated documentation files (the "Software"), to deal
|
6
|
+
# in the Software without restriction, including without limitation the rights
|
7
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
# copies of the Software, and to permit persons to whom the Software is
|
9
|
+
# furnished to do so, subject to the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be included in
|
12
|
+
# all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
17
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
20
|
+
# THE SOFTWARE.
|
21
|
+
#
|
22
|
+
# Made in Japan.
|
23
|
+
#++
|
24
|
+
|
25
|
+
|
26
|
+
module Ruote
|
27
|
+
|
28
|
+
class WfidGenerator
|
29
|
+
|
30
|
+
def initialize(context)
|
31
|
+
|
32
|
+
@context = context
|
33
|
+
|
34
|
+
@last =
|
35
|
+
@context.storage.get('variables', 'last_wfid') ||
|
36
|
+
{ 'type' => 'variables', '_id' => 'last_wfid', 'raw' => Time.now.utc.to_f }
|
37
|
+
end
|
38
|
+
|
39
|
+
def generate
|
40
|
+
|
41
|
+
raw = get_raw
|
42
|
+
|
43
|
+
"#{raw.strftime('%Y%m%d%H%M%S')}-#{raw.usec}"
|
44
|
+
end
|
45
|
+
|
46
|
+
protected
|
47
|
+
|
48
|
+
def get_raw
|
49
|
+
|
50
|
+
lraw = @last['raw'] + 0.01
|
51
|
+
|
52
|
+
raw = Time.now.utc
|
53
|
+
raw = raw + 0.01 while raw.to_f <= lraw
|
54
|
+
|
55
|
+
@last['raw'] = raw.to_f
|
56
|
+
|
57
|
+
last = @context.storage.put(@last, :update_rev => true)
|
58
|
+
|
59
|
+
if last == true
|
60
|
+
#
|
61
|
+
# 'last' is gone, have to put new one
|
62
|
+
@last.delete('_rev')
|
63
|
+
get_raw
|
64
|
+
|
65
|
+
elsif last
|
66
|
+
#
|
67
|
+
# put failed, have to re-ask
|
68
|
+
#
|
69
|
+
@last = last
|
70
|
+
get_raw
|
71
|
+
|
72
|
+
else
|
73
|
+
#
|
74
|
+
# put successful, we can build a new wfid
|
75
|
+
#
|
76
|
+
raw
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
@@ -0,0 +1,122 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2005-2011, John Mettraux, jmettraux@gmail.com
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
|
+
# of this software and associated documentation files (the "Software"), to deal
|
6
|
+
# in the Software without restriction, including without limitation the rights
|
7
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
# copies of the Software, and to permit persons to whom the Software is
|
9
|
+
# furnished to do so, subject to the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be included in
|
12
|
+
# all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
17
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
20
|
+
# THE SOFTWARE.
|
21
|
+
#
|
22
|
+
# Made in Japan.
|
23
|
+
#++
|
24
|
+
|
25
|
+
|
26
|
+
module Ruote
|
27
|
+
|
28
|
+
#
|
29
|
+
# A default history implementation, only keeps the most recent stuff
|
30
|
+
# in memory.
|
31
|
+
#
|
32
|
+
# NOTE : this default history is worthless when there are multiple workers.
|
33
|
+
# It only keeps track of the 'local' worker if there is one present.
|
34
|
+
#
|
35
|
+
class DefaultHistory
|
36
|
+
|
37
|
+
DATE_REGEX = /!(\d{4}-\d{2}-\d{2})!/
|
38
|
+
DEFAULT_MAX_SIZE = 1000
|
39
|
+
|
40
|
+
def initialize(context, options={})
|
41
|
+
|
42
|
+
@context = context
|
43
|
+
@options = options
|
44
|
+
|
45
|
+
@history = []
|
46
|
+
|
47
|
+
@context.worker.subscribe(:all, self) if @context.worker
|
48
|
+
# only care about logging if there is a worker present
|
49
|
+
end
|
50
|
+
|
51
|
+
# Returns all the msgs (events), most recent one is last.
|
52
|
+
#
|
53
|
+
def all
|
54
|
+
|
55
|
+
@history
|
56
|
+
end
|
57
|
+
|
58
|
+
# Returns all the wfids for which some piece of history is kept.
|
59
|
+
#
|
60
|
+
def wfids
|
61
|
+
|
62
|
+
@history.collect { |msg|
|
63
|
+
msg['wfid'] || (msg['fei']['wfid'] rescue nil)
|
64
|
+
}.compact.uniq.sort
|
65
|
+
end
|
66
|
+
|
67
|
+
# Returns all the msgs (events) for a given wfid. (Well, all the msgs
|
68
|
+
# that are kept.
|
69
|
+
#
|
70
|
+
def by_process(wfid)
|
71
|
+
|
72
|
+
@history.select { |msg|
|
73
|
+
(msg['wfid'] || (msg['fei']['wfid'] rescue nil)) == wfid
|
74
|
+
}
|
75
|
+
end
|
76
|
+
alias by_wfid by_process
|
77
|
+
|
78
|
+
# Returns an array [ most recent date, oldest date ] (Time instances).
|
79
|
+
#
|
80
|
+
def range
|
81
|
+
|
82
|
+
now = Time.now
|
83
|
+
|
84
|
+
[ (Time.parse(@history.first['seen_at']) rescue now),
|
85
|
+
(Time.parse(@history.last['seen_at']) rescue now) ]
|
86
|
+
end
|
87
|
+
|
88
|
+
def by_date(date)
|
89
|
+
|
90
|
+
d = Time.parse(date.to_s).utc.strftime('%Y-%m-%d')
|
91
|
+
|
92
|
+
@history.select { |m| Time.parse(m['seen_at']).strftime('%Y-%m-%d') == d }
|
93
|
+
end
|
94
|
+
|
95
|
+
#def history_to_tree (wfid)
|
96
|
+
# # (NOTE why not ?)
|
97
|
+
#end
|
98
|
+
|
99
|
+
# Forgets all the stored msgs.
|
100
|
+
#
|
101
|
+
def clear!
|
102
|
+
|
103
|
+
@history.clear
|
104
|
+
end
|
105
|
+
|
106
|
+
# This is the method called by the workqueue. Incoming engine events
|
107
|
+
# are 'processed' here.
|
108
|
+
#
|
109
|
+
def notify(msg)
|
110
|
+
|
111
|
+
msg = Ruote.fulldup(msg)
|
112
|
+
msg['seen_at'] = Ruote.now_to_utc_s
|
113
|
+
|
114
|
+
@history << msg
|
115
|
+
|
116
|
+
while (@history.size > (@options[:max_size] || DEFAULT_MAX_SIZE)) do
|
117
|
+
@history.shift
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
@@ -0,0 +1,176 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2005-2011, John Mettraux, jmettraux@gmail.com
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
|
+
# of this software and associated documentation files (the "Software"), to deal
|
6
|
+
# in the Software without restriction, including without limitation the rights
|
7
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
# copies of the Software, and to permit persons to whom the Software is
|
9
|
+
# furnished to do so, subject to the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be included in
|
12
|
+
# all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
17
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
20
|
+
# THE SOFTWARE.
|
21
|
+
#
|
22
|
+
# Made in Japan.
|
23
|
+
#++
|
24
|
+
|
25
|
+
|
26
|
+
module Ruote
|
27
|
+
|
28
|
+
#
|
29
|
+
# A container for the pretty printing logic of TestLogger.
|
30
|
+
#
|
31
|
+
module PrettyLogging
|
32
|
+
|
33
|
+
protected
|
34
|
+
|
35
|
+
#--
|
36
|
+
# <ESC>[{attr1};...;{attrn}m
|
37
|
+
#
|
38
|
+
# 0 Reset all attributes
|
39
|
+
# 1 Bright
|
40
|
+
# 2 Dim
|
41
|
+
# 4 Underscore
|
42
|
+
# 5 Blink
|
43
|
+
# 7 Reverse
|
44
|
+
# 8 Hidden
|
45
|
+
#
|
46
|
+
# Foreground Colours
|
47
|
+
# 30 Black
|
48
|
+
# 31 Red
|
49
|
+
# 32 Green
|
50
|
+
# 33 Yellow
|
51
|
+
# 34 Blue
|
52
|
+
# 35 Magenta
|
53
|
+
# 36 Cyan
|
54
|
+
# 37 White
|
55
|
+
#
|
56
|
+
# Background Colours
|
57
|
+
# 40 Black
|
58
|
+
# 41 Red
|
59
|
+
# 42 Green
|
60
|
+
# 43 Yellow
|
61
|
+
# 44 Blue
|
62
|
+
# 45 Magenta
|
63
|
+
# 46 Cyan
|
64
|
+
# 47 White
|
65
|
+
#++
|
66
|
+
|
67
|
+
def color(mod, s, clear=false)
|
68
|
+
|
69
|
+
return s if Ruote::WIN
|
70
|
+
return s unless STDOUT.tty?
|
71
|
+
|
72
|
+
"[#{mod}m#{s}[0m#{clear ? '' : "[#{@color}m"}"
|
73
|
+
end
|
74
|
+
|
75
|
+
def pretty_print(msg)
|
76
|
+
|
77
|
+
@count += 1
|
78
|
+
@count = 0 if @count > 9
|
79
|
+
|
80
|
+
ei = self.object_id.to_s[-2..-1]
|
81
|
+
|
82
|
+
fei = msg['fei']
|
83
|
+
depth = fei ? fei['expid'].split('_').size : 0
|
84
|
+
|
85
|
+
i = fei ?
|
86
|
+
[ fei['wfid'], (fei['subid'] || '')[0, 5], fei['expid'] ].join(' ') :
|
87
|
+
msg['wfid']
|
88
|
+
wfid = fei ? fei['wfid'] : msg['wfid']
|
89
|
+
|
90
|
+
rest = msg.dup
|
91
|
+
%w[
|
92
|
+
_id put_at _rev
|
93
|
+
type action
|
94
|
+
fei wfid variables
|
95
|
+
].each { |k| rest.delete(k) }
|
96
|
+
|
97
|
+
if v = rest['parent_id']
|
98
|
+
rest['parent_id'] = Ruote.to_storage_id(v)
|
99
|
+
end
|
100
|
+
if v = rest.delete('workitem')
|
101
|
+
rest[:wi] = [
|
102
|
+
v['fei'] ? Ruote.to_storage_id(v['fei']) : nil,
|
103
|
+
v['fields'].size ]
|
104
|
+
end
|
105
|
+
|
106
|
+
#if t = rest.delete('tree')
|
107
|
+
# rest[:t] = color(37, t.inspect, true)
|
108
|
+
#end
|
109
|
+
|
110
|
+
{ 'tree' => :t, 'parent_id' => :pi }.each do |k0, k1|
|
111
|
+
if v = rest.delete(k0)
|
112
|
+
rest[k1] = v
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
act = msg['action'][0, 2]
|
117
|
+
act = case msg['action']
|
118
|
+
when 'receive' then 'rc'
|
119
|
+
when 'dispatched' then 'dd'
|
120
|
+
when 'dispatch_cancel' then 'dc'
|
121
|
+
when 'dispatch_pause' then 'dp'
|
122
|
+
when 'dispatch_resume' then 'dr'
|
123
|
+
when 'pause', 'pause_process' then 'pz'
|
124
|
+
when 'resume', 'resume_process' then 'rz'
|
125
|
+
else act
|
126
|
+
end
|
127
|
+
act = case act
|
128
|
+
when 'la' then color('4;32', act)
|
129
|
+
when 'te' then color('4;31', act)
|
130
|
+
when 'ce' then color('31', act)
|
131
|
+
when 'ca' then color('31', act)
|
132
|
+
when 'rc' then color('4;33', act)
|
133
|
+
when 'di' then color('4;33', act)
|
134
|
+
when 'dd' then color('4;33', act)
|
135
|
+
when 'dc' then color('4;31', act)
|
136
|
+
when 'pz' then color('4;31', act)
|
137
|
+
when 'rz' then color('4;32', act)
|
138
|
+
when 'dp' then color('4;31', act)
|
139
|
+
when 'dr' then color('4;32', act)
|
140
|
+
else act
|
141
|
+
end
|
142
|
+
|
143
|
+
tail = if msg['action'] == 'error_intercepted'
|
144
|
+
|
145
|
+
tail = []
|
146
|
+
tail << " #{wfid} #{rest['error']['class']}"
|
147
|
+
tail << " #{wfid} #{rest['error']['message']}"
|
148
|
+
rest['error']['trace'].each do |line|
|
149
|
+
tail << " #{wfid} #{line}"
|
150
|
+
end
|
151
|
+
|
152
|
+
color(
|
153
|
+
@color,
|
154
|
+
"#{@count} #{ei} #{' ' * depth}#{act} * #{i}",
|
155
|
+
true
|
156
|
+
) +
|
157
|
+
"\n" +
|
158
|
+
color(
|
159
|
+
@color,
|
160
|
+
tail.join("\n"),
|
161
|
+
true)
|
162
|
+
|
163
|
+
else
|
164
|
+
|
165
|
+
pa = %w[ receive dispatch ].include?(msg['action']) ?
|
166
|
+
color('34', msg['participant_name']) + ' ' : ''
|
167
|
+
|
168
|
+
color(
|
169
|
+
@color,
|
170
|
+
"#{@count} #{ei} #{' ' * depth}#{act} * #{pa}#{i} #{rest.inspect}",
|
171
|
+
true)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
@@ -0,0 +1,159 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2005-2011, John Mettraux, jmettraux@gmail.com
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
|
+
# of this software and associated documentation files (the "Software"), to deal
|
6
|
+
# in the Software without restriction, including without limitation the rights
|
7
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
# copies of the Software, and to permit persons to whom the Software is
|
9
|
+
# furnished to do so, subject to the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be included in
|
12
|
+
# all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
17
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
20
|
+
# THE SOFTWARE.
|
21
|
+
#
|
22
|
+
# Made in Japan.
|
23
|
+
#++
|
24
|
+
|
25
|
+
|
26
|
+
module Ruote
|
27
|
+
|
28
|
+
#
|
29
|
+
# Logs the ruote engine history to the storage underlying the worker.
|
30
|
+
#
|
31
|
+
# Warning : don't use this history implementation when the storage is
|
32
|
+
# HashStorage. It will fill up your memory... Keeping history for a
|
33
|
+
# transient ruote is a bit overkill (IMHO).
|
34
|
+
#
|
35
|
+
# == using the StorageHistory
|
36
|
+
#
|
37
|
+
# engine.add_service(
|
38
|
+
# 'history', 'ruote/log/storage_history', 'Ruote::StorageHistory')
|
39
|
+
#
|
40
|
+
# # ...
|
41
|
+
#
|
42
|
+
# process_history = engine.history.by_wfid(wfid0)
|
43
|
+
#
|
44
|
+
#
|
45
|
+
# == final note
|
46
|
+
#
|
47
|
+
# By default, the history is an in-memory history (see Ruote::DefaultHistory)
|
48
|
+
# (and it is worthless when there are multiple workers).
|
49
|
+
#
|
50
|
+
class StorageHistory
|
51
|
+
|
52
|
+
DATE_REGEX = /!(\d{4}-\d{2}-\d{2})!/
|
53
|
+
|
54
|
+
def initialize(context, options={})
|
55
|
+
|
56
|
+
@context = context
|
57
|
+
@options = options
|
58
|
+
|
59
|
+
if @context.worker
|
60
|
+
|
61
|
+
# only care about logging if there is a worker present
|
62
|
+
|
63
|
+
@context.storage.add_type('history')
|
64
|
+
@context.worker.subscribe(:all, self)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# Returns all the wfids for which there are history items (msgs) stored.
|
69
|
+
#
|
70
|
+
def wfids
|
71
|
+
|
72
|
+
wfids = @context.storage.ids('history').collect { |id|
|
73
|
+
id.split('!').last
|
74
|
+
}.uniq.sort
|
75
|
+
|
76
|
+
wfids.delete('no_wfid')
|
77
|
+
|
78
|
+
wfids
|
79
|
+
end
|
80
|
+
|
81
|
+
# Returns all the msgs for a given wfid (process instance id).
|
82
|
+
#
|
83
|
+
def by_process(wfid)
|
84
|
+
|
85
|
+
@context.storage.get_many('history', wfid)
|
86
|
+
end
|
87
|
+
alias :by_wfid :by_process
|
88
|
+
|
89
|
+
# Returns an array [ most recent date, oldest date ] (Time instances).
|
90
|
+
#
|
91
|
+
def range
|
92
|
+
|
93
|
+
ids = @context.storage.ids('history')
|
94
|
+
|
95
|
+
#p ids.sort == ids
|
96
|
+
|
97
|
+
fm = DATE_REGEX.match(ids.first)[1]
|
98
|
+
lm = DATE_REGEX.match(ids.last)[1]
|
99
|
+
|
100
|
+
first = Time.parse("#{fm} 00:00:00 UTC")
|
101
|
+
last = Time.parse("#{lm} 00:00:00 UTC") + 24 * 3600
|
102
|
+
|
103
|
+
[ first, last ]
|
104
|
+
end
|
105
|
+
|
106
|
+
# Returns all the history events for a given day.
|
107
|
+
#
|
108
|
+
# Takes as argument whatever is a datetime when turned to a string and
|
109
|
+
# parsed.
|
110
|
+
#
|
111
|
+
def by_date(date)
|
112
|
+
|
113
|
+
date = Time.parse(date.to_s).strftime('%Y-%m-%d')
|
114
|
+
|
115
|
+
@context.storage.get_many('history', /!#{date}!/)
|
116
|
+
end
|
117
|
+
|
118
|
+
#def history_to_tree (wfid)
|
119
|
+
# # (NOTE why not ?)
|
120
|
+
#end
|
121
|
+
|
122
|
+
# The history system doesn't implement purge! so that when purge! is called
|
123
|
+
# on the engine, the history is not cleared.
|
124
|
+
#
|
125
|
+
# Call this *dangerous* clear! method to clean out any history file.
|
126
|
+
#
|
127
|
+
def clear!
|
128
|
+
|
129
|
+
@context.storage.purge_type!('history')
|
130
|
+
end
|
131
|
+
|
132
|
+
# This is the method called by the workqueue. Incoming engine events
|
133
|
+
# are 'processed' here.
|
134
|
+
#
|
135
|
+
def notify(msg)
|
136
|
+
|
137
|
+
msg = msg.dup
|
138
|
+
# a shallow copy is sufficient
|
139
|
+
|
140
|
+
si = if fei = msg['fei']
|
141
|
+
Ruote::FlowExpressionId.to_storage_id(fei)
|
142
|
+
else
|
143
|
+
msg['wfid'] || 'no_wfid'
|
144
|
+
end
|
145
|
+
|
146
|
+
_id = msg['_id']
|
147
|
+
msg['original_id'] = _id
|
148
|
+
msg['_id'] = "#{_id}!#{si}"
|
149
|
+
|
150
|
+
msg['type'] = 'history'
|
151
|
+
msg['original_put_at'] = msg['put_at']
|
152
|
+
|
153
|
+
msg.delete('_rev')
|
154
|
+
|
155
|
+
@context.storage.put(msg)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|