cpee 2.1.118 → 2.1.120

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: efddf22a558661bc01c0dbb55c372e497165cbbe73a0e04e3e2ff9902139c5c6
4
- data.tar.gz: dbb7ad60c6a29cb017e07124525f97f77d86ac4f58f8e99014c26b3dd0e4e50c
3
+ metadata.gz: 6bd002e776366ffd4053f69d04e34e88d6e17cede48668ddeec71dd0a8d423c1
4
+ data.tar.gz: f7141f31c96892dbd83146f6bfe56de06d620f2a1958282815f26db58575ea96
5
5
  SHA512:
6
- metadata.gz: 5d0a617afcc7628c3e71b14843e9ab710c37f761adbe365828ba094de56d1b402f07397ee926a764abc05a83baba5e7e7da197d4d3cf08c237c8a028502665cc
7
- data.tar.gz: af828a05d29fa674031b52b01f824964308c555d5fe50575a642687c1fe6f1a9b954577286ef69092e626af8aa773b8e6b455a4e7e4ebe5bf9af1ae784781a18
6
+ metadata.gz: 92fe3afab3035858ff7be53198418be5364b50e10b39a294a662ddb285d241f12bbb8ac44ce3dca207862f841d73ae47ad6f9c209b5bea9979dfe74829c39da9
7
+ data.tar.gz: eae4fc2fc3cd2b4f9c206c0318198e9bd6295ea61b49366217b3c81a3c5426aebab5b4e6ea8d99af813d46cc2be7bfb42c65ad018245c556327b6033a924fd0c
@@ -799,22 +799,19 @@ function monitor_instance_pos() {// {{{
799
799
  }// }}}
800
800
 
