openwferu 0.9.1 → 0.9.2

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.
Files changed (104) hide show
  1. data/{README → README.txt} +16 -13
  2. data/bin/validate-workflow.rb +46 -22
  3. data/examples/README.txt +8 -0
  4. data/examples/homeworkreview.rb +66 -0
  5. data/examples/quotereporter.rb +154 -0
  6. data/lib/{openwferu.rb → openwfe.rb} +6 -8
  7. data/lib/{ru → openwfe}/contextual.rb +11 -3
  8. data/lib/{ru → openwfe/engine}/engine.rb +50 -36
  9. data/lib/{ru/participant.rb → openwfe/engine/file_persisted_engine.rb} +21 -22
  10. data/lib/openwfe/expool/expressionpool.rb +534 -0
  11. data/lib/openwfe/expool/expstorage.rb +184 -0
  12. data/lib/openwfe/expool/journalexpstorage.rb +312 -0
  13. data/lib/openwfe/expool/yamlexpstorage.rb +127 -0
  14. data/lib/{ru → openwfe/expressions}/environment.rb +19 -14
  15. data/lib/{ru → openwfe/expressions}/expressionmap.rb +48 -21
  16. data/lib/{ru → openwfe/expressions}/fe_concurrence.rb +111 -35
  17. data/lib/openwfe/expressions/fe_cursor.rb +236 -0
  18. data/lib/{ru → openwfe/expressions}/fe_define.rb +5 -5
  19. data/lib/openwfe/expressions/fe_fqv.rb +99 -0
  20. data/lib/openwfe/expressions/fe_iterator.rb +182 -0
  21. data/lib/{ru/fe_misc.rb → openwfe/expressions/fe_losfor.rb} +14 -56
  22. data/lib/openwfe/expressions/fe_misc.rb +102 -0
  23. data/lib/{ru → openwfe/expressions}/fe_participant.rb +25 -14
  24. data/lib/{ru → openwfe/expressions}/fe_raw.rb +39 -75
  25. data/lib/{ru/fe_base.rb → openwfe/expressions/fe_sequence.rb} +40 -35
  26. data/lib/{ru → openwfe/expressions}/fe_subprocess.rb +30 -14
  27. data/lib/{ru → openwfe/expressions}/fe_time.rb +59 -31
  28. data/lib/{ru → openwfe/expressions}/fe_utils.rb +42 -26
  29. data/lib/{ru → openwfe/expressions}/fe_value.rb +20 -14
  30. data/lib/openwfe/expressions/flowexpression.rb +434 -0
  31. data/lib/openwfe/expressions/raw_prog.rb +391 -0
  32. data/lib/openwfe/expressions/raw_xml.rb +128 -0
  33. data/lib/openwfe/flowexpressionid.rb +148 -0
  34. data/lib/{ru → openwfe}/logging.rb +10 -6
  35. data/lib/{osocket.rb → openwfe/osocket.rb} +36 -35
  36. data/lib/{otime.rb → openwfe/otime.rb} +71 -21
  37. data/lib/openwfe/participants/atomparticipants.rb +144 -0
  38. data/lib/openwfe/participants/enoparticipant.rb +73 -0
  39. data/lib/openwfe/participants/participant.rb +85 -0
  40. data/lib/{ru → openwfe/participants}/participantmap.rb +40 -12
  41. data/lib/{ru → openwfe/participants}/participants.rb +41 -12
  42. data/lib/openwfe/participants/soapparticipants.rb +96 -0
  43. data/lib/{controlclient.rb → openwfe/rest/controlclient.rb} +12 -13
  44. data/lib/{definitions.rb → openwfe/rest/definitions.rb} +3 -3
  45. data/lib/{exception.rb → openwfe/rest/exception.rb} +3 -3
  46. data/lib/{restclient.rb → openwfe/rest/restclient.rb} +13 -22
  47. data/lib/{worklistclient.rb → openwfe/rest/worklistclient.rb} +33 -46
  48. data/lib/openwfe/rest/xmlcodec.rb +575 -0
  49. data/lib/{ru → openwfe}/rudefinitions.rb +32 -4
  50. data/lib/{ru → openwfe}/service.rb +20 -8
  51. data/lib/openwfe/storage/yamlfilestorage.rb +159 -0
  52. data/lib/{ru → openwfe/util}/dollar.rb +10 -8
  53. data/lib/openwfe/util/lru_cache.rb +149 -0
  54. data/lib/{ru → openwfe/util}/scheduler.rb +18 -10
  55. data/lib/{ru → openwfe/util}/schedulers.rb +7 -7
  56. data/lib/{utils.rb → openwfe/utils.rb} +93 -9
  57. data/lib/openwfe/workitem.rb +366 -0
  58. data/lib/openwfe/worklist/worklists.rb +175 -0
  59. data/test/README.txt +27 -0
  60. data/test/atomtest.rb +99 -0
  61. data/test/crontest.rb +58 -0
  62. data/test/dollartest.rb +3 -3
  63. data/test/feitest.rb +42 -14
  64. data/test/file_persistence_test.rb +93 -0
  65. data/test/flowtestbase.rb +72 -26
  66. data/test/ft_0.rb +1 -97
  67. data/test/ft_0b_sequence.rb +33 -0
  68. data/test/ft_0c_testname.rb +29 -0
  69. data/test/ft_10_loop.rb +48 -0
  70. data/test/ft_11_ppd.rb +292 -0
  71. data/test/ft_12_blockparticipant.rb +45 -0
  72. data/test/ft_13_eno.rb +51 -0
  73. data/test/ft_14_subprocess.rb +90 -0
  74. data/test/ft_14b_subprocess.rb +40 -0
  75. data/test/ft_15_iterator.rb +70 -0
  76. data/test/ft_16_fqv.rb +57 -0
  77. data/test/ft_1_unset.rb +25 -1
  78. data/test/ft_2_concurrence.rb +10 -5
  79. data/test/ft_3_equals.rb +35 -1
  80. data/test/ft_4_misc.rb +16 -1
  81. data/test/ft_5_time.rb +26 -1
  82. data/test/ft_6_lambda.rb +2 -1
  83. data/test/{ft_7_losfor.rb → ft_7_lose.rb} +41 -35
  84. data/test/ft_8_forget.rb +46 -0
  85. data/test/ft_9_cursor.rb +94 -0
  86. data/test/journal_persistence_test.rb +147 -0
  87. data/test/misctest.rb +13 -9
  88. data/test/rake_ptest.rb +18 -0
  89. data/test/rake_qtest.rb +43 -0
  90. data/test/{fulltest.rb → rake_test.rb} +2 -2
  91. data/test/raw_prog_test.rb +236 -0
  92. data/test/rest_test.rb +189 -0
  93. data/test/rutest_utils.rb +1 -1
  94. data/test/timetest.rb +42 -34
  95. metadata +125 -82
  96. data/lib/codec.rb +0 -573
  97. data/lib/flowexpressionid.rb +0 -139
  98. data/lib/ru/expressionpool.rb +0 -382
  99. data/lib/ru/expressionstorage.rb +0 -99
  100. data/lib/ru/flowexpression.rb +0 -272
  101. data/lib/ru/ruutils.rb +0 -70
  102. data/lib/test.rb +0 -222
  103. data/lib/workitem.rb +0 -249
  104. data/test/quicktest.rb +0 -21
