cpee 2.1.121 → 2.1.123
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 +4 -4
- data/cockpit/js/instance.js +0 -19
- data/cockpit/js/modifiers.js +4 -3
- data/cpee.gemspec +2 -1
- data/lib/cpee/implementation_properties.rb +7 -6
- data/lib/cpee/persistence.rb +43 -8
- data/server/executionhandlers/eval/connection.rb +5 -2
- data/server/executionhandlers/eval/controller.rb +1 -0
- data/server/executionhandlers/eval/execution.rb +32 -17
- data/server/executionhandlers/ruby/connection.rb +18 -9
- data/server/executionhandlers/ruby/controller.rb +4 -8
- data/server/executionhandlers/ruby/dsl_to_dslx.xsl +6 -3
- data/server/executionhandlers/ruby/execution.rb +31 -17
- data/server/resources/topics.xml +1 -0
- data/server/routing/end.pid +1 -1
- data/server/routing/forward-events-00.pid +1 -1
- data/server/routing/forward-votes.pid +1 -1
- data/server/routing/persist.pid +1 -1
- data/server/routing/persist.rb +9 -1
- metadata +15 -1
- data/server/executionhandlers/eval/controller.rb +0 -226
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 63c48292c70c40336ce8385bb86fbea2722ebb3becbfe091843f5d7f60268d0c
|
|
4
|
+
data.tar.gz: 8b53f0ea495c73ccc423ad1cbca5c764928fdee41ab7af9c853f725c3dc3ed34
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 977f66a12107bd16c154d55320a3d1f42bf15713419e50dcf1456532dffd332b6d465ec97f2721b61b3ec0d50aab5768b3dabb77a8ecc87ae3e78f63aa63ac77
|
|
7
|
+
data.tar.gz: 6038b1ba120f2b8ca11e53f5b00987658c6789f33382c215be5bcf5b252f88d3e215c3a4281d614236a40bd93926e2bd4ab90ddb49f97195f67fdead80b5411d
|
data/cockpit/js/instance.js
CHANGED
|
@@ -1172,25 +1172,6 @@ async function set_testset(testset,exec) {// {{{
|
|
|
1172
1172
|
await Promise.all(promises);
|
|
1173
1173
|
|
|
1174
1174
|
document.dispatchEvent(model_loaded);
|
|
1175
|
-
|
|
1176
|
-
$.ajax({
|
|
1177
|
-
type: "GET",
|
|
1178
|
-
url: url + "/properties/state/",
|
|
1179
|
-
dataType: "text",
|
|
1180
|
-
success: function(res){
|
|
1181
|
-
$.ajax({
|
|
1182
|
-
type: "PUT",
|
|
1183
|
-
url: url + "/properties/state/",
|
|
1184
|
-
data: ({value: res}),
|
|
1185
|
-
error: report_failure,
|
|
1186
|
-
success: function(res){
|
|
1187
|
-
if (exec) start_instance();
|
|
1188
|
-
}
|
|
1189
|
-
});
|
|
1190
|
-
}
|
|
1191
|
-
});
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
1175
|
}// }}}
|
|
1195
1176
|
|
|
1196
1177
|
function load_testsetfile_after() { //{{{
|
data/cockpit/js/modifiers.js
CHANGED
|
@@ -143,10 +143,11 @@ function modifiers_select() {
|
|
|
143
143
|
let top = $(r).attr('data-resource');
|
|
144
144
|
let it = $(s).attr('value');
|
|
145
145
|
$('select',r).val(it);
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
146
|
+
if (typeof(save['modifiers_active'][top]) == "undefined") {
|
|
147
|
+
// set for page load
|
|
148
|
+
save['modifiers_active'][top] = it;
|
|
149
149
|
}
|
|
150
|
+
modifiers_display_ui(rep + 'modifiers/',top,it,save['modifiers_active'][top] == it);
|
|
150
151
|
save['modifiers_active'][top] = it;
|
|
151
152
|
}
|
|
152
153
|
});
|
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.
|
|
3
|
+
s.version = "2.1.123"
|
|
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."
|
|
@@ -32,6 +32,7 @@ Gem::Specification.new do |s|
|
|
|
32
32
|
s.add_runtime_dependency 'mimemagic', '~>0'
|
|
33
33
|
s.add_runtime_dependency 'get_process_mem', '~>0.2'
|
|
34
34
|
s.add_runtime_dependency 'webrick', '~>1.7'
|
|
35
|
+
s.add_runtime_dependency 'msgpack', '~>1.8'
|
|
35
36
|
s.add_runtime_dependency 'by', '~> 1.1', '>= 1.1.0'
|
|
36
37
|
s.add_runtime_dependency 'concurrent-ruby', '~> 1.3', '>= 1.3.5'
|
|
37
38
|
end
|
|
@@ -158,7 +158,11 @@ module CPEE
|
|
|
158
158
|
CPEE::Properties::PutStatus::set id, opts, node.first.dump
|
|
159
159
|
end
|
|
160
160
|
if (node = doc.find('/p:properties/p:executionhandler')).any?
|
|
161
|
-
|
|
161
|
+
if doc.find('/p:properties/p:description/*').any?
|
|
162
|
+
CPEE::Properties::PutExecutionHandler::set id, opts, node.first.text, false
|
|
163
|
+
else
|
|
164
|
+
CPEE::Properties::PutExecutionHandler::set id, opts, node.first.text
|
|
165
|
+
end
|
|
162
166
|
end
|
|
163
167
|
|
|
164
168
|
%w{dataelements endpoints attributes}.each do |item|
|
|
@@ -424,10 +428,7 @@ module CPEE
|
|
|
424
428
|
doc.find("/*/*").each do |ele|
|
|
425
429
|
val[ele.qname.name] = ele.text unless val.has_key?(ele.qname.name)
|
|
426
430
|
end
|
|
427
|
-
|
|
428
|
-
newkeys = val.keys
|
|
429
|
-
del = oldkeys - newkeys
|
|
430
|
-
CPEE::Persistence::set_list(id,opts,item,val,del)
|
|
431
|
+
CPEE::Persistence::set_list(id,opts,item,val,true,true)
|
|
431
432
|
end
|
|
432
433
|
|
|
433
434
|
def response
|
|
@@ -514,7 +515,7 @@ module CPEE
|
|
|
514
515
|
@status = 410
|
|
515
516
|
else
|
|
516
517
|
if CPEE::Persistence::extract_item(id,opts,@r.join('/'))
|
|
517
|
-
CPEE::Persistence::set_list(id,opts,item,val,val.keys)
|
|
518
|
+
CPEE::Persistence::set_list(id,opts,item,val,false,true,val.keys)
|
|
518
519
|
else
|
|
519
520
|
@status = 404
|
|
520
521
|
end
|
data/lib/cpee/persistence.rb
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
# CPEE (file COPYING in the main directory). If not, see
|
|
13
13
|
# <http://www.gnu.org/licenses/>.
|
|
14
14
|
|
|
15
|
+
require 'msgpack'
|
|
15
16
|
require_relative 'attributes_helper'
|
|
16
17
|
require_relative 'message'
|
|
17
18
|
|
|
@@ -30,26 +31,60 @@ module CPEE
|
|
|
30
31
|
CPEE::Message::wait(opts[:redis],opts[:redis_dyn].call('Temporary Storage Transaction Subscriber'))
|
|
31
32
|
end
|
|
32
33
|
|
|
33
|
-
def self::set_list(id,opts,item,values,
|
|
34
|
+
def self::set_list(id,opts,item,values,diff=false,delete=false,deletions=[]) #{{{
|
|
34
35
|
ah = AttributesHelper.new
|
|
35
36
|
attributes = Persistence::extract_list(id,opts,'attributes').to_h
|
|
36
37
|
dataelements = Persistence::extract_list(id,opts,'dataelements').to_h
|
|
37
38
|
endpoints = Persistence::extract_list(id,opts,'endpoints').to_h
|
|
39
|
+
oldvalues = case item
|
|
40
|
+
when 'attributes' then attributes
|
|
41
|
+
when 'endpoints' then endpoints
|
|
42
|
+
when 'dataelements' then dataelements
|
|
43
|
+
end
|
|
44
|
+
sort = []
|
|
45
|
+
if diff
|
|
46
|
+
deletions = oldvalues.keys - values.keys
|
|
47
|
+
if oldvalues.length > 1 && oldvalues.length == values.length && deletions.length == 0 && oldvalues.keys != values.keys
|
|
48
|
+
sort = values.keys
|
|
49
|
+
end
|
|
50
|
+
values.delete_if do |k,v|
|
|
51
|
+
oldvalues[k] && oldvalues[k] == v
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
payload = {
|
|
55
|
+
:values => oldvalues.merge(values).transform_values{|val| JSON::parse(val) rescue val },
|
|
56
|
+
:attributes => ah.translate(attributes,dataelements,endpoints)
|
|
57
|
+
}
|
|
38
58
|
CPEE::Message::send(
|
|
39
59
|
:event,
|
|
40
|
-
File.join(item,'
|
|
60
|
+
File.join(item,'modify'),
|
|
41
61
|
opts[:url],
|
|
42
62
|
id,
|
|
43
63
|
Persistence::extract_item(id,opts,'attributes/uuid'),
|
|
44
64
|
Persistence::extract_item(id,opts,'attributes/info'),
|
|
45
|
-
|
|
46
|
-
:changed => values.keys,
|
|
47
|
-
:deleted => deleted,
|
|
48
|
-
:values => values.transform_values{|val| JSON::parse(val) rescue val },
|
|
49
|
-
:attributes => ah.translate(attributes,dataelements,endpoints),
|
|
50
|
-
},
|
|
65
|
+
payload,
|
|
51
66
|
opts[:redis]
|
|
52
67
|
)
|
|
68
|
+
payload[:values] = values.transform_values{|val| JSON::parse(val) rescue val }
|
|
69
|
+
payload[:changed] = values.keys
|
|
70
|
+
if delete
|
|
71
|
+
payload[:deleted] = deletions
|
|
72
|
+
end
|
|
73
|
+
if sort.any?
|
|
74
|
+
payload[:sort] = sort
|
|
75
|
+
end
|
|
76
|
+
if values.any? || deletions.any? || sort.any?
|
|
77
|
+
CPEE::Message::send(
|
|
78
|
+
:event,
|
|
79
|
+
File.join(item,'change'),
|
|
80
|
+
opts[:url],
|
|
81
|
+
id,
|
|
82
|
+
Persistence::extract_item(id,opts,'attributes/uuid'),
|
|
83
|
+
Persistence::extract_item(id,opts,'attributes/info'),
|
|
84
|
+
payload,
|
|
85
|
+
opts[:redis]
|
|
86
|
+
)
|
|
87
|
+
end
|
|
53
88
|
end #}}}
|
|
54
89
|
def self::extract_set(id,opts,item) #{{{
|
|
55
90
|
opts[:redis].smembers(@@obj + ":#{id}/#{item}").map do |e|
|
|
@@ -29,9 +29,12 @@ class ConnectionWrapper < WEEL::ConnectionWrapperBase
|
|
|
29
29
|
tso + 2 > tsn && count > 100
|
|
30
30
|
end # }}}
|
|
31
31
|
|
|
32
|
-
def self::inform_state_change(arguments,newstate) # {{{
|
|
32
|
+
def self::inform_state_change(arguments,newstate,data) # {{{
|
|
33
33
|
controller = arguments[0]
|
|
34
|
-
controller.notify(
|
|
34
|
+
controller.notify('state/change', :state => newstate)
|
|
35
|
+
if newstate == :stopped || newstate == :finished
|
|
36
|
+
controller.notify('dataelements/modify', :eid => 'ex-post', :values => data)
|
|
37
|
+
end
|
|
35
38
|
end # }}}
|
|
36
39
|
def self::inform_syntax_error(arguments,err,code)# {{{
|
|
37
40
|
# TODO extract spot (code) where error happened for better error handling (ruby 3.1 only)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
../ruby/controller.rb
|
|
@@ -19,21 +19,22 @@ module CPEE
|
|
|
19
19
|
|
|
20
20
|
module ExecutionHandler
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
BACKEND_INSTANCE = 'instance.rb'
|
|
24
|
-
DSL_TO_DSLX_XSL = File.expand_path(File.join(__dir__,'dsl_to_dslx.xsl'))
|
|
25
|
-
BACKEND_RUN = File.expand_path(File.join(__dir__,'backend','run.rb'))
|
|
26
|
-
BACKEND_OPTS = File.expand_path(File.join(__dir__,'backend','opts.yaml'))
|
|
27
|
-
BACKEND_TEMPLATE = File.expand_path(File.join(__dir__,'backend','instance.template'))
|
|
22
|
+
self.const_set File.basename(__dir__).capitalize, Module.new {
|
|
23
|
+
self::BACKEND_INSTANCE = 'instance.rb'
|
|
24
|
+
self::DSL_TO_DSLX_XSL = File.expand_path(File.join(__dir__,'dsl_to_dslx.xsl'))
|
|
25
|
+
self::BACKEND_RUN = File.expand_path(File.join(__dir__,'backend','run.rb'))
|
|
26
|
+
self::BACKEND_OPTS = File.expand_path(File.join(__dir__,'backend','opts.yaml'))
|
|
27
|
+
self::BACKEND_TEMPLATE = File.expand_path(File.join(__dir__,'backend','instance.template'))
|
|
28
28
|
|
|
29
29
|
def self::dslx_to_dsl(dslx,ep) # transpile
|
|
30
|
-
trans = XML::Smart::open_unprotected(
|
|
30
|
+
trans = XML::Smart::open_unprotected(self::DSL_TO_DSLX_XSL)
|
|
31
31
|
dslx.transform_with(trans).to_s
|
|
32
32
|
end
|
|
33
33
|
|
|
34
34
|
def self::prepare(id,opts) # write result to disk
|
|
35
|
+
FileUtils.rm_rf(Dir.glob(File.join(opts[:instances],id.to_s,'*')) + Dir.glob(File.join(opts[:instances],id.to_s,'.remote')))
|
|
35
36
|
Dir.mkdir(File.join(opts[:instances],id.to_s)) rescue nil
|
|
36
|
-
FileUtils.copy(
|
|
37
|
+
FileUtils.copy(self::BACKEND_RUN,File.join(opts[:instances],id.to_s))
|
|
37
38
|
dsl = CPEE::Persistence::extract_item(id,opts,'dsl')
|
|
38
39
|
hw = CPEE::Persistence::extract_item(id,opts,'executionhandler')
|
|
39
40
|
endpoints = CPEE::Persistence::extract_list(id,opts,'endpoints')
|
|
@@ -43,7 +44,8 @@ module CPEE
|
|
|
43
44
|
positions.map! do |k, v|
|
|
44
45
|
[ k, v, CPEE::Persistence::extract_item(id,opts,File.join('positions',k,'@passthrough')) ]
|
|
45
46
|
end
|
|
46
|
-
iopts = YAML::load_file(
|
|
47
|
+
iopts = YAML::load_file(self::BACKEND_OPTS)
|
|
48
|
+
iopts[:instance_id] = id
|
|
47
49
|
iopts[:host] = opts[:host]
|
|
48
50
|
iopts[:url] = opts[:url]
|
|
49
51
|
iopts[:redis_url] = opts[:redis_url]
|
|
@@ -57,13 +59,26 @@ module CPEE
|
|
|
57
59
|
iopts[:executionhandlers] = opts[:executionhandlers]
|
|
58
60
|
iopts[:global_executionhandlers] = opts[:global_executionhandlers]
|
|
59
61
|
end
|
|
62
|
+
iopts[:attributes] = attributes
|
|
63
|
+
iopts[:votes] = {}
|
|
64
|
+
CPEE::Persistence::extract_handlers(id,opts).each do |de|
|
|
65
|
+
if de[1] && de[1]&.empty?.!
|
|
66
|
+
CPEE::Persistence::extract_handler(id,opts,de[0]).each do |ele|
|
|
67
|
+
topic, type, name = ele.split('/')
|
|
68
|
+
if type == 'vote'
|
|
69
|
+
iopts[:votes][ele] ||= []
|
|
70
|
+
iopts[:votes][ele] << de[0]
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
60
75
|
|
|
61
|
-
File.open(File.join(opts[:instances],id.to_s,File.basename(
|
|
76
|
+
File.open(File.join(opts[:instances],id.to_s,File.basename(self::BACKEND_OPTS)),'w') do |f|
|
|
62
77
|
YAML::dump(iopts,f)
|
|
63
78
|
end
|
|
64
|
-
template = ERB.new(File.read(
|
|
79
|
+
template = ERB.new(File.read(self::BACKEND_TEMPLATE), trim_mode: '-')
|
|
65
80
|
res = template.result_with_hash(dsl: dsl, dataelements: dataelements, endpoints: endpoints, positions: positions)
|
|
66
|
-
File.write(File.join(opts[:instances],id.to_s,
|
|
81
|
+
File.write(File.join(opts[:instances],id.to_s,self::BACKEND_INSTANCE),res)
|
|
67
82
|
if attributes.has_key?('remote')
|
|
68
83
|
uri = URI::parse(attributes['remote'])
|
|
69
84
|
Net::SSH.start(uri.host,uri.user,:keys => [ opts[:ssh_key] ] ) do |ssh|
|
|
@@ -77,12 +92,12 @@ module CPEE
|
|
|
77
92
|
def self::run(id,opts)
|
|
78
93
|
if File.exist? File.join(opts[:instances],id.to_s,'.remote')
|
|
79
94
|
uri = URI::parse(File.read(File.join(opts[:instances],id.to_s,'.remote')))
|
|
80
|
-
exe = File.join(uri.path,id.to_s,File.basename(BACKEND_RUN))
|
|
95
|
+
exe = File.join(uri.path,id.to_s,File.basename(self::BACKEND_RUN))
|
|
81
96
|
Net::SSH.start(uri.host,uri.user,:keys => [ opts[:ssh_key] ] ) do |ssh|
|
|
82
97
|
ssh.exec!("ruby #{exe} >#{exe}.out 2>#{exe}.err &")
|
|
83
98
|
end
|
|
84
99
|
else
|
|
85
|
-
exe = File.join(opts[:instances],id.to_s,File.basename(
|
|
100
|
+
exe = File.join(opts[:instances],id.to_s,File.basename(self::BACKEND_RUN))
|
|
86
101
|
pid = Kernel.spawn(opts[:libs_preloaderrun] + ' ' + exe , :pgroup => true, :in => '/dev/null', :out => exe + '.out', :err => exe + '.err')
|
|
87
102
|
Process.detach pid
|
|
88
103
|
File.write(exe + '.pid',pid)
|
|
@@ -92,7 +107,7 @@ module CPEE
|
|
|
92
107
|
def self::stop(id,opts) ### return: bool to tell if manually changing redis is necessary
|
|
93
108
|
if File.exist? File.join(opts[:instances],id.to_s,'.remote')
|
|
94
109
|
uri = URI::parse(File.read(File.join(opts[:instances],id.to_s,'.remote')))
|
|
95
|
-
exe = File.join(uri.path,id.to_s,File.basename(BACKEND_RUN))
|
|
110
|
+
exe = File.join(uri.path,id.to_s,File.basename(self::BACKEND_RUN))
|
|
96
111
|
Net::SSH.start(uri.host,uri.user,:keys => [ opts[:ssh_key] ] ) do |ssh|
|
|
97
112
|
pid = ssh.exec!("cat #{exe}.pid 2>/dev/null")
|
|
98
113
|
if pid != '' && ssh.exec!("kill -0 #{pid} >/dev/null 2>&1; echo $?").strip == '0'
|
|
@@ -104,7 +119,7 @@ module CPEE
|
|
|
104
119
|
end
|
|
105
120
|
end
|
|
106
121
|
else
|
|
107
|
-
exe = File.join(opts[:instances],id.to_s,File.basename(
|
|
122
|
+
exe = File.join(opts[:instances],id.to_s,File.basename(self::BACKEND_RUN))
|
|
108
123
|
pid = File.read(exe + '.pid') rescue nil
|
|
109
124
|
if pid && (Process.kill(0, pid.to_i) rescue false)
|
|
110
125
|
Process.kill('HUP', pid.to_i) rescue nil
|
|
@@ -115,7 +130,7 @@ module CPEE
|
|
|
115
130
|
end
|
|
116
131
|
end
|
|
117
132
|
end
|
|
118
|
-
|
|
133
|
+
}
|
|
119
134
|
|
|
120
135
|
end
|
|
121
136
|
|
|
@@ -29,9 +29,12 @@ class ConnectionWrapper < WEEL::ConnectionWrapperBase
|
|
|
29
29
|
tso + 2 > tsn && count > 100
|
|
30
30
|
end # }}}
|
|
31
31
|
|
|
32
|
-
def self::inform_state_change(arguments,newstate) # {{{
|
|
32
|
+
def self::inform_state_change(arguments,newstate,data) # {{{
|
|
33
33
|
controller = arguments[0]
|
|
34
|
-
controller.notify(
|
|
34
|
+
controller.notify('state/change', :state => newstate)
|
|
35
|
+
if newstate == :stopped || newstate == :finished
|
|
36
|
+
controller.notify('dataelements/modify', :eid => 'ex-post', :values => data)
|
|
37
|
+
end
|
|
35
38
|
end # }}}
|
|
36
39
|
def self::inform_syntax_error(arguments,err,code)# {{{
|
|
37
40
|
# TODO extract spot (code) where error happened for better error handling (ruby 3.1 only)
|
|
@@ -96,7 +99,7 @@ class ConnectionWrapper < WEEL::ConnectionWrapperBase
|
|
|
96
99
|
}
|
|
97
100
|
end #}}}
|
|
98
101
|
|
|
99
|
-
def proto_curl(parameters) #{{{
|
|
102
|
+
def proto_curl(parameters, dataelements) #{{{
|
|
100
103
|
params = []
|
|
101
104
|
callback = SecureRandom.hex(16)
|
|
102
105
|
(parameters[:arguments] || []).each do |s|
|
|
@@ -200,11 +203,11 @@ class ConnectionWrapper < WEEL::ConnectionWrapperBase
|
|
|
200
203
|
headers['CPEE_SALVAGE'] = true
|
|
201
204
|
c = result[0]&.value
|
|
202
205
|
c = c.read if c.respond_to? :read
|
|
203
|
-
callback([ Riddl::Parameter::Complex.new('error','application/json',StringIO.new(JSON::generate({ 'status' => status, 'error' => c }))) ], headers)
|
|
206
|
+
callback([ Riddl::Parameter::Complex.new('error','application/json',StringIO.new(JSON::generate({ 'status' => status, 'error' => c }))) ], headers, dataelements)
|
|
204
207
|
else
|
|
205
208
|
if headers['CPEE_CALLBACK'] && headers['CPEE_CALLBACK'] == 'true' && result.any?
|
|
206
209
|
headers['CPEE_UPDATE'] = true
|
|
207
|
-
callback result, headers
|
|
210
|
+
callback result, headers, dataelements
|
|
208
211
|
elsif headers['CPEE_CALLBACK'] && headers['CPEE_CALLBACK'] == 'true' && result.empty?
|
|
209
212
|
if headers['CPEE_INSTANTIATION']
|
|
210
213
|
@controller.notify("task/instantiation", :'activity-uuid' => @handler_activity_uuid, :label => @label, :activity => @handler_position, :endpoint => @handler_endpoint, :received => CPEE::ValueHelper.parse(headers['CPEE_INSTANTIATION']))
|
|
@@ -214,19 +217,19 @@ class ConnectionWrapper < WEEL::ConnectionWrapperBase
|
|
|
214
217
|
end
|
|
215
218
|
# do nothing, later on things will happend
|
|
216
219
|
else
|
|
217
|
-
callback result, headers
|
|
220
|
+
callback result, headers, dataelements
|
|
218
221
|
end
|
|
219
222
|
end
|
|
220
223
|
end #}}}
|
|
221
224
|
|
|
222
|
-
def activity_handle(passthrough, parameters) # {{{
|
|
225
|
+
def activity_handle(passthrough, parameters, dataelements) # {{{
|
|
223
226
|
raise "Wrong endpoint" if @handler_endpoint.nil? || @handler_endpoint.empty?
|
|
224
227
|
@label = parameters[:label]
|
|
225
228
|
@anno = parameters.delete(:annotations) rescue nil
|
|
226
229
|
@controller.notify("activity/calling", :'activity-uuid' => @handler_activity_uuid, :label => @label, :activity => @handler_position, :passthrough => passthrough, :endpoint => @handler_endpoint, :parameters => parameters)
|
|
227
230
|
@controller.notify("activity/annotation", :'activity-uuid' => @handler_activity_uuid, :label => @label, :activity => @handler_position, :annotations => @anno)
|
|
228
231
|
if passthrough.to_s.empty?
|
|
229
|
-
proto_curl parameters
|
|
232
|
+
proto_curl parameters, dataelements
|
|
230
233
|
else
|
|
231
234
|
@controller.callback(self,passthrough,:'activity-uuid' => @handler_activity_uuid, :label => @label, :activity => @handler_position)
|
|
232
235
|
@handler_passthrough = passthrough
|
|
@@ -271,6 +274,9 @@ class ConnectionWrapper < WEEL::ConnectionWrapperBase
|
|
|
271
274
|
unless changed_dataelements.nil? || changed_dataelements.empty?
|
|
272
275
|
de = dataelements.slice(*changed_dataelements).transform_values { |v| enc = CPEE::EvalRuby::Translation::detect_encoding(v); (enc == 'OTHER' ? v : (v.encode('UTF-8',enc) rescue CPEE::EvalRuby::Translation::convert_to_base64(v))) }
|
|
273
276
|
@controller.notify("dataelements/change", :'activity-uuid' => @handler_activity_uuid, :endpoint => @handler_endpoint, :label => @label, :activity => @handler_position, :changed => changed_dataelements, :values => de)
|
|
277
|
+
if @anno && @anno[:_context_data_analysis] && @anno[:_context_data_analysis][:probes] && @anno[:_context_data_analysis][:probes].find{ |p| p.dig(:probe,:extractor_type) == 'intrinsic' }
|
|
278
|
+
@controller.notify("task/probe", :'activity-uuid' => @handler_activity_uuid, :endpoint => @handler_endpoint, :label => @label, :activity => @handler_position, :data => dataelements, :probes => @anno[:_context_data_analysis][:probes])
|
|
279
|
+
end
|
|
274
280
|
end
|
|
275
281
|
unless changed_endpoints.nil? || changed_endpoints.empty?
|
|
276
282
|
@controller.notify("endpoints/change", :'activity-uuid' => @handler_activity_uuid, :endpoint => @handler_endpoint, :label => @label, :activity => @handler_position, :changed => changed_endpoints, :values => endpoints.slice(*changed_endpoints))
|
|
@@ -284,7 +290,7 @@ class ConnectionWrapper < WEEL::ConnectionWrapperBase
|
|
|
284
290
|
@controller.vote("activity/syncing_before", :'activity-uuid' => @handler_activity_uuid, :endpoint => @handler_endpoint, :activity => @handler_position, :label => @label, :parameters => parameters)
|
|
285
291
|
end # }}}
|
|
286
292
|
|
|
287
|
-
def callback(result=nil,options={}) #{{{
|
|
293
|
+
def callback(result=nil,options={}, dataelements) #{{{
|
|
288
294
|
status, ret, headers = Riddl::Client.new(@controller.url_result_transformation).request 'put' => result
|
|
289
295
|
recv = if status >= 200 && status < 300
|
|
290
296
|
JSON::parse(ret[0].value.read)
|
|
@@ -293,6 +299,9 @@ class ConnectionWrapper < WEEL::ConnectionWrapperBase
|
|
|
293
299
|
end
|
|
294
300
|
|
|
295
301
|
@controller.notify("activity/receiving", :'activity-uuid' => @handler_activity_uuid, :label => @label, :activity => @handler_position, :endpoint => @handler_endpoint, :received => recv)
|
|
302
|
+
if @anno[:_context_data_analysis] && @anno[:_context_data_analysis][:probes] && @anno[:_context_data_analysis][:probes].find{ |p| p.dig(:probe,:extractor_type) == 'extrinsic' }
|
|
303
|
+
@controller.notify("task/probe", :'activity-uuid' => @handler_activity_uuid, :label => @label, :activity => @handler_position, :endpoint => @handler_endpoint, :received => recv, :data => dataelements, :probes => @anno[:_context_data_analysis]&.[](:probes))
|
|
304
|
+
end
|
|
296
305
|
|
|
297
306
|
@guard_files += result
|
|
298
307
|
@guard_files += ret
|
|
@@ -21,7 +21,6 @@ require 'cpee/value_helper'
|
|
|
21
21
|
require 'cpee/attributes_helper'
|
|
22
22
|
require 'cpee/message'
|
|
23
23
|
require 'cpee/redis'
|
|
24
|
-
require 'cpee/persistence'
|
|
25
24
|
require 'get_process_mem'
|
|
26
25
|
|
|
27
26
|
require 'ostruct'
|
|
@@ -42,12 +41,9 @@ class Controller
|
|
|
42
41
|
|
|
43
42
|
@id = id
|
|
44
43
|
|
|
45
|
-
@attributes =
|
|
46
|
-
CPEE::Persistence::extract_list(id,opts,'attributes').each do |de|
|
|
47
|
-
@attributes[de[0]] = de[1]
|
|
48
|
-
end
|
|
49
|
-
|
|
44
|
+
@attributes = opts[:attributes]
|
|
50
45
|
@attributes_helper = AttributesHelper.new
|
|
46
|
+
|
|
51
47
|
@thread = nil
|
|
52
48
|
@opts = opts
|
|
53
49
|
@instance = nil
|
|
@@ -74,7 +70,7 @@ class Controller
|
|
|
74
70
|
resp << Riddl::Parameter::Complex.new(e[0],e[1][1],e[1][2])
|
|
75
71
|
end
|
|
76
72
|
end
|
|
77
|
-
@callback_keys[identifier].send(:callback,resp,m['content']['headers'])
|
|
73
|
+
@callback_keys[identifier].send(:callback,resp,m['content']['headers'],dataelements)
|
|
78
74
|
end
|
|
79
75
|
end
|
|
80
76
|
if pat == 'callback-end:*'
|
|
@@ -183,7 +179,7 @@ class Controller
|
|
|
183
179
|
handler = File.join(topic,'vote',name)
|
|
184
180
|
votes = []
|
|
185
181
|
|
|
186
|
-
|
|
182
|
+
@opts[:votes][handler]&.each do |client|
|
|
187
183
|
voteid = SecureRandom.hex(16)
|
|
188
184
|
content[:key] = voteid
|
|
189
185
|
content[:attributes] = attributes_translated
|
|
@@ -91,9 +91,12 @@
|
|
|
91
91
|
</xsl:if>
|
|
92
92
|
<xsl:if test="name()='manipulate'">
|
|
93
93
|
<xsl:if test="@label">
|
|
94
|
-
<xsl:text>, {
|
|
95
|
-
<xsl:
|
|
96
|
-
|
|
94
|
+
<xsl:text>, { </xsl:text>
|
|
95
|
+
<xsl:text>:label => "</xsl:text>
|
|
96
|
+
<xsl:value-of select="@label"/>
|
|
97
|
+
<xsl:text>", </xsl:text>
|
|
98
|
+
<xsl:apply-templates select="d:annotations" mode="annotations"/>
|
|
99
|
+
<xsl:text> }</xsl:text>
|
|
97
100
|
</xsl:if>
|
|
98
101
|
<xsl:call-template name="print-mcontent">
|
|
99
102
|
<xsl:with-param name="myspace">
|
|
@@ -19,22 +19,22 @@ module CPEE
|
|
|
19
19
|
|
|
20
20
|
module ExecutionHandler
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
BACKEND_INSTANCE = 'instance.rb'
|
|
24
|
-
DSL_TO_DSLX_XSL = File.expand_path(File.join(__dir__,'dsl_to_dslx.xsl'))
|
|
25
|
-
BACKEND_RUN = File.expand_path(File.join(__dir__,'backend','run.rb'))
|
|
26
|
-
BACKEND_OPTS = File.expand_path(File.join(__dir__,'backend','opts.yaml'))
|
|
27
|
-
BACKEND_TEMPLATE = File.expand_path(File.join(__dir__,'backend','instance.template'))
|
|
22
|
+
self.const_set File.basename(__dir__).capitalize, Module.new {
|
|
23
|
+
self::BACKEND_INSTANCE = 'instance.rb'
|
|
24
|
+
self::DSL_TO_DSLX_XSL = File.expand_path(File.join(__dir__,'dsl_to_dslx.xsl'))
|
|
25
|
+
self::BACKEND_RUN = File.expand_path(File.join(__dir__,'backend','run.rb'))
|
|
26
|
+
self::BACKEND_OPTS = File.expand_path(File.join(__dir__,'backend','opts.yaml'))
|
|
27
|
+
self::BACKEND_TEMPLATE = File.expand_path(File.join(__dir__,'backend','instance.template'))
|
|
28
28
|
|
|
29
29
|
def self::dslx_to_dsl(dslx,ep) # transpile
|
|
30
|
-
trans = XML::Smart::open_unprotected(
|
|
30
|
+
trans = XML::Smart::open_unprotected(self::DSL_TO_DSLX_XSL)
|
|
31
31
|
dslx.transform_with(trans).to_s
|
|
32
32
|
end
|
|
33
33
|
|
|
34
34
|
def self::prepare(id,opts) # write result to disk
|
|
35
35
|
FileUtils.rm_rf(Dir.glob(File.join(opts[:instances],id.to_s,'*')) + Dir.glob(File.join(opts[:instances],id.to_s,'.remote')))
|
|
36
36
|
Dir.mkdir(File.join(opts[:instances],id.to_s)) rescue nil
|
|
37
|
-
FileUtils.copy(
|
|
37
|
+
FileUtils.copy(self::BACKEND_RUN,File.join(opts[:instances],id.to_s))
|
|
38
38
|
dsl = CPEE::Persistence::extract_item(id,opts,'dsl')
|
|
39
39
|
hw = CPEE::Persistence::extract_item(id,opts,'executionhandler')
|
|
40
40
|
endpoints = CPEE::Persistence::extract_list(id,opts,'endpoints')
|
|
@@ -44,7 +44,8 @@ module CPEE
|
|
|
44
44
|
positions.map! do |k, v|
|
|
45
45
|
[ k, v, CPEE::Persistence::extract_item(id,opts,File.join('positions',k,'@passthrough')) ]
|
|
46
46
|
end
|
|
47
|
-
iopts = YAML::load_file(
|
|
47
|
+
iopts = YAML::load_file(self::BACKEND_OPTS)
|
|
48
|
+
iopts[:instance_id] = id
|
|
48
49
|
iopts[:host] = opts[:host]
|
|
49
50
|
iopts[:url] = opts[:url]
|
|
50
51
|
iopts[:redis_url] = opts[:redis_url]
|
|
@@ -58,13 +59,26 @@ module CPEE
|
|
|
58
59
|
iopts[:executionhandlers] = opts[:executionhandlers]
|
|
59
60
|
iopts[:global_executionhandlers] = opts[:global_executionhandlers]
|
|
60
61
|
end
|
|
62
|
+
iopts[:attributes] = attributes
|
|
63
|
+
iopts[:votes] = {}
|
|
64
|
+
CPEE::Persistence::extract_handlers(id,opts).each do |de|
|
|
65
|
+
if de[1] && de[1]&.empty?.!
|
|
66
|
+
CPEE::Persistence::extract_handler(id,opts,de[0]).each do |ele|
|
|
67
|
+
topic, type, name = ele.split('/')
|
|
68
|
+
if type == 'vote'
|
|
69
|
+
iopts[:votes][ele] ||= []
|
|
70
|
+
iopts[:votes][ele] << de[0]
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
61
75
|
|
|
62
|
-
File.open(File.join(opts[:instances],id.to_s,File.basename(
|
|
76
|
+
File.open(File.join(opts[:instances],id.to_s,File.basename(self::BACKEND_OPTS)),'w') do |f|
|
|
63
77
|
YAML::dump(iopts,f)
|
|
64
78
|
end
|
|
65
|
-
template = ERB.new(File.read(
|
|
79
|
+
template = ERB.new(File.read(self::BACKEND_TEMPLATE), trim_mode: '-')
|
|
66
80
|
res = template.result_with_hash(dsl: dsl, dataelements: dataelements, endpoints: endpoints, positions: positions)
|
|
67
|
-
File.write(File.join(opts[:instances],id.to_s,
|
|
81
|
+
File.write(File.join(opts[:instances],id.to_s,self::BACKEND_INSTANCE),res)
|
|
68
82
|
if attributes.has_key?('remote')
|
|
69
83
|
uri = URI::parse(attributes['remote'])
|
|
70
84
|
Net::SSH.start(uri.host,uri.user,:keys => [ opts[:ssh_key] ] ) do |ssh|
|
|
@@ -78,12 +92,12 @@ module CPEE
|
|
|
78
92
|
def self::run(id,opts)
|
|
79
93
|
if File.exist? File.join(opts[:instances],id.to_s,'.remote')
|
|
80
94
|
uri = URI::parse(File.read(File.join(opts[:instances],id.to_s,'.remote')))
|
|
81
|
-
exe = File.join(uri.path,id.to_s,File.basename(BACKEND_RUN))
|
|
95
|
+
exe = File.join(uri.path,id.to_s,File.basename(self::BACKEND_RUN))
|
|
82
96
|
Net::SSH.start(uri.host,uri.user,:keys => [ opts[:ssh_key] ] ) do |ssh|
|
|
83
97
|
ssh.exec!("ruby #{exe} >#{exe}.out 2>#{exe}.err &")
|
|
84
98
|
end
|
|
85
99
|
else
|
|
86
|
-
exe = File.join(opts[:instances],id.to_s,File.basename(
|
|
100
|
+
exe = File.join(opts[:instances],id.to_s,File.basename(self::BACKEND_RUN))
|
|
87
101
|
pid = Kernel.spawn(opts[:libs_preloaderrun] + ' ' + exe , :pgroup => true, :in => '/dev/null', :out => exe + '.out', :err => exe + '.err')
|
|
88
102
|
Process.detach pid
|
|
89
103
|
File.write(exe + '.pid',pid)
|
|
@@ -93,7 +107,7 @@ module CPEE
|
|
|
93
107
|
def self::stop(id,opts) ### return: bool to tell if manually changing redis is necessary
|
|
94
108
|
if File.exist? File.join(opts[:instances],id.to_s,'.remote')
|
|
95
109
|
uri = URI::parse(File.read(File.join(opts[:instances],id.to_s,'.remote')))
|
|
96
|
-
exe = File.join(uri.path,id.to_s,File.basename(BACKEND_RUN))
|
|
110
|
+
exe = File.join(uri.path,id.to_s,File.basename(self::BACKEND_RUN))
|
|
97
111
|
Net::SSH.start(uri.host,uri.user,:keys => [ opts[:ssh_key] ] ) do |ssh|
|
|
98
112
|
pid = ssh.exec!("cat #{exe}.pid 2>/dev/null")
|
|
99
113
|
if pid != '' && ssh.exec!("kill -0 #{pid} >/dev/null 2>&1; echo $?").strip == '0'
|
|
@@ -105,7 +119,7 @@ module CPEE
|
|
|
105
119
|
end
|
|
106
120
|
end
|
|
107
121
|
else
|
|
108
|
-
exe = File.join(opts[:instances],id.to_s,File.basename(
|
|
122
|
+
exe = File.join(opts[:instances],id.to_s,File.basename(self::BACKEND_RUN))
|
|
109
123
|
pid = File.read(exe + '.pid') rescue nil
|
|
110
124
|
if pid && (Process.kill(0, pid.to_i) rescue false)
|
|
111
125
|
Process.kill('HUP', pid.to_i) rescue nil
|
|
@@ -116,7 +130,7 @@ module CPEE
|
|
|
116
130
|
end
|
|
117
131
|
end
|
|
118
132
|
end
|
|
119
|
-
|
|
133
|
+
}
|
|
120
134
|
|
|
121
135
|
end
|
|
122
136
|
|
data/server/resources/topics.xml
CHANGED
data/server/routing/end.pid
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
1283631
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
1283649
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
1283643
|
data/server/routing/persist.pid
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
1283637
|
data/server/routing/persist.rb
CHANGED
|
@@ -88,10 +88,18 @@ Daemonite.new do |opts|
|
|
|
88
88
|
end
|
|
89
89
|
when /event:\d+:dataelements\/change/, /event:\d+:endpoints\/change/, /event:\d+:attributes\/change/
|
|
90
90
|
topic = mess.dig('topic')
|
|
91
|
+
max = opts[:redis].zrange("instance:#{instance}/#{topic}", -1, -1, :withscores => true)&.dig(0,1).to_i
|
|
92
|
+
if (eles = mess.dig('content','sort'))&.any?
|
|
93
|
+
opts[:redis].multi do |multi|
|
|
94
|
+
eles.each_with_index do |e,i|
|
|
95
|
+
multi.zadd("instance:#{instance}/#{topic}",i,e,xx: true)
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
91
99
|
opts[:redis].multi do |multi|
|
|
92
100
|
mess.dig('content','changed')&.each_with_index do |c,i|
|
|
93
101
|
unless what =~ /event:\d+:attributes\/change/ && c == 'uuid'
|
|
94
|
-
multi.zadd("instance:#{instance}/#{topic}",i,c)
|
|
102
|
+
multi.zadd("instance:#{instance}/#{topic}",max + 1 + i,c,nx: true)
|
|
95
103
|
if what =~ /event:\d+:dataelements\/change/
|
|
96
104
|
multi.set("instance:#{instance}/#{topic}/#{c}",CPEE::ValueHelper::generate(mess.dig('content','values',c)))
|
|
97
105
|
else
|
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.
|
|
4
|
+
version: 2.1.123
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Juergen eTM Mangler
|
|
@@ -171,6 +171,20 @@ dependencies:
|
|
|
171
171
|
- - "~>"
|
|
172
172
|
- !ruby/object:Gem::Version
|
|
173
173
|
version: '1.7'
|
|
174
|
+
- !ruby/object:Gem::Dependency
|
|
175
|
+
name: msgpack
|
|
176
|
+
requirement: !ruby/object:Gem::Requirement
|
|
177
|
+
requirements:
|
|
178
|
+
- - "~>"
|
|
179
|
+
- !ruby/object:Gem::Version
|
|
180
|
+
version: '1.8'
|
|
181
|
+
type: :runtime
|
|
182
|
+
prerelease: false
|
|
183
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
184
|
+
requirements:
|
|
185
|
+
- - "~>"
|
|
186
|
+
- !ruby/object:Gem::Version
|
|
187
|
+
version: '1.8'
|
|
174
188
|
- !ruby/object:Gem::Dependency
|
|
175
189
|
name: by
|
|
176
190
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -1,226 +0,0 @@
|
|
|
1
|
-
# This file is part of CPEE.
|
|
2
|
-
#
|
|
3
|
-
# CPEE is free software: you can redistribute it and/or modify it under the terms
|
|
4
|
-
# of the GNU General Public License as published by the Free Software Foundation,
|
|
5
|
-
# either version 3 of the License, or (at your option) any later version.
|
|
6
|
-
#
|
|
7
|
-
# CPEE is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
8
|
-
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
|
9
|
-
# PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
10
|
-
#
|
|
11
|
-
# You should have received a copy of the GNU General Public License along with
|
|
12
|
-
# CPEE (file COPYING in the main directory). If not, see
|
|
13
|
-
# <http://www.gnu.org/licenses/>.
|
|
14
|
-
|
|
15
|
-
require 'weel'
|
|
16
|
-
require 'json'
|
|
17
|
-
require 'redis'
|
|
18
|
-
require 'securerandom'
|
|
19
|
-
require 'riddl/client'
|
|
20
|
-
require 'cpee/value_helper'
|
|
21
|
-
require 'cpee/attributes_helper'
|
|
22
|
-
require 'cpee/message'
|
|
23
|
-
require 'cpee/redis'
|
|
24
|
-
require 'cpee/persistence'
|
|
25
|
-
require 'get_process_mem'
|
|
26
|
-
|
|
27
|
-
require 'ostruct'
|
|
28
|
-
class ParaStruct < OpenStruct
|
|
29
|
-
def to_json(*a)
|
|
30
|
-
table.to_json
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
def ⭐(a); ParaStruct.new(a); end
|
|
34
|
-
|
|
35
|
-
class Controller
|
|
36
|
-
def initialize(id,dir,opts)
|
|
37
|
-
CPEE::redis_connect(opts,"Instance #{id}")
|
|
38
|
-
CPEE::Message::set_workers(opts[:workers])
|
|
39
|
-
|
|
40
|
-
@redis = opts[:redis]
|
|
41
|
-
@votes = []
|
|
42
|
-
|
|
43
|
-
@id = id
|
|
44
|
-
|
|
45
|
-
@attributes = {}
|
|
46
|
-
CPEE::Persistence::extract_list(id,opts,'attributes').each do |de|
|
|
47
|
-
@attributes[de[0]] = de[1]
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
@attributes_helper = AttributesHelper.new
|
|
51
|
-
@thread = nil
|
|
52
|
-
@opts = opts
|
|
53
|
-
@instance = nil
|
|
54
|
-
@loop_guard = {}
|
|
55
|
-
|
|
56
|
-
@callback_keys = {}
|
|
57
|
-
|
|
58
|
-
@subs = Thread.new do
|
|
59
|
-
@psredis = @opts[:redis_dyn].call "Instance #{@id} Callback Response"
|
|
60
|
-
@psredis.psubscribe('callback-response:*','callback-end:*') do |on|
|
|
61
|
-
on.pmessage do |pat, what, message|
|
|
62
|
-
if pat == 'callback-response:*'
|
|
63
|
-
_, worker, identifier = what.split(':')
|
|
64
|
-
if @callback_keys.has_key?(identifier)
|
|
65
|
-
index = message.index(' ')
|
|
66
|
-
mess = message[index+1..-1]
|
|
67
|
-
instance, uuid = message[0...index].split(',')
|
|
68
|
-
m = JSON.parse(mess)
|
|
69
|
-
resp = []
|
|
70
|
-
m['content']['values'].each do |e|
|
|
71
|
-
if e[1][0] == 'simple'
|
|
72
|
-
resp << Riddl::Parameter::Simple.new(e[0],e[1][1])
|
|
73
|
-
elsif e[1][0] == 'complex'
|
|
74
|
-
resp << Riddl::Parameter::Complex.new(e[0],e[1][1],e[1][2])
|
|
75
|
-
end
|
|
76
|
-
end
|
|
77
|
-
@callback_keys[identifier].send(:callback,resp,m['content']['headers'])
|
|
78
|
-
end
|
|
79
|
-
end
|
|
80
|
-
if pat == 'callback-end:*'
|
|
81
|
-
_, worker, identifier = what.split(':')
|
|
82
|
-
@callback_keys.delete(identifier)
|
|
83
|
-
end
|
|
84
|
-
end
|
|
85
|
-
end
|
|
86
|
-
@psredis.close
|
|
87
|
-
rescue => e
|
|
88
|
-
sleep 1
|
|
89
|
-
retry
|
|
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
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
attr_reader :id
|
|
100
|
-
attr_reader :attributes
|
|
101
|
-
attr_reader :loop_guard
|
|
102
|
-
|
|
103
|
-
def attributes_translated
|
|
104
|
-
@attributes_translated || @attributes_translated = @attributes_helper.translate(attributes,dataelements,endpoints)
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
def uuid
|
|
108
|
-
@attributes['uuid']
|
|
109
|
-
end
|
|
110
|
-
def host
|
|
111
|
-
@opts[:host]
|
|
112
|
-
end
|
|
113
|
-
def base_url
|
|
114
|
-
File.join(@opts[:url],'/')
|
|
115
|
-
end
|
|
116
|
-
def instance_url
|
|
117
|
-
File.join(@opts[:url].to_s,@id.to_s,'/')
|
|
118
|
-
end
|
|
119
|
-
def instance_id
|
|
120
|
-
@id
|
|
121
|
-
end
|
|
122
|
-
def base
|
|
123
|
-
base_url
|
|
124
|
-
end
|
|
125
|
-
def instance=(inst)
|
|
126
|
-
@instance = inst
|
|
127
|
-
end
|
|
128
|
-
def endpoints
|
|
129
|
-
@instance.endpoints
|
|
130
|
-
end
|
|
131
|
-
def dataelements
|
|
132
|
-
@instance.data
|
|
133
|
-
end
|
|
134
|
-
def url_result_transformation
|
|
135
|
-
@opts[:url_result_transformation]
|
|
136
|
-
end
|
|
137
|
-
def url_code
|
|
138
|
-
@opts[:url_code]
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
def start
|
|
142
|
-
if vote("state/change", :state => 'running')
|
|
143
|
-
@thread = @instance.start
|
|
144
|
-
@thread.join
|
|
145
|
-
else
|
|
146
|
-
@thread = @instance.stop
|
|
147
|
-
@thread.join
|
|
148
|
-
end
|
|
149
|
-
end
|
|
150
|
-
|
|
151
|
-
def sim
|
|
152
|
-
if vote("state/change", :state => 'simulating')
|
|
153
|
-
@thread = @instance.sim
|
|
154
|
-
@thread.join
|
|
155
|
-
else
|
|
156
|
-
@thread = @instance.stop
|
|
157
|
-
@thread.join
|
|
158
|
-
end
|
|
159
|
-
end
|
|
160
|
-
|
|
161
|
-
def stop
|
|
162
|
-
### tell the instance to stop
|
|
163
|
-
@instance.stop
|
|
164
|
-
### end all votes or it will not work
|
|
165
|
-
Thread.new do # doing stuff in trap context is a nono. but in a thread its fine :-)
|
|
166
|
-
@votes.each do |key|
|
|
167
|
-
CPEE::Message::send(:'vote-response',key,base,@id,uuid,info,true,@redis)
|
|
168
|
-
end
|
|
169
|
-
end
|
|
170
|
-
end
|
|
171
|
-
|
|
172
|
-
def info
|
|
173
|
-
@attributes['info']
|
|
174
|
-
end
|
|
175
|
-
|
|
176
|
-
def notify(what,content={})
|
|
177
|
-
content[:attributes] = attributes_translated
|
|
178
|
-
CPEE::Message::send(:event,what,base,@id,uuid,info,content,@redis)
|
|
179
|
-
end
|
|
180
|
-
|
|
181
|
-
def vote(what,content={})
|
|
182
|
-
topic, name = what.split('/')
|
|
183
|
-
handler = File.join(topic,'vote',name)
|
|
184
|
-
votes = []
|
|
185
|
-
|
|
186
|
-
CPEE::Persistence::extract_handler(id,@opts,handler).each do |client|
|
|
187
|
-
voteid = SecureRandom.hex(16)
|
|
188
|
-
content[:key] = voteid
|
|
189
|
-
content[:attributes] = attributes_translated
|
|
190
|
-
content[:subscription] = client
|
|
191
|
-
votes << voteid
|
|
192
|
-
CPEE::Message::send(:vote,what,base,@id,uuid,info,content,@redis)
|
|
193
|
-
end
|
|
194
|
-
|
|
195
|
-
if votes.length > 0
|
|
196
|
-
@votes += votes
|
|
197
|
-
psredis = @opts[:redis_dyn].call "Instance #{@id} Vote"
|
|
198
|
-
collect = []
|
|
199
|
-
psredis.subscribe(votes.map{|e| ['vote-response:00:' + e.to_s] }.flatten) do |on|
|
|
200
|
-
on.message do |what, message|
|
|
201
|
-
index = message.index(' ')
|
|
202
|
-
mess = message[index+1..-1]
|
|
203
|
-
m = JSON.parse(mess)
|
|
204
|
-
collect << ((m['content'] == true || m['content'] == 'true') || false)
|
|
205
|
-
@votes.delete m['name']
|
|
206
|
-
cancel_callback m['name']
|
|
207
|
-
if collect.length >= votes.length
|
|
208
|
-
psredis.unsubscribe
|
|
209
|
-
end
|
|
210
|
-
end
|
|
211
|
-
end
|
|
212
|
-
!collect.include?(false)
|
|
213
|
-
else
|
|
214
|
-
true
|
|
215
|
-
end
|
|
216
|
-
end
|
|
217
|
-
|
|
218
|
-
def callback(hw,key,content)
|
|
219
|
-
CPEE::Message::send(:callback,'activity/content',base,@id,uuid,info,content.merge(:key => key),@redis)
|
|
220
|
-
@callback_keys[key] = hw
|
|
221
|
-
end
|
|
222
|
-
|
|
223
|
-
def cancel_callback(key)
|
|
224
|
-
CPEE::Message::send(:'callback-end',key,base,@id,uuid,info,{},@redis)
|
|
225
|
-
end
|
|
226
|
-
end
|