801
801
  function monitor_instance_running(content,event) {// {{{
802
- if (event == "calling") {
803
- if (!save['activity_red_states'][content['activity-uuid']]) {
804
- save['activity_red_states'][content['activity-uuid']] = true
805
- format_visual_add(content.activity,"active")
806
- }
807
- } else if (event == "manipulating") {
808
- if (!save['activity_red_states'][content['activity-uuid']]) {
809
- save['activity_red_states'][content['activity-uuid']] = true
810
- format_visual_add(content.activity,"active")
802
+ let uuid = content['activity-uuid'];
803
+ let cur = save['activity_red_states'][uuid];
804
+ if (event == "calling" || event == "manipulating") {
805
+ if (!cur && save['instance_pos'].filter( (_,e) => { return e.nodeName == content.activity }).length == 0) {
806
+ save['activity_red_states'][uuid] = { position: content.activity, state: 'active' };
807
+ format_visual_add(content.activity,"active");
811
808
  }
812
809
  } else if (event == "done") {
813
- if (save['activity_red_states'][content['activity-uuid']]) {
810
+ if ((cur && cur.state == 'active') || save['instance_pos'].filter( (_,e) => { return e.nodeName == content.activity }).length > 0) {
814
811
  format_visual_remove(content.activity,"active");
815
812
  }
816
- save['activity_red_states'][content['activity-uuid']] = true
817
- setTimeout(() => {delete save['activity_red_states'][content['activity-uuid']]},1);
813
+ save['activity_red_states'][uuid] = { position: content.activity, state: 'done' };
814
+ setTimeout(() => {delete save['activity_red_states'][uuid]},1000);
818
815
  }
819
816
  } // }}}
820
817
  function monitor_instance_pos_change(content) {// {{{
@@ -0,0 +1,228 @@
1
+ <?xml version="1.0"?>
2
+ <testset xmlns="http://cpee.org/ns/properties/2.0">
3
+ <executionhandler>ruby</executionhandler>
4
+ <dataelements>
5
+ <a>2</a>
6
+ <b>{"a":2,"b":12}</b>
7
+ <c>{"a":2}</c>
8
+ </dataelements>
9
+ <endpoints>
10
+ <user>https-post://cpee.org/services/timeout-user.php</user>
11
+ <auto>https-post://cpee.org/services/timeout-auto.php</auto>
12
+ <timeout>https-post://cpee.org/services/timeout.php</timeout>
13
+ <subprocess>https-post://cpee.org/flow/start/url/</subprocess>
14
+ <send>https-post://cpee.org/ing/correlators/message/send/</send>
15
+ <receive>https-get://cpee.org/ing/correlators/message/receive/</receive>
16
+ </endpoints>
17
+ <attributes>
18
+ <guarded>none</guarded>
19
+ <info>Readonly Local</info>
20
+ <modeltype>CPEE</modeltype>
21
+ <theme>preset</theme>
22
+ <creator>Christine Ashcreek</creator>
23
+ <guarded_id/>
24
+ <author>Christine Ashcreek</author>
25
+ <model_uuid>5b08fb27-26dd-4d18-8cc1-7907e79af97c</model_uuid>
26
+ <model_version/>
27
+ <design_dir>Templates.dir</design_dir>
28
+ <design_stage>development</design_stage>
29
+ </attributes>
30
+ <description>
31
+ <description xmlns="http://cpee.org/ns/description/1.0">
32
+ <manipulate id="a1" label="Set data.a to 2">
33
+ <code>data.a = 2</code>
34
+ <annotations>
35
+ <_logging_behavior>
36
+ <_exclude>false</_exclude>
37
+ </_logging_behavior>
38
+ <_context_data_analysis>
39
+ <probes/>
40
+ </_context_data_analysis>
41
+ </annotations>
42
+ </manipulate>
43
+ <parallel eid="e1" wait="-1" cancel="last">
44
+ <parallel_branch>
45
+ <call id="a3" endpoint="timeout">
46
+ <parameters>
47
+ <label>Wait 2</label>
48
+ <color/>
49
+ <arguments>
50
+ <timeout>2</timeout>
51
+ <data/>
52
+ </arguments>
53
+ </parameters>
54
+ <annotations>
55
+ <_generic/>
56
+ <_logging_behavior>
57
+ <_exclude>false</_exclude>
58
+ <_include>false</_include>
59
+ </_logging_behavior>
60
+ <_timing>
61
+ <_timing_weight/>
62
+ <_timing_avg/>
63
+ <explanations/>
64
+ </_timing>
65
+ <_shifting>
66
+ <_shifting_type>Duration</_shifting_type>
67
+ </_shifting>
68
+ <_context_data_analysis>
69
+ <probes/>
70
+ <ips/>
71
+ </_context_data_analysis>
72
+ <report>
73
+ <url/>
74
+ </report>
75
+ <_notes>
76
+ <_notes_general/>
77
+ </_notes>
78
+ </annotations>
79
+ <documentation>
80
+ <input/>
81
+ <output/>
82
+ <implementation>
83
+ <description/>
84
+ </implementation>
85
+ </documentation>
86
+ </call>
87
+ <choose eid="e2" mode="exclusive" label="">
88
+ <alternative eid="e3" condition="local.a == 2">
89
+ <call id="a2" endpoint="timeout">
90
+ <parameters>
91
+ <label>local.a as param</label>
92
+ <color/>
93
+ <arguments>
94
+ <timeout>1</timeout>
95
+ <data>
96
+ <a>!local.a</a>
97
+ <b>12</b>
98
+ </data>
99
+ </arguments>
100
+ </parameters>
101
+ <code>
102
+ <signal>false</signal>
103
+ <prepare/>
104
+ <finalize output="result">data.b = result</finalize>
105
+ <update output="result"/>
106
+ <rescue output="result"/>
107
+ </code>
108
+ <annotations>
109
+ <_generic/>
110
+ <_logging_behavior>
111
+ <_exclude>false</_exclude>
112
+ <_include>false</_include>
113
+ </_logging_behavior>
114
+ <_timing>
115
+ <_timing_weight/>
116
+ <_timing_avg/>
117
+ <explanations/>
118
+ </_timing>
119
+ <_shifting>
120
+ <_shifting_type>Duration</_shifting_type>
121
+ </_shifting>
122
+ <_context_data_analysis>
123
+ <probes/>
124
+ <ips/>
125
+ </_context_data_analysis>
126
+ <report>
127
+ <url/>
128
+ </report>
129
+ <_notes>
130
+ <_notes_general/>
131
+ </_notes>
132
+ </annotations>
133
+ <documentation>
134
+ <input/>
135
+ <output/>
136
+ <implementation>
137
+ <description/>
138
+ </implementation>
139
+ <code>
140
+ <description/>
141
+ </code>
142
+ </documentation>
143
+ </call>
144
+ <_probability>
145
+ <_probability_min/>
146
+ <_probability_max/>
147
+ <_probability_avg/>
148
+ </_probability>
149
+ </alternative>
150
+ <otherwise/>
151
+ </choose>
152
+ </parallel_branch>
153
+ <parallel_branch>
154
+ <manipulate id="a4" label="Set local.a to 1">
155
+ <code>local.a = 1</code>
156
+ <annotations>
157
+ <_logging_behavior>
158
+ <_exclude>false</_exclude>
159
+ </_logging_behavior>
160
+ <_context_data_analysis>
161
+ <probes/>
162
+ </_context_data_analysis>
163
+ </annotations>
164
+ </manipulate>
165
+ <call id="a5" endpoint="timeout">
166
+ <parameters>
167
+ <label>local.a as param</label>
168
+ <color/>
169
+ <arguments>
170
+ <timeout/>
171
+ <data>
172
+ <a>!local.a</a>
173
+ </data>
174
+ </arguments>
175
+ </parameters>
176
+ <code>
177
+ <signal>false</signal>
178
+ <prepare/>
179
+ <finalize output="result">data.c = result</finalize>
180
+ <update output="result"/>
181
+ <rescue output="result"/>
182
+ </code>
183
+ <annotations>
184
+ <_generic/>
185
+ <_logging_behavior>
186
+ <_exclude>false</_exclude>
187
+ <_include>false</_include>
188
+ </_logging_behavior>
189
+ <_timing>
190
+ <_timing_weight/>
191
+ <_timing_avg/>
192
+ <explanations/>
193
+ </_timing>
194
+ <_shifting>
195
+ <_shifting_type>Duration</_shifting_type>
196
+ </_shifting>
197
+ <_context_data_analysis>
198
+ <probes/>
199
+ <ips/>
200
+ </_context_data_analysis>
201
+ <report>
202
+ <url/>
203
+ </report>
204
+ <_notes>
205
+ <_notes_general/>
206
+ </_notes>
207
+ </annotations>
208
+ <documentation>
209
+ <input/>
210
+ <output/>
211
+ <implementation>
212
+ <description/>
213
+ </implementation>
214
+ <code>
215
+ <description/>
216
+ </code>
217
+ </documentation>
218
+ </call>
219
+ </parallel_branch>
220
+ </parallel>
221
+ </description>
222
+ </description>
223
+ <transformation>
224
+ <description type="copy"/>
225
+ <dataelements type="none"/>
226
+ <endpoints type="none"/>
227
+ </transformation>
228
+ </testset>
data/cpee.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "cpee"
3
- s.version = "2.1.118"
3
+ s.version = "2.1.120"
4
4
  s.platform = Gem::Platform::RUBY
5
5
  s.license = "LGPL-3.0-or-later"
6
6
  s.summary = "The cloud process execution engine (cpee.org). If you just need workflow execution, without a rest service exposing it, then use WEEL."
@@ -33,4 +33,5 @@ Gem::Specification.new do |s|
33
33
  s.add_runtime_dependency 'get_process_mem', '~>0.2'
34
34
  s.add_runtime_dependency 'webrick', '~>1.7'
35
35
  s.add_runtime_dependency 'by', '~> 1.1', '>= 1.1.0'
36
+ s.add_runtime_dependency 'concurrent-ruby', '~> 1.3', '>= 1.3.5'
36
37
  end
@@ -399,7 +399,7 @@ module CPEE
399
399
  end
400
400
  subs.each do |s|
401
401
  begin
402
- NewInstance::sub(multi,id,s.to_doc,s.attributes['id'] || Digest::MD5.hexdigest(Kernel::rand().to_s))
402
+ NewInstance::sub(multi,id,s.to_doc,s.attributes['id'] || SecureRandom.hex(16))
403
403
  end
404
404
  end
405
405
 
@@ -58,11 +58,11 @@ module CPEE
58
58
 
59
59
  if CPEE::Persistence::is_member?(id,opts,'callbacks',callback)
60
60
  res = {}
61
- res[:uuid] = CPEE::Persistence::extract_item(id,opts,"callback/#{callback}/uuid")
62
- res[:type] = CPEE::Persistence::extract_item(id,opts,"callback/#{callback}/type")
63
- res[:position] = CPEE::Persistence::extract_item(id,opts,"callback/#{callback}/position")
64
- res[:label] = CPEE::Persistence::extract_item(id,opts,"callback/#{callback}/label")
65
- if sub = CPEE::Persistence::extract_item(id,opts,"callback/#{callback}/subscription")
61
+ res[:uuid] = CPEE::Persistence::extract_item(id,opts,"callbacks/#{callback}/uuid")
62
+ res[:type] = CPEE::Persistence::extract_item(id,opts,"callbacks/#{callback}/type")
63
+ res[:position] = CPEE::Persistence::extract_item(id,opts,"callbacks/#{callback}/position")
64
+ res[:label] = CPEE::Persistence::extract_item(id,opts,"callbacks/#{callback}/label")
65
+ if sub = CPEE::Persistence::extract_item(id,opts,"callbacks/#{callback}/subscription")
66
66
  res[:subscription] = sub
67
67
  end
68
68
 
@@ -82,7 +82,7 @@ module CPEE
82
82
  if opts[:statemachine].final? id
83
83
  @status = 410
84
84
  else
85
- if CPEE::Persistence::extract_item(id,opts,"callback/#{callback}/type") == 'callback'
85
+ if CPEE::Persistence::extract_item(id,opts,"callbacks/#{callback}/type") == 'callback'
86
86
  CPEE::Message::send(
87
87
  :'callback-end',
88
88
  callback,
@@ -93,7 +93,7 @@ module CPEE
93
93
  {},
94
94
  opts[:redis]
95
95
  )
96
- elsif CPEE::Persistence::extract_item(id,opts,"callback/#{callback}/type") == 'vote'
96
+ elsif CPEE::Persistence::extract_item(id,opts,"callbacks/#{callback}/type") == 'vote'
97
97
  CPEE::Message::send(
98
98
  :'vote-response',
99
99
  callback,
@@ -128,7 +128,7 @@ module CPEE
128
128
  if opts[:statemachine].final? id
129
129
  @status = 410
130
130
  else
131
- if CPEE::Persistence::extract_item(id,opts,"callback/#{callback}/type") == 'callback'
131
+ if CPEE::Persistence::extract_item(id,opts,"callbacks/#{callback}/type") == 'callback'
132
132
  ret = {}
133
133
  ret['values'] = @p.map{ |e|
134
134
  # bei complex wenn kleiner 500KiB statt e.value.path e.value.read
@@ -159,7 +159,7 @@ module CPEE
159
159
  ret,
160
160
  opts[:redis]
161
161
  )
162
- elsif CPEE::Persistence::extract_item(id,opts,"callback/#{callback}/type") == 'vote'
162
+ elsif CPEE::Persistence::extract_item(id,opts,"callbacks/#{callback}/type") == 'vote'
163
163
  if @p.length == 1 && @p[0].name == 'continue' && @p[0].class == Riddl::Parameter::Simple
164
164
  CPEE::Message::send(
165
165
  :'vote-response',
@@ -129,7 +129,7 @@ module CPEE
129
129
  if opts[:statemachine].final? id
130
130
  @status = 410
131
131
  else
132
- key = @p[0].name == 'id' ? @p.shift.value : Digest::MD5.hexdigest(Kernel::rand().to_s)
132
+ key = @p[0].name == 'id' ? @p.shift.value : SecureRandom.hex(16)
133
133
  url = @p[0].name == 'url' ? @p.shift.value : nil
134
134
  values = []
135
135
  while @p.length > 0
data/lib/cpee/message.rb CHANGED
@@ -15,6 +15,7 @@
15
15
  module CPEE
16
16
 
17
17
  module Message
18
+ @@mutex = Mutex.new
18
19
  @@who = 'cpee'
19
20
  @@type = 'instance'
20
21
  @@tworkers = 1
@@ -39,19 +40,19 @@ module CPEE
39
40
  end
40
41
 
41
42
  def self::target
42
- @@last < @@tworkers-1 ? @@last += 1 : @@last = 0
43
+ @@mutex.synchronize { @@last < @@tworkers-1 ? @@last += 1 : @@last = 0 }
43
44
  end
44
45
 
45
46
  def self::wait(backend,sub,tt=nil)
46
47
  target = '%02i' % (tt || CPEE::Message::target)
47
- wid = Digest::MD5.hexdigest(Kernel::rand().to_s)
48
+ wid = SecureRandom.hex(16)
48
49
  begin
49
- sub.subscribe_with_timeout(2,'event:' + target + ':transaction/finished') do |on|
50
+ sub.subscribe_with_timeout(2,"event:#{target}:transaction/finished") do |on|
50
51
  on.message do |what,message|
51
52
  mess = message[0...message.index(' ')]
52
- sub.unsubscribe('event:' + target + ':transaction/finished') if mess == wid
53
+ sub.unsubscribe("event:#{target}:transaction/finished") if mess == wid
53
54
  end
54
- backend.publish('event:' + target + ':transaction/start',wid + ' {}')
55
+ backend.publish("event:#{target}:transaction/start","#{wid} {}")
55
56
  end
56
57
  rescue => e
57
58
  puts "timeout error"
@@ -65,7 +66,7 @@ module CPEE
65
66
  name = ::File::basename(event)
66
67
  payload = {
67
68
  @@who => cpee,
68
- @@type + '-url' => File.join(cpee,instance.to_s),
69
+ "#{@@type}-url" => File.join(cpee,instance.to_s),
69
70
  @@type => instance,
70
71
  'topic' => topic,
71
72
  'type' => type,
@@ -73,13 +74,10 @@ module CPEE
73
74
  'timestamp' => Time.now.xmlschema(6),
74
75
  'content' => content
75
76
  }
76
- payload[@@type + '-uuid'] = instance_uuid if instance_uuid
77
- payload[@@type + '-name'] = instance_name if instance_name
77
+ payload["#{@@type}-uuid"] = instance_uuid if instance_uuid
78
+ payload["#{@@type}-name"] = instance_name if instance_name
78
79
 
79
- backend.publish(type.to_s + ':' + target + ':' + event.to_s,
80
- instance.to_s + ',' + instance_uuid.to_s + ' ' +
81
- JSON::generate(payload)
82
- )
80
+ backend.publish("#{type}:#{target}:#{event}", "#{instance},#{instance_uuid} #{JSON::generate(payload)}")
83
81
  end
84
82
 
85
83
  def self::send_url(type, event, cpee, content={}, backend)
@@ -152,11 +152,11 @@ module CPEE
152
152
  res += cbs
153
153
  res += Persistence::keys_extract_name(opts,id,'callbacks')
154
154
  cbs.each do |c|
155
- ckey = Persistence::keys_extract_set_raw(opts,c)
156
- res << File.join(ckey,'position')
157
- res << File.join(ckey,'label')
158
- res << File.join(ckey,'uuid')
159
- res << File.join(ckey,'type')
155
+ res << "#{c}/position"
156
+ res << "#{c}/label"
157
+ res << "#{c}/uuid"
158
+ res << "#{c}/type"
159
+ res << "#{c}/subscription"
160
160
  end
161
161
  res += Persistence::keys_extract_name(opts,id,'dsl')
162
162
  res += Persistence::keys_extract_name(opts,id,'dslx')
@@ -15,6 +15,7 @@
15
15
  require 'charlock_holmes'
16
16
  require 'mimemagic'
17
17
  require 'base64'
18
+ require 'securerandom'
18
19
  require 'cpee-eval-ruby/translation'
19
20
 
20
21
  class ConnectionWrapper < WEEL::ConnectionWrapperBase
@@ -36,6 +37,8 @@ class ConnectionWrapper < WEEL::ConnectionWrapperBase
36
37
  # TODO extract spot (code) where error happened for better error handling (ruby 3.1 only)
37
38
  # https://github.com/rails/rails/pull/45818/commits/3beb2aff3be712e44c34a588fbf35b79c0246ca5
38
39
  controller = arguments[0]
40
+ puts err.message
41
+ puts err.backtrace
39
42
  begin
40
43
  controller.notify("description/error", :message => err.backtrace[0].match(/(.*?)(, Line |:)(\d+):\s(.*)/)[4] + err.message, :line => err.backtrace[0].match(/(.*?)(, Line |:)(\d+):/)[3], :where => err.backtrace[0].match(/(.*?)(, Line |:)(\d+):/)[1])
41
44
  rescue => e
@@ -44,6 +47,8 @@ class ConnectionWrapper < WEEL::ConnectionWrapperBase
44
47
  end# }}}
45
48
  def self::inform_connectionwrapper_error(arguments,err) # {{{
46
49
  controller = arguments[0]
50
+ puts err.message
51
+ puts err.backtrace
47
52
  begin
48
53
  if err.backtrace[0] !~ /, Line/
49
54
  controller.notify("executionhandler/error", :message => err.backtrace[0].gsub(/(Activity a\d+)/,'\1:'), :line => -1, :where => err.backtrace[0].match(/Activity a\d+/)[0])
@@ -68,7 +73,7 @@ class ConnectionWrapper < WEEL::ConnectionWrapperBase
68
73
  @handler_continue = continue
69
74
  @handler_position = position
70
75
  @handler_passthrough = nil
71
- @handler_activity_uuid = Digest::MD5.hexdigest(Kernel::rand().to_s)
76
+ @handler_activity_uuid = SecureRandom.hex(16)
72
77
  @label = ''
73
78
  @guard_files = []
74
79
  @guard_items = []
@@ -93,7 +98,7 @@ class ConnectionWrapper < WEEL::ConnectionWrapperBase
93
98
 
94
99
  def proto_curl(parameters) #{{{
95
100
  params = []
96
- callback = Digest::MD5.hexdigest(Kernel::rand().to_s)
101
+ callback = SecureRandom.hex(16)
97
102
  (parameters[:arguments] || []).each do |s|
98
103
  if s.respond_to?(:mimetype)
99
104
  params << Riddl::Parameter::Complex.new(s.name.to_s,v.mimetype,v.value)
@@ -351,7 +356,7 @@ class ConnectionWrapper < WEEL::ConnectionWrapperBase
351
356
 
352
357
  def prepare(__lock,__dataelements,__endpoints,__status,__local,__additional,__code,__exec_endpoints,__exec_parameters) #{{{
353
358
  __struct = if __code
354
- manipulate(true,__lock,__dataelements,__endpoints,__status,__local,__additional,__code,'Parameter')
359
+ manipulate(true,__lock,__dataelements,__endpoints,__status,__local,__additional,__code,'prepare')
355
360
  else
356
361
  WEEL::ReadStructure.new(__dataelements,__endpoints,__local,__additional)
357
362
  end
@@ -376,7 +381,10 @@ class ConnectionWrapper < WEEL::ConnectionWrapperBase
376
381
  def test_condition(__eid,__dataelements,__endpoints,__local,__additional,__code,__args={}) #{{{
377
382
  __struct = WEEL::ReadStructure.new(__dataelements,__endpoints,__local,__additional).instance_eval(__code,'Condition',1)
378
383
 
379
- @controller.notify("gateway/decide", :eid => __eid, :instance_uuid => @controller.uuid, :code => __code, :condition => (__struct ? "true" : "false"))
384
+ __struct = 'false' unless __struct
385
+ __struct = (__struct == 'false' || __struct == 'null' || __struct == 'nil' || __struct == false ? false : true)
386
+
387
+ @controller.notify("gateway/decide", :eid => __eid, :instance_uuid => @controller.uuid, :code => __code, :condition => __struct)
380
388
  @controller.notify("gateway/annotation", :eid => __eid, :'activity-uuid' => @handler_activity_uuid, :label => @label, :activity => @handler_position, :annotations => {})
381
389
  __struct
382
390
  end #}}}
@@ -22,6 +22,7 @@ require 'cpee/attributes_helper'
22
22
  require 'cpee/message'
23
23
  require 'cpee/redis'
24
24
  require 'cpee/persistence'
25
+ require 'get_process_mem'
25
26
 
26
27
  require 'ostruct'
27
28
  class ParaStruct < OpenStruct
@@ -87,20 +88,25 @@ class Controller
87
88
  sleep 1
88
89
  retry
89
90
  end
91
+ Thread.new do
92
+ while true
93
+ notify("status/resource_utilization", :mib => GetProcessMem.new.mb, **Process.times.to_h)
94
+ sleep 3
95
+ end
96
+ end
90
97
  end
91
98
 
92
99
  attr_reader :id
93
100
  attr_reader :attributes
94
101
  attr_reader :loop_guard
95
102
 
96
- def uuid
97
- @attributes['uuid']
98
- end
99
-
100
103
  def attributes_translated
101
- @attributes_helper.translate(attributes,dataelements,endpoints)
104
+ @attributes_translated || @attributes_translated = @attributes_helper.translate(attributes,dataelements,endpoints)
102
105
  end
103
106
 
107
+ def uuid
108
+ @attributes['uuid']
109
+ end
104
110
  def host
105
111
  @opts[:host]
106
112
  end
@@ -178,7 +184,7 @@ class Controller
178
184
  votes = []
179
185
 
180
186
  CPEE::Persistence::extract_handler(id,@opts,handler).each do |client|
181
- voteid = Digest::MD5.hexdigest(Kernel::rand().to_s)
187
+ voteid = SecureRandom.hex(16)
182
188
  content[:key] = voteid
183
189
  content[:attributes] = attributes_translated
184
190
  content[:subscription] = client
@@ -15,6 +15,7 @@
15
15
  require 'charlock_holmes'
16
16
  require 'mimemagic'
17
17
  require 'base64'
18
+ require 'securerandom'
18
19
  require 'cpee-eval-ruby/translation'
19
20
 
20
21
  class ConnectionWrapper < WEEL::ConnectionWrapperBase
@@ -36,6 +37,8 @@ class ConnectionWrapper < WEEL::ConnectionWrapperBase
36
37
  # TODO extract spot (code) where error happened for better error handling (ruby 3.1 only)
37
38
  # https://github.com/rails/rails/pull/45818/commits/3beb2aff3be712e44c34a588fbf35b79c0246ca5
38
39
  controller = arguments[0]
40
+ puts err.message
41
+ puts err.backtrace
39
42
  begin
40
43
  controller.notify("description/error", :message => err.backtrace[0].match(/(.*?)(, Line |:)(\d+):\s(.*)/)[4] + err.message, :line => err.backtrace[0].match(/(.*?)(, Line |:)(\d+):/)[3], :where => err.backtrace[0].match(/(.*?)(, Line |:)(\d+):/)[1])
41
44
  rescue => e
@@ -44,7 +47,7 @@ class ConnectionWrapper < WEEL::ConnectionWrapperBase
44
47
  end# }}}
45
48
  def self::inform_connectionwrapper_error(arguments,err) # {{{
46
49
  controller = arguments[0]
47
- p err.message
50
+ puts err.message
48
51
  puts err.backtrace
49
52
  begin
50
53
  if err.backtrace[0] !~ /, Line/
@@ -70,7 +73,7 @@ class ConnectionWrapper < WEEL::ConnectionWrapperBase
70
73
  @handler_continue = continue
71
74
  @handler_position = position
72
75
  @handler_passthrough = nil
73
- @handler_activity_uuid = Digest::MD5.hexdigest(Kernel::rand().to_s)
76
+ @handler_activity_uuid = SecureRandom.hex(16)
74
77
  @label = ''
75
78
  @guard_files = []
76
79
  @guard_items = []
@@ -95,7 +98,7 @@ class ConnectionWrapper < WEEL::ConnectionWrapperBase
95
98
 
96
99
  def proto_curl(parameters) #{{{
97
100
  params = []
98
- callback = Digest::MD5.hexdigest(Kernel::rand().to_s)
101
+ callback = SecureRandom.hex(16)
99
102
  (parameters[:arguments] || []).each do |s|
100
103
  if s.respond_to?(:mimetype)
101
104
  params << Riddl::Parameter::Complex.new(s.name.to_s,v.mimetype,v.value)
@@ -369,79 +372,79 @@ class ConnectionWrapper < WEEL::ConnectionWrapperBase
369
372
  end
370
373
  end
371
374
 
372
- def argument_eval(code,struct)
375
+ def argument_eval(__code,__struct)
373
376
  send = []
374
- send.push Riddl::Parameter::Simple::new('code',code)
375
- send.push Riddl::Parameter::Complex::new('dataelements','application/json', JSON::generate(struct.data))
376
- send.push Riddl::Parameter::Complex::new('local','application/json', JSON::generate(struct.local)) if struct.local
377
- send.push Riddl::Parameter::Complex::new('endpoints','application/json', JSON::generate(struct.endpoints))
378
- send.push Riddl::Parameter::Complex::new('additional','application/json', JSON::generate(struct.additional))
377
+ send.push Riddl::Parameter::Simple::new('code',__code)
378
+ send.push Riddl::Parameter::Complex::new('dataelements','application/json', JSON::generate(__struct.data))
379
+ send.push Riddl::Parameter::Complex::new('local','application/json', JSON::generate(__struct.local)) if __struct.local
380
+ send.push Riddl::Parameter::Complex::new('endpoints','application/json', JSON::generate(__struct.endpoints))
381
+ send.push Riddl::Parameter::Complex::new('additional','application/json', JSON::generate(__struct.additional))
379
382
 
380
383
  status, ret, headers = Riddl::Client.new(@controller.url_code).request 'put' => send
381
384
  recv = if status >= 200 && status < 300
382
385
  ret.empty? ? nil : JSON::parse(ret[0].value.read)
383
386
  else
384
- code_error_handling ret, 'Parameter ' + code
387
+ code_error_handling ret, 'Parameter ' + __code
385
388
  end
386
389
  recv
387
390
  end
388
391
 
389
- def prepare(lock,dataelements,endpoints,status,local,additional,code,exec_endpoints,exec_parameters) #{{{
390
- struct = if code
391
- manipulate(true,lock,dataelements,endpoints,status,local,additional,code,'prepare')
392
+ def prepare(__lock,__dataelements,__endpoints,__status,__local,__additional,__code,__exec_endpoints,__exec_parameters) #{{{
393
+ __struct = if __code
394
+ manipulate(true,__lock,__dataelements,__endpoints,__status,__local,__additional,__code,'prepare')
392
395
  else
393
- WEEL::ReadStructure.new(dataelements,endpoints,local,additional)
396
+ WEEL::ReadStructure.new(__dataelements,__endpoints,__local,__additional)
394
397
  end
395
- @handler_endpoint = exec_endpoints.is_a?(Array) ? exec_endpoints.map{ |ep| struct.endpoints[ep] }.compact : struct.endpoints[exec_endpoints]
398
+ @handler_endpoint = __exec_endpoints.is_a?(Array) ? __exec_endpoints.map{ |ep| __struct.endpoints[ep] }.compact : __struct.endpoints[__exec_endpoints]
396
399
  if @controller.attributes['sim_engine']
397
400
  @handler_endpoint_orig = @handler_endpoint
398
401
  @handler_endpoint = @controller.attributes['sim_engine'].to_s + '?original_endpoint=' + Riddl::Protocols::Utils::escape(@handler_endpoint)
399
402
  end
400
- params = exec_parameters.dup
401
- params[:arguments] = params[:arguments].dup if params[:arguments]
402
- params[:arguments]&.map! do |ele|
403
- t = ele.dup
404
- if t.value.is_a?(WEEL::ProcString)
405
- t.value = argument_eval t.value.code, struct
406
- elsif t.value.is_a?(Array) || t.value.is_a?(Hash)
407
- argument_transform_value t.value, struct
403
+ __params = __exec_parameters.dup
404
+ __params[:arguments] = __params[:arguments].dup if __params[:arguments]
405
+ __params[:arguments]&.map! do |__ele|
406
+ __tmp = __ele.dup
407
+ if __tmp.value.is_a?(WEEL::ProcString)
408
+ __tmp.value = argument_eval(__tmp.value.code, __struct)
409
+ elsif __tmp.value.is_a?(Array) || __tmp.value.is_a?(Hash)
410
+ argument_transform_value __tmp.value, __struct
408
411
  end
409
- t
412
+ __tmp
410
413
  end
411
- params
414
+ __params
412
415
  end #}}}
413
- def test_condition(eid,dataelements,endpoints,local,additional,code,args={}) #{{{
416
+ def test_condition(__eid,__dataelements,__endpoints,__local,__additional,__code,__args={}) #{{{
414
417
  send = []
415
- send.push Riddl::Parameter::Simple::new('code',code)
416
- send.push Riddl::Parameter::Complex::new('dataelements','application/json', JSON::generate(dataelements))
417
- send.push Riddl::Parameter::Complex::new('local','application/json', JSON::generate(local)) if local
418
- send.push Riddl::Parameter::Complex::new('endpoints','application/json', JSON::generate(endpoints))
419
- send.push Riddl::Parameter::Complex::new('additional','application/json', JSON::generate(additional))
418
+ send.push Riddl::Parameter::Simple::new('code',__code)
419
+ send.push Riddl::Parameter::Complex::new('dataelements','application/json', JSON::generate(__dataelements))
420
+ send.push Riddl::Parameter::Complex::new('local','application/json', JSON::generate(__local)) if __local
421
+ send.push Riddl::Parameter::Complex::new('endpoints','application/json', JSON::generate(__endpoints))
422
+ send.push Riddl::Parameter::Complex::new('additional','application/json', JSON::generate(__additional))
420
423
 
421
424
  status, ret, headers = Riddl::Client.new(@controller.url_code).request 'put' => send
422
- recv = if status >= 200 && status < 300
425
+ __struct = if status >= 200 && status < 300
423
426
  ret.empty? ? nil : JSON::parse(ret[0].value.read)
424
427
  else
425
428
  code_error_handling ret, 'Condition ' + code, WEEL::Signal::Error
426
429
  end
427
- recv = 'false' unless recv
428
- recv = (recv == 'false' || recv == 'null' || recv == 'nil' || recv == false ? false : true)
430
+ __struct = 'false' unless __struct
431
+ __struct = (__struct == 'false' || __struct == 'null' || __struct == 'nil' || __struct == false ? false : true)
429
432
 
430
- @controller.notify("gateway/decide", :eid => eid, :instance_uuid => @controller.uuid, :code => code, :condition => recv)
431
- @controller.notify("gateway/annotation", :eid => eid, :'activity-uuid' => @handler_activity_uuid, :label => @label, :activity => @handler_position, :annotations => {})
432
- recv
433
+ @controller.notify("gateway/decide", :eid => __eid, :instance_uuid => @controller.uuid, :code => __code, :condition => __struct)
434
+ @controller.notify("gateway/annotation", :eid => __eid, :'activity-uuid' => @handler_activity_uuid, :label => @label, :activity => @handler_position, :annotations => {})
435
+ __struct
433
436
  end #}}}
434
- def manipulate(readonly,lock,dataelements,endpoints,status,local,additional,code,where,result=nil,options=nil) #{{{
435
- lock.synchronize do
437
+ def manipulate(__readonly,__lock,__dataelements,__endpoints,__status,__local,__additional,__code,__where,__result=nil,__options=nil) #{{{
438
+ __lock.synchronize do
436
439
  send = []
437
- send.push Riddl::Parameter::Simple::new('code',code)
438
- send.push Riddl::Parameter::Complex::new('dataelements','application/json', JSON::generate(dataelements))
439
- send.push Riddl::Parameter::Complex::new('local','application/json', JSON::generate(local)) if local
440
- send.push Riddl::Parameter::Complex::new('endpoints','application/json', JSON::generate(endpoints))
441
- send.push Riddl::Parameter::Complex::new('additional','application/json', JSON::generate(additional))
442
- send.push Riddl::Parameter::Complex::new('status','application/json', JSON::generate(status)) if status
443
- send.push Riddl::Parameter::Complex::new('call_result','application/json', JSON::generate(result))
444
- send.push Riddl::Parameter::Complex::new('call_headers','application/json', JSON::generate(options))
440
+ send.push Riddl::Parameter::Simple::new('code',__code)
441
+ send.push Riddl::Parameter::Complex::new('dataelements','application/json', JSON::generate(__dataelements))
442
+ send.push Riddl::Parameter::Complex::new('local','application/json', JSON::generate(__local)) if __local
443
+ send.push Riddl::Parameter::Complex::new('endpoints','application/json', JSON::generate(__endpoints))
444
+ send.push Riddl::Parameter::Complex::new('additional','application/json', JSON::generate(__additional))
445
+ send.push Riddl::Parameter::Complex::new('status','application/json', JSON::generate(__status)) if __status
446
+ send.push Riddl::Parameter::Complex::new('call_result','application/json', JSON::generate(__result))
447
+ send.push Riddl::Parameter::Complex::new('call_headers','application/json', JSON::generate(__options))
445
448
 
446
449
  stat, ret, headers = Riddl::Client.new(@controller.url_code).request 'put' => send
447
450
 
@@ -454,16 +457,16 @@ class ConnectionWrapper < WEEL::ConnectionWrapperBase
454
457
  changed_endpoints = JSON::parse(ret.shift.value.read) if ret.any? && ret[0].name == 'changed_endpoints'
455
458
  changed_status = JSON::parse(ret.shift.value.read) if ret.any? && ret[0].name == 'changed_status'
456
459
 
457
- struct = if readonly
458
- WEEL::ReadStructure.new(dataelements,endpoints,local,additional)
460
+ __struct = if __readonly
461
+ WEEL::ReadStructure.new(__dataelements,__endpoints,__local,__additional)
459
462
  else
460
- WEEL::ManipulateStructure.new(dataelements, endpoints, status, local, additional)
463
+ WEEL::ManipulateStructure.new(__dataelements, __endpoints, __status, __local, __additional)
461
464
  end
462
- struct.update(changed_dataelements,changed_endpoints,changed_status)
465
+ __struct.update(changed_dataelements,changed_endpoints,changed_status)
463
466
 
464
- struct
467
+ __struct
465
468
  else
466
- code_error_handling ret, where
469
+ code_error_handling ret, __where
467
470
  end
468
471
  end
469
472
  end #}}}
@@ -100,14 +100,13 @@ class Controller
100
100
  attr_reader :attributes
101
101
  attr_reader :loop_guard
102
102
 
103
- def uuid
104
- @attributes['uuid']
105
- end
106
-
107
103
  def attributes_translated
108
- @attributes_helper.translate(attributes,dataelements,endpoints)
104
+ @attributes_translated || @attributes_translated = @attributes_helper.translate(attributes,dataelements,endpoints)
109
105
  end
110
106
 
107
+ def uuid
108
+ @attributes['uuid']
109
+ end
111
110
  def host
112
111
  @opts[:host]
113
112
  end
@@ -185,7 +184,7 @@ class Controller
185
184
  votes = []
186
185
 
187
186
  CPEE::Persistence::extract_handler(id,@opts,handler).each do |client|
188
- voteid = Digest::MD5.hexdigest(Kernel::rand().to_s)
187
+ voteid = SecureRandom.hex(16)
189
188
  content[:key] = voteid
190
189
  content[:attributes] = attributes_translated
191
190
  content[:subscription] = client
@@ -1 +1 @@
1
- 209439
1
+ 2029031
@@ -41,11 +41,11 @@ Daemonite.new do |opts|
41
41
  instance, uuid = message[0...index].split(',')
42
42
  opts[:redis].multi do |multi|
43
43
  multi.srem("instance:#{instance}/callbacks",key)
44
- multi.del("instance:#{instance}/callback/#{key}/uuid")
45
- multi.del("instance:#{instance}/callback/#{key}/label")
46
- multi.del("instance:#{instance}/callback/#{key}/position")
47
- multi.del("instance:#{instance}/callback/#{key}/type")
48
- multi.del("instance:#{instance}/callback/#{key}/subscription")
44
+ multi.del("instance:#{instance}/callbacks/#{key}/uuid")
45
+ multi.del("instance:#{instance}/callbacks/#{key}/label")
46
+ multi.del("instance:#{instance}/callbacks/#{key}/position")
47
+ multi.del("instance:#{instance}/callbacks/#{key}/type")
48
+ multi.del("instance:#{instance}/callbacks/#{key}/subscription")
49
49
  end
50
50
  rescue => e
51
51
  puts e.message
@@ -1 +1 @@
1
- 209481
1
+ 2029049
@@ -16,9 +16,12 @@
16
16
 
17
17
  require 'redis'
18
18
  require 'daemonite'
19
+ require 'concurrent-ruby'
19
20
  require 'riddl/client'
20
21
  require_relative '../../lib/cpee/redis'
21
22
 
23
+ HTTP_POOL = Concurrent::FixedThreadPool.new(32)
24
+
22
25
  Daemonite.new do |opts|
23
26
  opts[:runtime_opts] += [
24
27
  ["--url=URL", "-uURL", "Specify redis url", ->(p){ opts[:redis_url] = p }],
@@ -48,32 +51,35 @@ Daemonite.new do |opts|
48
51
  topic = ::File::dirname(event)
49
52
  name = ::File::basename(event)
50
53
  long = File.join(topic,type,name)
51
- opts[:redis].smembers("instance:#{instance}/handlers").each do |key|
52
- if opts[:redis].smembers("instance:#{instance}/handlers/#{key}").include? long
53
- url = opts[:redis].get("instance:#{instance}/handlers/#{key}/url")
54
- if url.nil? || url == ""
55
- opts[:redis].publish("forward:#{instance}/#{key}",mess)
56
- else
57
- # Ractor.new(url,type,topic,name,mess) do |url,type,topic,name,mess|
58
- # sadly typhoes does not support ractors
59
- Thread.new do
60
- Riddl::Client.new(url).post [
61
- Riddl::Header.new("CPEE-INSTANCE",instance),
62
- Riddl::Header.new("CPEE-INSTANCE-UUID",uuid),
63
- Riddl::Parameter::Simple::new('type',type),
64
- Riddl::Parameter::Simple::new('topic',topic),
65
- Riddl::Parameter::Simple::new('event',name),
66
- Riddl::Parameter::Complex::new('notification','application/json',mess)
67
- ]
68
- end
54
+
55
+ keys = opts[:redis].smembers("instance:#{instance}/handlers")
56
+ checks = opts[:redis].pipelined { |p| keys.each { |k| p.sismember("instance:#{instance}/handlers/#{k}", long) } }
57
+ matched = keys.zip(checks).select { |_, hit| hit }.map(&:first)
58
+ urls = opts[:redis].pipelined { |p| matched.each { |k| p.get("instance:#{instance}/handlers/#{k}/url") } }
59
+ matched.zip(urls).each do |key, url|
60
+ if url.nil? || url == ""
61
+ opts[:redis].publish("forward:#{instance}/#{key}",mess)
62
+ else
63
+ # Ractor.new(url,type,topic,name,mess) do |url,type,topic,name,mess|
64
+ # sadly typhoes does not support ractors
65
+ HTTP_POOL.post do
66
+ Riddl::Client.new(url).post [
67
+ Riddl::Header.new("CPEE-INSTANCE",instance),
68
+ Riddl::Header.new("CPEE-INSTANCE-UUID",uuid),
69
+ Riddl::Parameter::Simple::new('type',type),
70
+ Riddl::Parameter::Simple::new('topic',topic),
71
+ Riddl::Parameter::Simple::new('event',name),
72
+ Riddl::Parameter::Complex::new('notification','application/json',mess)
73
+ ]
69
74
  end
70
75
  end
71
76
  end
72
77
  unless opts[:redis].exists?("instance:#{instance}/state")
73
- empt = opts[:redis].keys("instance:#{instance}/*").to_a
74
- opts[:redis].multi do |multi|
75
- multi.del empt
76
- end
78
+ ### delete everything under instance
79
+ ### how can there be stuff under an instance (handlers, subscriptions)? Are they created later?
80
+ empt = []
81
+ opts[:redis].scan_each("instance:#{instance}/*") { |k| empt << k }
82
+ opts[:redis].del(*empt) unless empt.empty?
77
83
  end
78
84
  rescue => e
79
85
  puts e.message
@@ -1 +1 @@
1
- 209467
1
+ 2029043
@@ -24,11 +24,11 @@ require_relative '../../lib/cpee/redis'
24
24
  def persist_handler(instance,key,mess,redis) #{{{
25
25
  redis.multi do |multi|
26
26
  multi.sadd("instance:#{instance}/callbacks",key)
27
- multi.set("instance:#{instance}/callback/#{key}/subscription",mess.dig('content','subscription'))
28
- multi.set("instance:#{instance}/callback/#{key}/uuid",mess.dig('content','activity-uuid'))
29
- multi.set("instance:#{instance}/callback/#{key}/label",mess.dig('content','label'))
30
- multi.set("instance:#{instance}/callback/#{key}/position",mess.dig('content','activity'))
31
- multi.set("instance:#{instance}/callback/#{key}/type",'vote')
27
+ multi.set("instance:#{instance}/callbacks/#{key}/subscription",mess.dig('content','subscription'))
28
+ multi.set("instance:#{instance}/callbacks/#{key}/uuid",mess.dig('content','activity-uuid'))
29
+ multi.set("instance:#{instance}/callbacks/#{key}/label",mess.dig('content','label'))
30
+ multi.set("instance:#{instance}/callbacks/#{key}/position",mess.dig('content','activity'))
31
+ multi.set("instance:#{instance}/callbacks/#{key}/type",'vote')
32
32
  end
33
33
  end #}}}
34
34
 
@@ -1 +1 @@
1
- 209453
1
+ 2029037
@@ -66,10 +66,10 @@ Daemonite.new do |opts|
66
66
  key = mess.dig('content','key')
67
67
  opts[:redis].multi do |multi|
68
68
  multi.sadd("instance:#{instance}/callbacks",key)
69
- multi.set("instance:#{instance}/callback/#{key}/uuid",mess.dig('content','activity-uuid'))
70
- multi.set("instance:#{instance}/callback/#{key}/label",mess.dig('content','label'))
71
- multi.set("instance:#{instance}/callback/#{key}/position",mess.dig('content','activity'))
72
- multi.set("instance:#{instance}/callback/#{key}/type",'callback')
69
+ multi.set("instance:#{instance}/callbacks/#{key}/uuid",mess.dig('content','activity-uuid'))
70
+ multi.set("instance:#{instance}/callbacks/#{key}/label",mess.dig('content','label'))
71
+ multi.set("instance:#{instance}/callbacks/#{key}/position",mess.dig('content','activity'))
72
+ multi.set("instance:#{instance}/callbacks/#{key}/type",'callback')
73
73
  end
74
74
  when /event:\d+:state\/change/
75
75
  opts[:redis].multi do |multi|
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cpee
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.118
4
+ version: 2.1.120
5
5
  platform: ruby
6
6
  authors:
7
7
  - Juergen eTM Mangler
@@ -191,6 +191,26 @@ dependencies:
191
191
  - - ">="
192
192
  - !ruby/object:Gem::Version
193
193
  version: 1.1.0
194
+ - !ruby/object:Gem::Dependency
195
+ name: concurrent-ruby
196
+ requirement: !ruby/object:Gem::Requirement
197
+ requirements:
198
+ - - "~>"
199
+ - !ruby/object:Gem::Version
200
+ version: '1.3'
201
+ - - ">="
202
+ - !ruby/object:Gem::Version
203
+ version: 1.3.5
204
+ type: :runtime
205
+ prerelease: false
206
+ version_requirements: !ruby/object:Gem::Requirement
207
+ requirements:
208
+ - - "~>"
209
+ - !ruby/object:Gem::Version
210
+ version: '1.3'
211
+ - - ">="
212
+ - !ruby/object:Gem::Version
213
+ version: 1.3.5
194
214
  description: see http://cpee.org
195
215
  email: juergen.mangler@gmail.com
196
216
  executables:
@@ -294,6 +314,7 @@ files:
294
314
  - cockpit/templates/IUPC arXiv:1104.3609 P34 2.xml
295
315
  - cockpit/templates/IUPC arXiv:1104.3609 P34 3.xml
296
316
  - cockpit/templates/ML-pipe-multi.xml
317
+ - cockpit/templates/Readonly Local.xml
297
318
  - cockpit/templates/Subprocess.xml
298
319
  - cockpit/templates/Subprocess.xml.attrs
299
320
  - cockpit/templates/Track Test Local.xml