@@ -0,0 +1,127 @@
1
+ #
2
+ #--
3
+ # Copyright (c) 2006-2007, 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
+ # $Id: definitions.rb 2725 2006-06-02 13:26:32Z jmettraux $
34
+ #
35
+
36
+ #
37
+ # "made in Japan"
38
+ #
39
+ # Nicolas Modrzyk at openwfe.org
40
+ # John Mettraux at openwfe.org
41
+ #
42
+
43
+ require 'find'
44
+
45
+ require 'openwfe/storage/yamlfilestorage'
46
+
47
+ require 'openwfe/expressions/flowexpression'
48
+ require 'openwfe/expressions/raw_xml'
49
+ #
50
+ # making sure classes in those files are loaded
51
+ # before their yaml persistence is tuned
52
+ # (else the reopening of the class is interpreted as
53
+ # a definition of the class...)
54
+
55
+
56
+ module OpenWFE
57
+
58
+ #
59
+ # reopening some classes in order to facilitate their
60
+ # yaml serialization
61
+ #
62
+
63
+ # opening for tuning yaml persistence
64
+ #
65
+ class FlowExpression
66
+ def to_yaml_properties
67
+ l = super()
68
+ l.delete("@application_context")
69
+ return l
70
+ end
71
+ end
72
+
73
+ # opening for tuning yaml persistence
74
+ #
75
+ class XmlRawExpression
76
+ def to_yaml_properties
77
+ l = super()
78
+ l.delete("@raw_representation")
79
+ return l
80
+ end
81
+ end
82
+
83
+ #
84
+ # yaml expression storage
85
+ #
86
+ class YamlFileExpressionStorage < YamlFileStorage
87
+
88
+ def initialize (service_name, application_context)
89
+ path = if (@application_context)
90
+ @application_context[:file_expression_storage_path]
91
+ else
92
+ DEFAULT_FILE_STORAGE_PATH
93
+ end
94
+ super(service_name, application_context, path + "/expool")
95
+ end
96
+
97
+ def compute_file_path (fei)
98
+
99
+ return @basepath + "/engine_env.yaml" \
100
+ if fei.workflow_instance_id == "0"
101
+
102
+ wfid = fei.parent_workflow_instance_id
103
+
104
+ @basepath + "/" +
105
+ wfid[-1, 1] + "/" +
106
+ wfid[-2, 1] + "/" +
107
+ wfid + "/" +
108
+ fei.workflow_instance_id + "__" +
109
+ fei.expression_id + "_" +
110
+ fei.expression_name + ".yaml"
111
+ end
112
+
113
+ def to_s
114
+ s = "\n\n==== #{self.class} ===="
115
+ s << "\n"
116
+ Find.find(@basepath) do |path|
117
+ if not File.stat(path).directory?
118
+ s << path
119
+ s << "\n"
120
+ end
121
+ end
122
+ s << "==== . ====\n"
123
+ return s
124
+ end
125
+
126
+ end
127
+ end
@@ -1,6 +1,6 @@
1
1
  #
