openwferu 0.9.11 → 0.9.12
Sign up to get free protection for your applications and to get access to all the features.
- data/README.txt +0 -3
- data/examples/engine_template.rb +10 -4
- data/lib/openwfe/engine/engine.rb +336 -63
- data/lib/openwfe/engine/file_persisted_engine.rb +9 -1
- data/lib/openwfe/expool/errorjournal.rb +379 -0
- data/lib/openwfe/expool/expressionpool.rb +84 -55
- data/lib/openwfe/expool/expstorage.rb +54 -18
- data/lib/openwfe/expool/journal.rb +31 -22
- data/lib/openwfe/expool/yamlexpstorage.rb +57 -16
- data/lib/openwfe/expressions/fe_sequence.rb +1 -1
- data/lib/openwfe/expressions/flowexpression.rb +13 -1
- data/lib/openwfe/expressions/{fe_raw.rb → raw.rb} +5 -2
- data/lib/openwfe/expressions/raw_prog.rb +1 -1
- data/lib/openwfe/expressions/raw_xml.rb +1 -1
- data/lib/openwfe/expressions/time.rb +2 -0
- data/lib/openwfe/flowexpressionid.rb +21 -6
- data/lib/openwfe/omixins.rb +37 -14
- data/lib/openwfe/participants/atomparticipants.rb +6 -5
- data/lib/openwfe/participants/participantmap.rb +2 -0
- data/lib/openwfe/rest/controlclient.rb +1 -0
- data/lib/openwfe/rudefinitions.rb +5 -1
- data/lib/openwfe/storage/yamlfilestorage.rb +7 -3
- data/lib/openwfe/util/otime.rb +1 -1
- data/lib/openwfe/util/safe.rb +14 -0
- data/lib/openwfe/util/scheduler.rb +8 -5
- data/lib/openwfe/util/workqueue.rb +9 -2
- data/lib/openwfe/utils.rb +18 -0
- data/lib/openwfe/version.rb +1 -1
- data/test/atom_test.rb +27 -26
- data/test/fei_test.rb +3 -3
- data/test/file_persistence_test.rb +19 -2
- data/test/ft_0c_testname.rb +6 -3
- data/test/ft_26_load.rb +14 -7
- data/test/ft_26b_load.rb +87 -0
- data/test/ft_26c_load.rb +71 -0
- data/test/ft_27_getflowpos.rb +22 -3
- data/test/ft_34_cancelwfid.rb +3 -2
- data/test/ft_42_environments.rb +3 -1
- data/test/ft_58_ejournal.rb +119 -0
- data/test/ft_59_ps.rb +118 -0
- data/test/ft_60_ecancel.rb +87 -0
- data/test/ft_tests.rb +4 -0
- data/test/hparticipant_test.rb +1 -1
- data/test/orest_test.rb +27 -4
- data/test/param_test.rb +5 -1
- data/test/participant_test.rb +39 -0
- data/test/rake_qtest.rb +3 -5
- data/test/rest_test.rb +2 -2
- data/test/scheduler_test.rb +10 -15
- metadata +10 -3
data/README.txt
CHANGED
data/examples/engine_template.rb
CHANGED
@@ -8,9 +8,6 @@ require 'rubygems'
|
|
8
8
|
|
9
9
|
require 'openwfe/engine/engine'
|
10
10
|
require 'openwfe/engine/file_persisted_engine'
|
11
|
-
require 'openwfe/expool/history'
|
12
|
-
require 'openwfe/expool/journal'
|
13
|
-
require 'openwfe/listeners/listeners'
|
14
11
|
require 'openwfe/participants/participants'
|
15
12
|
|
16
13
|
|
@@ -62,9 +59,11 @@ engine = OpenWFE::CachedFilePersistedEngine.new
|
|
62
59
|
|
63
60
|
# -- process history
|
64
61
|
|
62
|
+
#require 'openwfe/expool/history'
|
63
|
+
|
65
64
|
#engine.init_service("history", InMemoryHistory)
|
66
65
|
#
|
67
|
-
# keeps all process history in an
|
66
|
+
# keeps all process history in an array in memory
|
68
67
|
# use only for test purposes !
|
69
68
|
|
70
69
|
#engine.init_service("history", FileHistory)
|
@@ -74,12 +73,17 @@ engine = OpenWFE::CachedFilePersistedEngine.new
|
|
74
73
|
|
75
74
|
# -- process journaling
|
76
75
|
|
76
|
+
#require 'openwfe/expool/journal'
|
77
77
|
#engine.init_service("journal", Journal)
|
78
78
|
#
|
79
79
|
# activates 'journaling',
|
80
80
|
#
|
81
81
|
# see http://openwferu.rubyforge.org/journal.html
|
82
82
|
#
|
83
|
+
# Journaling has a cost in terms of performace.
|
84
|
+
# Journaling should be used only in case you might want to migrate
|
85
|
+
# [segments of] running processes.
|
86
|
+
#
|
83
87
|
#engine.application_context[:keep_journals] = true
|
84
88
|
#
|
85
89
|
# if set to true, the journal of terminated processes will be kept
|
@@ -93,6 +97,8 @@ engine = OpenWFE::CachedFilePersistedEngine.new
|
|
93
97
|
# participants or LaunchItem requesting the launch of a particular flow)
|
94
98
|
#
|
95
99
|
|
100
|
+
#require 'openwfe/listeners/listeners'
|
101
|
+
|
96
102
|
#sl = OpenWFE::SocketListener.new(
|
97
103
|
# "socket_listener", @engine.application_context, 7008)
|
98
104
|
#engine.add_workitem_listener(sl)
|
@@ -43,15 +43,18 @@
|
|
43
43
|
require 'logger'
|
44
44
|
require 'fileutils'
|
45
45
|
|
46
|
-
require 'openwfe/
|
46
|
+
require 'openwfe/omixins'
|
47
47
|
require 'openwfe/rudefinitions'
|
48
48
|
require 'openwfe/service'
|
49
|
+
require 'openwfe/workitem'
|
49
50
|
require 'openwfe/util/irb'
|
50
51
|
require 'openwfe/util/scheduler'
|
51
52
|
require 'openwfe/util/schedulers'
|
52
53
|
require 'openwfe/expool/wfidgen'
|
53
54
|
require 'openwfe/expool/expressionpool'
|
54
55
|
require 'openwfe/expool/expstorage'
|
56
|
+
require 'openwfe/expool/errorjournal'
|
57
|
+
require 'openwfe/expressions/environment'
|
55
58
|
require 'openwfe/expressions/expressionmap'
|
56
59
|
require 'openwfe/participants/participantmap'
|
57
60
|
|
@@ -64,6 +67,7 @@ module OpenWFE
|
|
64
67
|
#
|
65
68
|
class Engine < Service
|
66
69
|
include OwfeServiceLocator
|
70
|
+
include FeiMixin
|
67
71
|
|
68
72
|
#
|
69
73
|
# Builds an OpenWFEru engine.
|
@@ -82,8 +86,10 @@ module OpenWFE
|
|
82
86
|
$OWFE_LOG = application_context[:logger]
|
83
87
|
|
84
88
|
unless $OWFE_LOG
|
89
|
+
#puts "Creating logs in " + FileUtils.pwd
|
85
90
|
FileUtils.mkdir("logs") unless File.exist?("logs")
|
86
|
-
$OWFE_LOG = Logger.new("logs/openwferu.log")
|
91
|
+
$OWFE_LOG = Logger.new("logs/openwferu.log", 10, 1024000)
|
92
|
+
$OWFE_LOG.level = Logger::INFO
|
87
93
|
end
|
88
94
|
|
89
95
|
# build order matters.
|
@@ -92,14 +98,40 @@ module OpenWFE
|
|
92
98
|
# pool and thus needs to be instantiated after it.
|
93
99
|
|
94
100
|
build_scheduler()
|
101
|
+
#
|
102
|
+
# for delayed or repetitive executions (it's the engine's clock)
|
103
|
+
# see http://openwferu.rubyforge.org/scheduler.html
|
95
104
|
|
96
105
|
build_expression_map()
|
106
|
+
#
|
107
|
+
# mapping expression names ('sequence', 'if', 'concurrence',
|
108
|
+
# 'when'...) to their implementations (SequenceExpression,
|
109
|
+
# IfExpression, ConcurrenceExpression, ...)
|
97
110
|
|
98
111
|
build_wfid_generator()
|
112
|
+
#
|
113
|
+
# the workflow instance (process instance) id generator
|
114
|
+
# making sure each process instance has a unique identifier
|
115
|
+
|
99
116
|
build_expression_pool()
|
117
|
+
#
|
118
|
+
# the core (hairy ball) of the engine
|
119
|
+
|
100
120
|
build_expression_storage()
|
121
|
+
#
|
122
|
+
# the engine persistence (persisting the expression instances
|
123
|
+
# that make up process instances)
|
101
124
|
|
102
125
|
build_participant_map()
|
126
|
+
#
|
127
|
+
# building the services that maps participant names to
|
128
|
+
# participant implementations / instances.
|
129
|
+
|
130
|
+
build_error_journal()
|
131
|
+
#
|
132
|
+
# builds the error journal (keeping track of failures
|
133
|
+
# in business process executions, and an opportunity to
|
134
|
+
# fix and replay)
|
103
135
|
|
104
136
|
linfo { "new() --- engine started --- #{self.object_id}" }
|
105
137
|
end
|
@@ -136,6 +168,10 @@ module OpenWFE
|
|
136
168
|
# either a String containing the URL of the process definition
|
137
169
|
# to launch (with an empty LaunchItem created on the fly).
|
138
170
|
#
|
171
|
+
# The launch object can also be a String containing the XML process
|
172
|
+
# definition or directly a class extending OpenWFE::ProcessDefinition
|
173
|
+
# (Ruby process definition).
|
174
|
+
#
|
139
175
|
# Returns the FlowExpressionId instance of the expression at the
|
140
176
|
# root of the newly launched process.
|
141
177
|
#
|
@@ -163,7 +199,12 @@ module OpenWFE
|
|
163
199
|
li
|
164
200
|
end
|
165
201
|
|
166
|
-
get_expression_pool.launch launchitem
|
202
|
+
fei = get_expression_pool.launch launchitem
|
203
|
+
|
204
|
+
fei.dup
|
205
|
+
#
|
206
|
+
# so that users of this launch() method can play with their
|
207
|
+
# fei without breaking things
|
167
208
|
end
|
168
209
|
|
169
210
|
#
|
@@ -292,6 +333,21 @@ module OpenWFE
|
|
292
333
|
get_scheduler.join
|
293
334
|
end
|
294
335
|
|
336
|
+
#
|
337
|
+
# Calling this method makes the control flow block until the
|
338
|
+
# workflow engine is inactive.
|
339
|
+
#
|
340
|
+
# TODO : implement idle_for
|
341
|
+
#
|
342
|
+
def join_until_idle ()
|
343
|
+
|
344
|
+
storage = get_expression_storage
|
345
|
+
|
346
|
+
while storage.size > 1
|
347
|
+
sleep 1
|
348
|
+
end
|
349
|
+
end
|
350
|
+
|
295
351
|
#
|
296
352
|
# Enabling the console means that hitting CTRL-C on the window /
|
297
353
|
# term / dos box / whatever does run the OpenWFEru engine will
|
@@ -346,56 +402,139 @@ module OpenWFE
|
|
346
402
|
end
|
347
403
|
|
348
404
|
#
|
405
|
+
# Waits for a given process instance to terminate.
|
406
|
+
# The method only exits when the flow terminates, but beware : if
|
407
|
+
# the process already terminated, the method will never exit.
|
408
|
+
#
|
409
|
+
# The parameter can be a FlowExpressionId instance, for example the
|
410
|
+
# one given back by a launch(), or directly a workflow instance id
|
411
|
+
# (String).
|
412
|
+
#
|
413
|
+
# This method is mainly used in utests.
|
414
|
+
#
|
415
|
+
def wait_for (fei_or_wfid)
|
416
|
+
|
417
|
+
wfid = if fei_or_wfid.kind_of?(FlowExpressionId)
|
418
|
+
fei_or_wfid.workflow_instance_id
|
419
|
+
else
|
420
|
+
fei_or_wfid
|
421
|
+
end
|
422
|
+
|
423
|
+
#Thread.pass
|
424
|
+
# #
|
425
|
+
# # let the flow 'stabilize' or progress before enquiring
|
426
|
+
#fexp = get_expression_pool.fetch_expression(fei)
|
427
|
+
#return unless fexp
|
428
|
+
#
|
429
|
+
# doesn't work well
|
430
|
+
|
431
|
+
t = Thread.new { Thread.stop }
|
432
|
+
|
433
|
+
get_expression_pool.add_observer(:terminate) do |channel, fe, wi|
|
434
|
+
t.wakeup if fe.fei.workflow_instance_id == wfid
|
435
|
+
end
|
436
|
+
|
437
|
+
ldebug { "wait_for() #{wfid}" }
|
438
|
+
|
439
|
+
t.join
|
440
|
+
end
|
441
|
+
|
442
|
+
#
|
443
|
+
# Returns a hash of ProcessStatus instances. The keys of the hash
|
444
|
+
# are workflow instance ids.
|
445
|
+
#
|
446
|
+
# A ProcessStatus is a description of the state of a process instance
|
447
|
+
# it enumerates the expressions where the process is currently
|
448
|
+
# located (waiting certainly) and the errors the process currently
|
449
|
+
# has (hopefully none).
|
450
|
+
#
|
451
|
+
def get_process_status (wfid=nil)
|
452
|
+
|
453
|
+
wfid = to_wfid(wfid) if wfid
|
454
|
+
|
455
|
+
result = {}
|
456
|
+
|
457
|
+
get_expression_storage.real_each(wfid) do |fei, fexp|
|
458
|
+
next if fexp.kind_of?(Environment)
|
459
|
+
next unless fexp.apply_time
|
460
|
+
(result[fei.parent_wfid] ||= ProcessStatus.new) << fexp
|
461
|
+
end
|
462
|
+
|
463
|
+
result.values.each do |ps|
|
464
|
+
get_error_journal.get_error_log(ps.wfid).each do |error|
|
465
|
+
ps << error
|
466
|
+
end
|
467
|
+
end
|
468
|
+
|
469
|
+
class << result
|
470
|
+
def to_s
|
471
|
+
pretty_print_process_status(self)
|
472
|
+
end
|
473
|
+
end
|
474
|
+
|
475
|
+
result
|
476
|
+
end
|
477
|
+
|
478
|
+
#--
|
349
479
|
# METHODS FROM THE EXPRESSION POOL
|
350
480
|
#
|
351
481
|
# These methods are 'proxy' to method found in the expression pool.
|
352
482
|
# They are made available here for a simpler model.
|
353
|
-
|
483
|
+
#++
|
354
484
|
|
355
485
|
#
|
356
486
|
# Returns the list of applied expressions belonging to a given
|
357
487
|
# workflow instance.
|
358
488
|
# May be used to determine where a process instance currently is.
|
359
489
|
#
|
360
|
-
|
361
|
-
|
490
|
+
# This method returns all the expressions (the stack) a process
|
491
|
+
# went through to reach its current state.
|
492
|
+
#
|
493
|
+
def get_process_stack (workflow_instance_id)
|
494
|
+
|
495
|
+
get_expression_pool.get_process_stack(workflow_instance_id)
|
362
496
|
end
|
363
|
-
alias :
|
497
|
+
alias :get_flow_stack :get_process_stack
|
364
498
|
|
365
499
|
#
|
366
|
-
# Lists all
|
500
|
+
# Lists all workflow (process) instances currently in the expool (in
|
367
501
|
# the engine).
|
368
502
|
# This method will return a list of "process-definition" expressions
|
369
503
|
# (root of flows).
|
370
504
|
#
|
371
|
-
# If consider_subprocesses is set to true, "process-definition"
|
372
|
-
# expressions of subprocesses will be returned as well.
|
373
|
-
#
|
374
505
|
# "wfid_prefix" allows your to query for specific workflow instance
|
375
506
|
# id prefixes.
|
376
507
|
#
|
377
|
-
|
508
|
+
# If consider_subprocesses is set to true, "process-definition"
|
509
|
+
# expressions of subprocesses will be returned as well.
|
510
|
+
#
|
511
|
+
def list_processes (consider_subprocesses=false, wfid_prefix=nil)
|
378
512
|
|
379
|
-
get_expression_pool.
|
513
|
+
get_expression_pool.list_processes(
|
380
514
|
consider_subprocesses, wfid_prefix)
|
381
515
|
end
|
382
|
-
alias :
|
516
|
+
alias :list_workflows :list_processes
|
383
517
|
|
384
518
|
#
|
385
519
|
# Given any expression of a process, cancels the complete process
|
386
520
|
# instance.
|
387
521
|
#
|
388
|
-
def
|
389
|
-
|
522
|
+
def cancel_process (exp_or_wfid)
|
523
|
+
|
524
|
+
get_expression_pool.cancel_process(exp_or_wfid)
|
390
525
|
end
|
391
|
-
alias :
|
526
|
+
alias :cancel_flow :cancel_process
|
392
527
|
|
393
528
|
#
|
394
529
|
# Cancels the given expression (and its children if any)
|
395
530
|
# (warning : advanced method)
|
396
531
|
#
|
532
|
+
# Cancelling the root expression of a process is equivalent to
|
533
|
+
# cancelling the process.
|
534
|
+
#
|
397
535
|
def cancel_expression (exp_or_fei)
|
398
|
-
|
536
|
+
|
537
|
+
get_expression_pool.cancel_expression(exp_or_fei)
|
399
538
|
end
|
400
539
|
|
401
540
|
#
|
@@ -403,53 +542,16 @@ module OpenWFE
|
|
403
542
|
# (warning : advanced method)
|
404
543
|
#
|
405
544
|
def forget_expression (exp_or_fei)
|
406
|
-
get_expression_pool.forget(exp_or_fei)
|
407
|
-
end
|
408
545
|
|
409
|
-
|
410
|
-
# Waits for a given process instance to terminate.
|
411
|
-
# The method only exits when the flow terminates, but beware : if
|
412
|
-
# the process already terminated, the method will never exit.
|
413
|
-
#
|
414
|
-
# The parameter can be a FlowExpressionId instance, for example the
|
415
|
-
# one given back by a launch(), or directly a workflow instance id
|
416
|
-
# (String).
|
417
|
-
#
|
418
|
-
# This method is mainly used in utests.
|
419
|
-
#
|
420
|
-
def wait_for (fei_or_wfid)
|
421
|
-
|
422
|
-
wfid = if fei_or_wfid.kind_of?(FlowExpressionId)
|
423
|
-
fei_or_wfid.workflow_instance_id
|
424
|
-
else
|
425
|
-
fei_or_wfid
|
426
|
-
end
|
427
|
-
|
428
|
-
#Thread.pass
|
429
|
-
# #
|
430
|
-
# # let the flow 'stabilize' or progress before enquiring
|
431
|
-
#fexp = get_expression_pool.fetch_expression(fei)
|
432
|
-
#return unless fexp
|
433
|
-
#
|
434
|
-
# doesn't work well
|
435
|
-
|
436
|
-
t = Thread.new { Thread.stop }
|
437
|
-
|
438
|
-
get_expression_pool.add_observer(:terminate) do |channel, fe, wi|
|
439
|
-
t.wakeup if fe.fei.workflow_instance_id == wfid
|
440
|
-
end
|
441
|
-
|
442
|
-
ldebug { "wait_for() #{wfid}" }
|
443
|
-
|
444
|
-
t.join
|
546
|
+
get_expression_pool.forget(exp_or_fei)
|
445
547
|
end
|
446
548
|
|
447
549
|
protected
|
448
550
|
|
449
|
-
|
551
|
+
#--
|
450
552
|
# the following methods may get overridden upon extension
|
451
553
|
# see for example file_persisted_engine.rb
|
452
|
-
|
554
|
+
#++
|
453
555
|
|
454
556
|
def build_expression_map
|
455
557
|
|
@@ -458,13 +560,14 @@ module OpenWFE
|
|
458
560
|
# the expression map is not a Service anymore,
|
459
561
|
# it's a simple instance (that will be reused in other
|
460
562
|
# OpenWFEru components)
|
461
|
-
|
462
|
-
#ldebug do
|
463
|
-
# "build_expression_map() :\n" +
|
464
|
-
# get_expression_map.to_s
|
465
|
-
#end
|
466
563
|
end
|
467
564
|
|
565
|
+
#
|
566
|
+
# This implementation builds a KotobaWfidGenerator instance and
|
567
|
+
# binds it in the engine context.
|
568
|
+
# There are other WfidGeneration implementations available, like
|
569
|
+
# UuidWfidGenerator or FieldWfidGenerator.
|
570
|
+
#
|
468
571
|
def build_wfid_generator
|
469
572
|
|
470
573
|
#init_service S_WFID_GENERATOR, DefaultWfidGenerator
|
@@ -479,26 +582,196 @@ module OpenWFE
|
|
479
582
|
# the field "wfid" of the LaunchItem.
|
480
583
|
end
|
481
584
|
|
585
|
+
#
|
586
|
+
# Builds the OpenWFEru expression pool (the core of the engine)
|
587
|
+
# and binds it in the engine context.
|
588
|
+
# There is only one implementation of the expression pool, so
|
589
|
+
# this method is usually never overriden.
|
590
|
+
#
|
482
591
|
def build_expression_pool
|
483
592
|
|
484
593
|
init_service(S_EXPRESSION_POOL, ExpressionPool)
|
485
594
|
end
|
486
595
|
|
596
|
+
#
|
597
|
+
# The implementation here builds an InMemoryExpressionStorage
|
598
|
+
# instance.
|
599
|
+
#
|
600
|
+
# See FilePersistedEngine or CachedFilePersistedEngine for
|
601
|
+
# overrides of this method.
|
602
|
+
#
|
487
603
|
def build_expression_storage
|
488
604
|
|
489
605
|
init_service(S_EXPRESSION_STORAGE, InMemoryExpressionStorage)
|
490
606
|
end
|
491
607
|
|
608
|
+
#
|
609
|
+
# The ParticipantMap is a mapping between participant names
|
610
|
+
# (well rather regular expressions) and participant implementations
|
611
|
+
# (see http://openwferu.rubyforge.org/participants.html)
|
612
|
+
#
|
492
613
|
def build_participant_map
|
493
614
|
|
494
615
|
init_service(S_PARTICIPANT_MAP, ParticipantMap)
|
495
616
|
end
|
496
617
|
|
618
|
+
#
|
619
|
+
# There is only one Scheduler implementation, that's the one
|
620
|
+
# built and bound here.
|
621
|
+
#
|
497
622
|
def build_scheduler
|
498
623
|
|
499
624
|
init_service(S_SCHEDULER, SchedulerService)
|
500
625
|
end
|
501
626
|
|
627
|
+
#
|
628
|
+
# The default implementation of this method uses an
|
629
|
+
# InMemoryErrorJournal (do not use in production).
|
630
|
+
#
|
631
|
+
def build_error_journal
|
632
|
+
|
633
|
+
init_service(S_ERROR_JOURNAL, InMemoryErrorJournal)
|
634
|
+
end
|
635
|
+
|
636
|
+
end
|
637
|
+
|
638
|
+
#
|
639
|
+
# ProcessStatus gathers information about the status of a business
|
640
|
+
# process instance.
|
641
|
+
#
|
642
|
+
# The status is mainly a list of expressions and a hash of errors.
|
643
|
+
#
|
644
|
+
# Instances of this class are obtained via Engine.process_status().
|
645
|
+
#
|
646
|
+
class ProcessStatus
|
647
|
+
|
648
|
+
#
|
649
|
+
# the String workflow instance id of the Process.
|
650
|
+
#
|
651
|
+
attr_reader :wfid
|
652
|
+
|
653
|
+
#
|
654
|
+
# The list of the expressions currently active in the process instance.
|
655
|
+
#
|
656
|
+
# For instance, if your process definition is currently in a
|
657
|
+
# concurrence, more than one expressions may be listed here.
|
658
|
+
#
|
659
|
+
attr_reader :expressions
|
660
|
+
|
661
|
+
#
|
662
|
+
# a hash whose values are ProcessError instances, the keys
|
663
|
+
# are FlowExpressionId instances (fei) (identifying the expressions
|
664
|
+
# that are concerned with the error)
|
665
|
+
#
|
666
|
+
attr_reader :errors
|
667
|
+
|
668
|
+
def initialize
|
669
|
+
@wfid = nil
|
670
|
+
@expressions = []
|
671
|
+
@errors = {}
|
672
|
+
end
|
673
|
+
|
674
|
+
#
|
675
|
+
# this method is used by Engine.get_process_status() when
|
676
|
+
# it prepares its results.
|
677
|
+
#
|
678
|
+
def << (item)
|
679
|
+
|
680
|
+
if item.kind_of?(FlowExpression)
|
681
|
+
add_expression item
|
682
|
+
else
|
683
|
+
add_error item
|
684
|
+
end
|
685
|
+
end
|
686
|
+
|
687
|
+
#
|
688
|
+
# A String representation, handy for debugging, quick viewing.
|
689
|
+
#
|
690
|
+
def to_s
|
691
|
+
s = ""
|
692
|
+
s << "-- #{self.class.name} --\n"
|
693
|
+
s << " wfid : #{@wfid}\n"
|
694
|
+
s << " expressions :\n"
|
695
|
+
@expressions.each do |fexp|
|
696
|
+
s << " #{fexp.fei}\n"
|
697
|
+
end
|
698
|
+
s << " errors : #{@errors.size}"
|
699
|
+
s
|
700
|
+
end
|
701
|
+
|
702
|
+
protected
|
703
|
+
|
704
|
+
def add_expression (fexp)
|
705
|
+
|
706
|
+
set_wfid fexp.fei.parent_wfid
|
707
|
+
|
708
|
+
#@expressions << fexp
|
709
|
+
|
710
|
+
exps = @expressions
|
711
|
+
@expressions = []
|
712
|
+
|
713
|
+
added = false
|
714
|
+
@expressions = exps.collect do |fe|
|
715
|
+
if added or fe.fei.wfid != fexp.fei.wfid
|
716
|
+
fe
|
717
|
+
else
|
718
|
+
if OpenWFE::starts_with(fexp.fei.expid, fe.fei.expid)
|
719
|
+
added = true
|
720
|
+
fexp
|
721
|
+
elsif OpenWFE::starts_with(fe.fei.expid, fexp.fei.expid)
|
722
|
+
added = true
|
723
|
+
fe
|
724
|
+
else
|
725
|
+
fe
|
726
|
+
end
|
727
|
+
end
|
728
|
+
end
|
729
|
+
@expressions << fexp unless added
|
730
|
+
end
|
731
|
+
|
732
|
+
def add_error (error)
|
733
|
+
@errors[error.fei] = error
|
734
|
+
end
|
735
|
+
|
736
|
+
def set_wfid (wfid)
|
737
|
+
|
738
|
+
return if @wfid
|
739
|
+
@wfid = wfid
|
740
|
+
end
|
741
|
+
end
|
742
|
+
|
743
|
+
#
|
744
|
+
# Renders a nice, terminal oriented, representation of an
|
745
|
+
# Engine.get_process_status() result.
|
746
|
+
#
|
747
|
+
# You usually directly benefit from this when doing
|
748
|
+
#
|
749
|
+
# puts engine.get_process_status.to_s
|
750
|
+
#
|
751
|
+
def pretty_print_process_status (ps)
|
752
|
+
|
753
|
+
s = ""
|
754
|
+
s << "process_id | name | rev | brn | err\n"
|
755
|
+
s << "--------------------+-------------------+---------+-----+-----\n"
|
756
|
+
|
757
|
+
ps.keys.sort.each do |wfid|
|
758
|
+
|
759
|
+
status = ps[wfid]
|
760
|
+
fexp = status.expressions[0]
|
761
|
+
ffei = fexp.fei
|
762
|
+
|
763
|
+
s << "%-19s" % wfid[0, 19]
|
764
|
+
s << " | "
|
765
|
+
s << "%-17s" % ffei.workflow_definition_name[0, 17]
|
766
|
+
s << " | "
|
767
|
+
s << "%-7s" % ffei.workflow_definition_revision[0, 7]
|
768
|
+
s << " | "
|
769
|
+
s << "%3s" % status.expressions.size.to_s[0, 3]
|
770
|
+
s << " | "
|
771
|
+
s << "%3s" % status.errors.size.to_s[0, 3]
|
772
|
+
s << "\n"
|
773
|
+
end
|
774
|
+
s
|
502
775
|
end
|
503
776
|
|
504
777
|
end
|
@@ -68,6 +68,14 @@ module OpenWFE
|
|
68
68
|
|
69
69
|
init_service(S_EXPRESSION_STORAGE, YamlFileExpressionStorage)
|
70
70
|
end
|
71
|
+
|
72
|
+
#
|
73
|
+
# Uses a file persisted error journal.
|
74
|
+
#
|
75
|
+
def build_error_journal ()
|
76
|
+
|
77
|
+
init_service(S_ERROR_JOURNAL, YamlErrorJournal)
|
78
|
+
end
|
71
79
|
end
|
72
80
|
|
73
81
|
#
|
@@ -78,7 +86,7 @@ module OpenWFE
|
|
78
86
|
# like 'sleep', 'cron', ... But if you do it before registering the
|
79
87
|
# participants you'll end up with broken processes.
|
80
88
|
#
|
81
|
-
class CachedFilePersistedEngine <
|
89
|
+
class CachedFilePersistedEngine < FilePersistedEngine
|
82
90
|
|
83
91
|
protected
|
84
92
|
|