openwferu 0.9.1 → 0.9.2

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