2
- #<tt>
3
- # Copyright (c) 2006, John Mettraux, OpenWFE.org
2
+ #--
3
+ # Copyright (c) 2006-2007, John Mettraux, OpenWFE.org
4
4
  # All rights reserved.
5
5
  #
6
6
  # Redistribution and use in source and binary forms, with or without
@@ -28,7 +28,7 @@
28
28
  # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29
29
  # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30
30
  # POSSIBILITY OF SUCH DAMAGE.
31
- #</tt>
31
+ #++
32
32
  #
33
33
  # $Id: definitions.rb 2725 2006-06-02 13:26:32Z jmettraux $
34
34
  #
@@ -39,11 +39,11 @@
39
39
  # John Mettraux at openwfe.org
40
40
  #
41
41
 
42
- require 'ru/flowexpression'
43
- require 'ru/ruutils'
42
+ require 'openwfe/utils'
43
+ require 'openwfe/expressions/flowexpression'
44
44
 
45
45
 
46
- module OpenWFEru
46
+ module OpenWFE
47
47
 
48
48
  #
49
49
  # An environment is a store for variables.
@@ -63,11 +63,12 @@ module OpenWFEru
63
63
  end
64
64
 
65
65
  def [] (key)
66
- if OpenWFEru::starts_with(key, "//")
66
+
67
+ if OpenWFE::starts_with(key, "//")
67
68
  return get_expression_pool()\
68
69
  .get_engine_environment()[key[2..-1]]
69
70
  end
70
- if OpenWFEru::starts_with(key, "/")
71
+ if OpenWFE::starts_with(key, "/")
71
72
  return get_root_environment()[key[1..-1]]
72
73
  end
73
74
 
@@ -77,35 +78,38 @@ module OpenWFEru
77
78
  if @variables.has_key?(key) or is_engine_environment?
78
79
  #if value or is_engine_environment?
79
80
 
80
- return get_parent()[key] if @parentId
81
+ return get_parent()[key] if @parent_id
81
82
 
82
83
  return get_expression_pool().fetch_engine_environment()[key]
83
84
  end
84
85
 
85
86
  def []= (key, value)
86
- if OpenWFEru::starts_with(key, "//")
87
+
88
+ if OpenWFE::starts_with(key, "//")
87
89
  key = key[2..-1]
88
90
  get_expression_pool().fetch_engine_environment()[key] = value
89
- elsif OpenWFEru::starts_with(key, "/")
91
+ elsif OpenWFE::starts_with(key, "/")
90
92
  key = key[1..-1]
91
93
  get_root_environment()[key] = value
92
94
  else
93
95
  @variables[key] = value
94
96
  store_itself()
95
97
 
96
- ldebug { "[]= #{@fei.to_debug_s} : '#{key}' -> '#{value}'" }
98
+ #ldebug { "[]= #{@fei.to_debug_s} : '#{key}' -> '#{value}'" }
97
99
  end
98
100
  end
99
101
 
100
102
  def delete (key)
101
- if OpenWFEru::starts_with(key, "//")
103
+
104
+ if OpenWFE::starts_with(key, "//")
102
105
  key = key[2..-1]
103
106
  get_expression_pool().fetch_engine_environment().delete(key)
104
- elsif OpenWFEru::starts_with(key, "/")
107
+ elsif OpenWFE::starts_with(key, "/")
105
108
  key = key[1..-1]
106
109
  get_root_environment().delete(key)
107
110
  else
108
111
  @variables.delete(key)
112
+ store_itself()
109
113
  end
110
114
  end
111
115
 
@@ -116,6 +120,7 @@ module OpenWFEru
116
120
  # variables in this environment.
117
121
  #
118
122
  def unbind ()
123
+
119
124
  @variables.each do |key, value|
120
125
  get_expression_pool().remove(value) \
121
126
  if value.kind_of? OpenWFE::FlowExpressionId
@@ -1,6 +1,6 @@
1
1
  #
2
2
  #--
3
- # Copyright (c) 2006, John Mettraux, OpenWFE.org
3
+ # Copyright (c) 2006-2007, John Mettraux, OpenWFE.org
4
4
  # All rights reserved.
5
5
  #
6
6
  # Redistribution and use in source and binary forms, with or without
@@ -39,18 +39,22 @@
39
39
  # John Mettraux at openwfe.org
40
40
  #
41
41
 
42
- require 'ru/service'
43
- require 'ru/fe_define'
44
- require 'ru/fe_base'
45
- require 'ru/fe_misc'
46
- require 'ru/fe_value'
47
- require 'ru/fe_subprocess'
48
- require 'ru/fe_concurrence'
49
- require 'ru/fe_participant'
50
- require 'ru/fe_time'
42
+ require 'openwfe/service'
43
+ require 'openwfe/expressions/fe_define'
44
+ require 'openwfe/expressions/fe_misc'
45
+ require 'openwfe/expressions/fe_value'
46
+ require 'openwfe/expressions/fe_sequence'
47
+ require 'openwfe/expressions/fe_subprocess'
48
+ require 'openwfe/expressions/fe_concurrence'
49
+ require 'openwfe/expressions/fe_participant'
50
+ require 'openwfe/expressions/fe_time'
51
+ require 'openwfe/expressions/fe_losfor'
52
+ require 'openwfe/expressions/fe_cursor'
53
+ require 'openwfe/expressions/fe_iterator'
54
+ require 'openwfe/expressions/fe_fqv'
51
55
 
52
56
 
53
- module OpenWFEru
57
+ module OpenWFE
54
58
 
55
59
  #
56
60
  # The mapping between expression names like 'sequence', 'participant', etc
@@ -58,15 +62,11 @@ module OpenWFEru
58
62
  #
59
63
  class ExpressionMap < Service
60
64
 
61
- #attr_accessor \
62
- # :applicationContext
63
-
64
- SYNC_PREFIX = "sync::"
65
-
66
65
  def initialize (serviceName, applicationContext)
67
66
  super(serviceName, applicationContext)
68
67
 
69
68
  @map = {}
69
+ @sync_map = {}
70
70
 
71
71
  @map["process-definition"] = DefineExpression
72
72
  @map["workflow-definition"] = DefineExpression
@@ -76,9 +76,9 @@ module OpenWFEru
76
76
  @map["participant"] = ParticipantExpression
77
77
 
78
78
  @map["concurrence"] = ConcurrenceExpression
79
- @map["#{SYNC_PREFIX}generic"] = GenericSyncExpression
79
+ @sync_map["generic"] = GenericSyncExpression
80
80
 
81
- @map["subprocess"] = SubprocessRefExpression
81
+ @map["subprocess"] = SubProcessRefExpression
82
82
 
83
83
  @map["set"] = SetValueExpression
84
84
  @map["unset"] = UnsetValueExpression
@@ -94,6 +94,25 @@ module OpenWFEru
94
94
 
95
95
  @map["lose"] = LoseExpression
96
96
  @map["forget"] = ForgetExpression
97
+
98
+ @map["cursor"] = CursorExpression
99
+ @map["loop"] = LoopExpression
100
+
101
+ @map["back"] = CursorCommandExpression
102
+ @map["skip"] = CursorCommandExpression
103
+ @map["break"] = CursorCommandExpression
104
+ @map["cancel"] = CursorCommandExpression
105
+ @map["rewind"] = CursorCommandExpression
106
+ @map["continue"] = CursorCommandExpression
107
+
108
+ @map["iterator"] = IteratorExpression
109
+
110
+ @map["field"] = FqvExpression
111
+ @map["quote"] = FqvExpression
112
+ @map["variable"] = FqvExpression
113
+ @map["f"] = FqvExpression
114
+ @map["q"] = FqvExpression
115
+ @map["v"] = FqvExpression
97
116
  end
98
117
 
99
118
  #
@@ -105,7 +124,7 @@ module OpenWFEru
105
124
  end
106
125
 
107
126
  def get_sync_class (expressionname)
108
- return @map["#{SYNC_PREFIX}#{expressionname}"]
127
+ return @sync_map[expressionname]
109
128
  end
110
129
 
111
130
  #
@@ -115,8 +134,16 @@ module OpenWFEru
115
134
  def is_definition? (expressionname)
116
135
  c = get_class(expressionname)
117
136
  return \
118
- (c == OpenWFEru::DefineExpression or
119
- c == OpenWFEru::SetValueExpression)
137
+ (c == OpenWFE::DefineExpression or
138
+ c == OpenWFE::SetValueExpression)
139
+ end
140
+
141
+ #
142
+ # Returns the list of expression names registered in this
143
+ # expression map.
144
+ #
145
+ def expression_names
146
+ return @map.keys
120
147
  end
121
148
 
122
149
  end
@@ -1,6 +1,6 @@
1
1
  #
2
2
  #--
3
- # Copyright (c) 2006, John Mettraux, OpenWFE.org
3
+ # Copyright (c) 2006-2007, John Mettraux, OpenWFE.org
4
4
  # All rights reserved.
5
5
  #
6
6
  # Redistribution and use in source and binary forms, with or without
@@ -39,17 +39,16 @@
39
39
  # John Mettraux at openwfe.org
40
40
  #
41
41
 
42
- require 'monitor'
43
- require 'ru/flowexpression'
44
- require 'ru/rudefinitions'
45
- require 'ru/ruutils'
42
+ require 'openwfe/utils'
43
+ require 'openwfe/rudefinitions'
44
+ require 'openwfe/expressions/flowexpression'
46
45
 
47
46
 
48
47
  #
49
48
  # base expressions like 'sequence' and 'concurrence'
50
49
  #
51
50
 
52
- module OpenWFEru
51
+ module OpenWFE
53
52
 
54
53
  class ConcurrenceExpression < SequenceExpression
55
54
 
@@ -64,49 +63,74 @@ module OpenWFEru
64
63
  @sync_expression = \
65
64
  get_expression_map().get_sync_class(sync).new(@attributes)
66
65
 
67
- #threads = []
68
-
69
66
  @children.each do |child|
70
67
  @sync_expression.add_child(child)
71
68
  end
72
69
 
70
+ store_itself()
71
+
72
+ concurrence = self
73
+
73
74
  @children.each do |child|
74
- t = Thread.new do
75
+ Thread.new do
75
76
  begin
76
- get_expression_pool().apply(child, workitem.dup)
77
+ concurrence.synchronize do
78
+ get_expression_pool().apply(child, workitem.dup)
79
+ end
77
80
  rescue Exception => e
78
81
  lwarn do
79
- "apply() caught exception in concurrent child\n" +
80
- OpenWFEru::exception_to_s(e)
82
+ "apply() " +
83
+ "caught exception in concurrent child " +
84
+ child.to_debug_s + "\n" +
85
+ OpenWFE::exception_to_s(e)
81
86
  end
82
87
  end
83
88
  end
89
+ end
90
+
91
+ #@sync_expression.ready(self)
92
+ #
93
+ # this is insufficient, have to do that :
84
94
 
85
- #threads << t
95
+ synchronize do
96
+ #
97
+ # Making sure the freshest version of the concurrence
98
+ # expression is used.
99
+ # This is especially important when using pure persistence.
100
+ #
101
+ reloaded_self, _fei = get_expression_pool.fetch(@fei)
102
+ reloaded_self.sync_expression.ready(reloaded_self)
86
103
  end
87
104
  end
88
105
 
89
106
  def reply (workitem)
90
- done = @sync_expression.reply(self, workitem)
91
- reply_to_parent(done) if done
107
+ @sync_expression.reply(self, workitem)
92
108
  end
93
109
  end
94
110
 
111
+ #
112
+ # A base for sync expressions, currently empty.
113
+ # That may change.
114
+ #
95
115
  class SyncExpression
96
- include Logging, MonitorMixin
97
116
 
98
- #def initialize()
99
- # super()
100
- #end
117
+ def initialize()
118
+ super()
119
+ end
101
120
  end
102
121
 
122
+ #
123
+ # The classical OpenWFE sync expression.
124
+ # Used by 'concurrence' and 'concurrent-iterator'
125
+ #
103
126
  class GenericSyncExpression < SyncExpression
104
127
 
105
128
  attr_accessor \
106
129
  :remaining_children,
107
130
  :count,
108
131
  :reply_count,
109
- :cancel_remaining
132
+ :cancel_remaining,
133
+ :unready_queue
110
134
 
111
135
  def initialize (attributes)
112
136
 
@@ -117,6 +141,31 @@ module OpenWFEru
117
141
 
118
142
  @count = determine_count(attributes)
119
143
  @cancel_remaining = determine_remaining(attributes)
144
+
145
+ @unready_queue = []
146
+ end
147
+
148
+ #
149
+ # when all the children got applied concurrently, the concurrence
150
+ # calls this method to notify the sync expression that replies
151
+ # can be processed
152
+ #
153
+ def ready (synchable)
154
+ synchable.synchronize do
155
+
156
+ synchable.ldebug do
157
+ "ready() called by #{synchable.fei.to_debug_s} " +
158
+ "#{@unready_queue.length} wi waiting"
159
+ end
160
+
161
+ queue = @unready_queue
162
+ @unready_queue = nil
163
+ synchable.store_itself()
164
+
165
+ queue.each do |workitem|
166
+ do_reply(synchable, workitem)
167
+ end
168
+ end
120
169
  end
121
170
 
122
171
  def add_child (child)
@@ -124,47 +173,74 @@ module OpenWFEru
124
173
  end
125
174
 
126
175
  def reply (synchable, workitem)
127
- synchronize do
176
+ synchable.synchronize do
177
+
178
+ if @unready_queue
179
+
180
+ @unready_queue << workitem
181
+
182
+ synchable.store_itself()
183
+
184
+ synchable.ldebug do
185
+ "#{self.class}.reply() "+
186
+ "#{@unready_queue.length} wi waiting..."
187
+ end
128
188
 
129
- @application_context = synchable.application_context
130
- #
131
- # ldebug uses the application context
189
+ else
190
+ do_reply(synchable, workitem)
191
+ end
192
+ end
193
+ end
194
+
195
+ protected
132
196
 
133
- ldebug { "reply() #{workitem.lastExpressionId.to_debug_s}" }
197
+ def do_reply (synchable, workitem)
198
+
199
+ synchable.ldebug do
200
+ "#{self.class}.do_reply() "+
201
+ "#{workitem.last_expression_id.to_debug_s}"
202
+ end
134
203
 
135
204
  @reply_count = @reply_count + 1
136
205
 
137
206
  @remaining_children.delete(workitem.last_expression_id)
138
207
 
139
- return workitem \
140
- if @remaining_children.length <= 0
208
+ if @remaining_children.length <= 0
209
+ synchable.reply_to_parent(workitem)
210
+ return
211
+ end
141
212
 
142
213
  if @count > 0 and @reply_count >= @count
143
214
  treat_remaining_children(synchable)
144
- return workitem
215
+ synchable.reply_to_parent(workitem)
145
216
  end
146
-
147
- return nil
148
217
  end
149
- end
150
-
151
- protected
152
218
 
153
219
  def treat_remaining_children (synchable)
154
220
 
155
221
  expool = synchable.get_expression_pool
156
222
 
157
223
  @remaining_children.each do |child|
224
+
225
+ synchable.ldebug do
226
+ "#{self.class}.treat_remainining_children() " +
227
+ "#{child.to_debug_s} " +
228
+ "(cancel ? #{@cancel_remaining})"
229
+ end
230
+
158
231
  if @cancel_remaining
159
232
  expool.cancel(child)
160
233
  else
161
- expool.remove(child)
234
+ #expool.remove(child)
235
+ expool.forget(child)
162
236
  end
163
237
  end
164
238
  end
165
239
 
166
240
  def determine_remaining (attributes)
167
- return attributes[A_REMAINING] == REM_CANCEL
241
+ a = attributes[A_REMAINING]
242
+ return true if not a
243
+ return a == REM_CANCEL
168
244
  end
169
245
 
170
246
  def determine_count (attributes)