cpee 2.0.5 → 2.0.11
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/config.json +3 -0
- data/cockpit/css/track.css +17 -6
- data/cockpit/css/ui.css +6 -2
- data/cockpit/css/wfadaptor.css +1 -1
- data/cockpit/edit.html +1 -0
- data/cockpit/index.html +2 -2
- data/cockpit/js/instance.js +75 -55
- data/cockpit/js/track.js +10 -0
- data/cockpit/js/ui.js +47 -16
- data/cockpit/templates/Track Test Local.xml +82 -0
- data/cockpit/templates/Track Test.xml +82 -0
- data/cockpit/templates/instantiate.local/Take_Sub.xml +61 -0
- data/cockpit/templates/instantiate/Take_Perf.xml +46 -0
- data/cockpit/templates/instantiate/Take_Sub.xml +57 -0
- data/cockpit/templates/instantiate/Take_X.xml +48 -0
- data/cockpit/themes/compact/rngs/call.rng +5 -0
- data/cockpit/themes/compact/rngs/callmanipulate.rng +6 -1
- data/cockpit/themes/default/rngs/call.rng +5 -0
- data/cockpit/themes/default/rngs/callmanipulate.rng +6 -1
- data/cockpit/themes/extended/rngs/call.rng +5 -0
- data/cockpit/themes/extended/rngs/callmanipulate.rng +6 -1
- data/cockpit/themes/model/theme.js +1 -1
- data/cockpit/themes/packed/rngs/call.rng +5 -0
- data/cockpit/themes/packed/rngs/callmanipulate.rng +6 -1
- data/cockpit/themes/preset/rngs/call.rng +5 -0
- data/cockpit/themes/preset/rngs/callmanipulate.rng +6 -1
- data/cockpit/track.html +37 -8
- data/cpee.gemspec +3 -3
- data/lib/cpee/implementation.rb +14 -5
- data/lib/cpee/implementation_notifications.rb +95 -62
- data/lib/cpee/persistence.rb +3 -0
- data/server/routing/end.pid +1 -0
- data/server/routing/forward-events.pid +1 -0
- data/server/routing/forward-events.rb +2 -1
- data/server/routing/forward-votes.pid +1 -0
- data/server/routing/forward-votes.rb +1 -1
- data/server/routing/persist.pid +1 -0
- data/server/server.conf +4 -0
- data/server/server.pid +1 -0
- data/tools/cpee +17 -11
- data/tools/server/resources/notifications/logging/subscription.xml +13 -1
- data/tools/server/resources/properties.init +16 -15
- metadata +22 -13
- data/cockpit/templates/convert_cpee2.rb +0 -15
- data/cockpit/themes/convert_cpee2.rb +0 -8
- data/tools/instantiation/instantiation +0 -23
- data/tools/server/resources/notifications/logging/consumer-secret +0 -1
- data/tools/server/resources/notifications/logging/producer-secret +0 -1
|
@@ -89,6 +89,11 @@
|
|
|
89
89
|
</zeroOrMore>
|
|
90
90
|
</element>
|
|
91
91
|
</element>
|
|
92
|
+
<element name="report" rngui:header="Reporting Annotation" rngui:fold="closed">
|
|
93
|
+
<element name="url" rngui:label='HTML Snippet'>
|
|
94
|
+
<data type="string" rngui:label="url to report snippet"/>
|
|
95
|
+
</element>
|
|
96
|
+
</element>
|
|
92
97
|
</element>
|
|
93
98
|
<element name="code" rngui:header="Implementation">
|
|
94
99
|
<element name="prepare" rngui:header="Prepare" rngui:label="Code" rngui:fold="closed_conditional">
|
|
@@ -137,4 +142,4 @@
|
|
|
137
142
|
</element>
|
|
138
143
|
</element>
|
|
139
144
|
</element>
|
|
140
|
-
</element>
|
|
145
|
+
</element>
|
data/cockpit/track.html
CHANGED
|
@@ -62,12 +62,41 @@
|
|
|
62
62
|
<div class='hidden' id='relaxngworker'></div>
|
|
63
63
|
<div id="trackfull">
|
|
64
64
|
<div id='graphcolumn'>
|
|
65
|
-
<div id="
|
|
66
|
-
<
|
|
67
|
-
<span
|
|
65
|
+
<div id="trackusage">
|
|
66
|
+
<div id='tracktitle'>
|
|
67
|
+
<span>
|
|
68
|
+
<a class="x-ui-button" name="glob_reload" title='reload' href=''>
|
|
69
|
+
<svg viewBox="0 -1.5 7 12" width="10" height="16">
|
|
70
|
+
<path
|
|
71
|
+
style="fill:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stop-color:#000000"
|
|
72
|
+
d="M 3.5,1.5 C 1.431441,1.5001975 -0.24540803,3.1770466 -0.24560554,5.2456055 -0.2454082,7.3141647 1.4314408,8.991014 3.5,8.9912113 5.5685591,8.991014 7.2454081,7.3141647 7.2456054,5.2456055 7.2454079,3.1770466 5.5685589,1.5001975 3.5,1.5 Z M 3.437195,4.0616198 c 0.020931,-5.551e-4 0.041873,-5.551e-4 0.062805,0 0.6537674,3.133e-4 1.1836723,0.5302183 1.1839856,1.1839857 C 4.6836723,5.8993729 4.1537674,6.4292778 3.5,6.4295912 2.8462325,6.4292778 2.3163276,5.8993729 2.3160142,5.2456055 2.315414,4.6155841 2.8080758,4.0953252 3.437195,4.0616198 Z"/>
|
|
73
|
+
</svg>
|
|
74
|
+
</a>
|
|
75
|
+
<a class="x-ui-button" name="glob_edit" title='edit' target='_blank' href='' id='current-monitor'><svg viewBox="0 -1.5 7 12" width="10" height="16">
|
|
76
|
+
<path
|
|
77
|
+
style="fill:#000000;stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
|
78
|
+
d="M -0.25,7.8194404 0.57057194,10.599984 3.1882886,9.3540573 Z"/>
|
|
79
|
+
<path
|
|
80
|
+
style="fill:#000000;stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
|
81
|
+
d="M 3.5215262,8.6074434 6.0527848,2.9361926 2.6144961,1.4015756 0.08323736,7.0728263 Z"/>
|
|
82
|
+
<path
|
|
83
|
+
style="fill:#000000;stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
|
84
|
+
d="M 6.4439758,2.0597335 6.9719316,0.87685566 3.533643,-0.6577613 3.005687,0.52511656 Z"/>
|
|
85
|
+
</svg></a>
|
|
86
|
+
<a class="x-ui-button" name="glob_unshow" title='unshow'>
|
|
87
|
+
<svg viewBox="0 -1.5 7 12" width="10" height="16">
|
|
88
|
+
<path
|
|
89
|
+
style="fill:#000000;stroke-width:0;stop-color:#000000"
|
|
90
|
+
d="M 5.75,1.4999999 3.5,3.75 1.25,1.4999999 -0.25000013,3 2,5.25 -0.25000013,7.5 1.25,9.0000002 3.5,6.75 5.75,9.0000002 7.2500001,7.5 5,5.25 7.2500001,3 Z"/>
|
|
91
|
+
</svg>
|
|
92
|
+
</a>
|
|
93
|
+
</span>
|
|
94
|
+
<span> - </span>
|
|
95
|
+
<span id="title">Loading ...</span>
|
|
96
|
+
</div>
|
|
97
|
+
<div id='state'>
|
|
68
98
|
<span id="state_any">
|
|
69
|
-
<
|
|
70
|
-
<button name="state_start" title='start'>
|
|
99
|
+
<button name="state_start" title='start' style='display:none'>
|
|
71
100
|
<svg viewBox="0 -1.5 7 12" width="10" height="16">
|
|
72
101
|
<path
|
|
73
102
|
style="fill:#000000;fill-rule:evenodd;stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
|
@@ -82,7 +111,6 @@
|
|
|
82
111
|
</svg>
|
|
83
112
|
</button>
|
|
84
113
|
<span id="state_extended">
|
|
85
|
-
<span> / </span>
|
|
86
114
|
<button name="state_replay" title='replay'>
|
|
87
115
|
<svg viewBox="0 -1.5 7 12" width="10" height="16">
|
|
88
116
|
<path
|
|
@@ -90,7 +118,6 @@
|
|
|
90
118
|
d="m -0.24999978,8.9999993 c 0,-2.7488167 0,-5.4976332 0,-8.24644997 C 1.1183278,0.76955385 2.4884861,0.71666052 3.8555376,0.79065567 4.5083287,0.83810218 5.2238942,1.0790874 5.5755039,1.7307256 6.1661398,2.7080902 6.0299484,4.2180754 5.1108772,4.9019222 4.7622397,5.1617467 4.3480204,5.2956156 3.9336064,5.3605366 4.9287868,5.9394132 5.4254071,7.0996814 6.0167729,8.0858876 6.1549588,8.3769029 6.4657247,8.7723933 6.5,8.9999999 c -0.5944185,0 -1.1888371,0 -1.7832559,0 C 4.0758679,7.9893475 3.4946311,6.9294648 2.7923497,5.9678488 2.4230355,5.5319748 1.8508715,5.5458842 1.3513114,5.5576027 c -0.1507526,-0.00412 -0.044576,0.272902 -0.076255,0.3990664 0,1.0144436 0,2.028887 0,3.0433307 -0.50835205,-3e-7 -1.01670555,8e-7 -1.52505618,-5e-7 z M 1.2750578,4.2411336 C 2.111059,4.2189781 2.9581852,4.3060525 3.7849326,4.1387394 4.4863715,3.8915585 4.5732952,2.6432813 3.9026802,2.2941453 3.5098807,2.068434 3.050719,2.1857044 2.6267379,2.1489138 c -0.4505578,-0.00242 -0.90112,0.00147 -1.3516801,-3.456e-4 0,0.6975176 0,1.3950347 0,2.0925522 z"
|
|
91
119
|
</svg>
|
|
92
120
|
</button>
|
|
93
|
-
<span> / </span>
|
|
94
121
|
<button name="state_abandon" title='abandon'>
|
|
95
122
|
<svg viewBox="0 -1.5 7 12" width="10" height="16">
|
|
96
123
|
<path
|
|
@@ -99,8 +126,10 @@
|
|
|
99
126
|
</svg>
|
|
100
127
|
</button>
|
|
101
128
|
</span>
|
|
129
|
+
<span> - Status: </span>
|
|
102
130
|
</span>
|
|
103
|
-
|
|
131
|
+
<span id="state_text">loading ...</span>
|
|
132
|
+
</div>
|
|
104
133
|
</div>
|
|
105
134
|
<div id='graphgrid'>
|
|
106
135
|
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:x="http://www.w3.org/1999/xlink" id='graphcanvas' width='1' height='1'></svg>
|
data/cpee.gemspec
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
Gem::Specification.new do |s|
|
|
2
2
|
s.name = "cpee"
|
|
3
|
-
s.version = "2.0.
|
|
3
|
+
s.version = "2.0.11"
|
|
4
4
|
s.platform = Gem::Platform::RUBY
|
|
5
5
|
s.license = "LGPL-3.0"
|
|
6
6
|
s.summary = "Preliminary release of cloud process execution engine (cpee.org). If you just need workflow execution, without a rest service exposing it, then use WEEL."
|
|
7
7
|
|
|
8
8
|
s.description = "see http://cpee.org"
|
|
9
9
|
|
|
10
|
-
s.files = Dir['{example/**/*,server/**/*,tools/**/*,lib/**/*,cockpit/**/*,cockpit/themes/*/*/*,contrib/logo*,contrib/Screen*}'] - Dir['{server/instances/**/*,cockpit/js_libs/**/*}'] + %w(COPYING FEATURES.md INSTALL.md Rakefile cpee.gemspec README.md AUTHORS)
|
|
10
|
+
s.files = Dir['{example/**/*,server/**/*,tools/**/*,tools/archive,lib/**/*,cockpit/**/*,cockpit/themes/*/*/*,contrib/logo*,contrib/Screen*}'] - Dir['{server/instances/**/*,cockpit/js_libs/**/*}'] + %w(COPYING FEATURES.md INSTALL.md Rakefile cpee.gemspec README.md AUTHORS)
|
|
11
11
|
s.require_path = 'lib'
|
|
12
12
|
s.extra_rdoc_files = ['README.md']
|
|
13
13
|
s.bindir = 'tools'
|
|
@@ -21,7 +21,7 @@ Gem::Specification.new do |s|
|
|
|
21
21
|
s.email = 'juergen.mangler@gmail.com'
|
|
22
22
|
s.homepage = 'http://cpee.org/'
|
|
23
23
|
|
|
24
|
-
s.add_runtime_dependency 'riddl', '~> 0.
|
|
24
|
+
s.add_runtime_dependency 'riddl', '~> 0.108'
|
|
25
25
|
s.add_runtime_dependency 'weel', '~> 1.99', '>= 1.99.90'
|
|
26
26
|
s.add_runtime_dependency 'highline', '~> 2.0'
|
|
27
27
|
s.add_runtime_dependency 'json', '~>2.1'
|
data/lib/cpee/implementation.rb
CHANGED
|
@@ -72,7 +72,9 @@ module CPEE
|
|
|
72
72
|
opts[:infinite_loop_stop] ||= 10000
|
|
73
73
|
opts[:redis_path] ||= '/tmp/redis.sock'
|
|
74
74
|
opts[:redis_db] ||= 3
|
|
75
|
+
opts[:sse_keepalive_frequency] ||= 10
|
|
75
76
|
|
|
77
|
+
opts[:sse_connections] = {}
|
|
76
78
|
opts[:redis] = Redis.new(path: opts[:redis_path], db: opts[:redis_db])
|
|
77
79
|
opts[:statemachine] = CPEE::StateMachine.new opts[:states], %w{running simulating replaying finishing stopping abandoned finished} do |id|
|
|
78
80
|
opts[:redis].get("instance:#{id}/state")
|
|
@@ -88,13 +90,20 @@ module CPEE
|
|
|
88
90
|
|
|
89
91
|
Proc.new do
|
|
90
92
|
parallel do
|
|
91
|
-
CPEE::watch_services(
|
|
92
|
-
EM.add_periodic_timer(
|
|
93
|
-
CPEE::watch_services(
|
|
93
|
+
CPEE::watch_services(opts[:watchdog_start_off])
|
|
94
|
+
EM.add_periodic_timer(opts[:watchdog_frequency]) do ### start services
|
|
95
|
+
CPEE::watch_services(opts[:watchdog_start_off])
|
|
96
|
+
end
|
|
97
|
+
EM.defer do ### catch all sse connections
|
|
98
|
+
CPEE::Notifications::sse_distributor(opts)
|
|
99
|
+
end
|
|
100
|
+
EM.add_periodic_timer(opts[:sse_keepalive_frequency]) do
|
|
101
|
+
CPEE::Notifications::sse_heartbeat(opts)
|
|
94
102
|
end
|
|
95
103
|
end
|
|
104
|
+
|
|
96
105
|
cleanup do
|
|
97
|
-
CPEE::cleanup_services(
|
|
106
|
+
CPEE::cleanup_services(opts[:watchdog_start_off])
|
|
98
107
|
end
|
|
99
108
|
|
|
100
109
|
interface 'main' do
|
|
@@ -183,7 +192,7 @@ module CPEE
|
|
|
183
192
|
doc = XML::Smart::open_unprotected(opts[:properties_init])
|
|
184
193
|
doc.register_namespace 'p', 'http://cpee.org/ns/properties/2.0'
|
|
185
194
|
name = @p[0].value
|
|
186
|
-
id = redis.
|
|
195
|
+
id = redis.zrevrange('instances', 0, 0).first.to_i + 1
|
|
187
196
|
uuid = SecureRandom.uuid
|
|
188
197
|
instance = 'instance:' + id.to_s
|
|
189
198
|
redis.multi do |multi|
|
|
@@ -73,28 +73,32 @@ module CPEE
|
|
|
73
73
|
id = @a[0]
|
|
74
74
|
opts = @a[1]
|
|
75
75
|
key = @r[-1]
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
76
|
+
if CPEE::Persistence::exists_handler?(id,opts,key)
|
|
77
|
+
Riddl::Parameter::Complex.new("subscriptions","text/xml") do
|
|
78
|
+
ret = XML::Smart::string <<-END
|
|
79
|
+
<subscription xmlns='http://riddl.org/ns/common-patterns/notifications-producer/2.0'/>
|
|
80
|
+
END
|
|
81
|
+
url = CPEE::Persistence::extract_item(id,opts,File.join('handler',key,'url'))
|
|
82
|
+
ret.root.attributes['url'] = url if url && !url.empty?
|
|
83
|
+
items = {}
|
|
84
|
+
CPEE::Persistence::extract_handler(id,opts,key).each do |h|
|
|
85
|
+
t, i, v = h.split('/')
|
|
86
|
+
items[t] ||= []
|
|
87
|
+
items[t] << [i,v]
|
|
88
|
+
end
|
|
89
|
+
items.each do |k,v|
|
|
90
|
+
ret.root.add('topic').tap do |n|
|
|
91
|
+
n.attributes['id'] = k
|
|
92
|
+
v.each do |e|
|
|
93
|
+
n.add *e
|
|
94
|
+
end
|
|
93
95
|
end
|
|
94
96
|
end
|
|
97
|
+
ret.to_s
|
|
95
98
|
end
|
|
96
|
-
|
|
97
|
-
|
|
99
|
+
else
|
|
100
|
+
@status = 404
|
|
101
|
+
end
|
|
98
102
|
end
|
|
99
103
|
end #}}}
|
|
100
104
|
|
|
@@ -102,19 +106,24 @@ module CPEE
|
|
|
102
106
|
def response
|
|
103
107
|
id = @a[0]
|
|
104
108
|
opts = @a[1]
|
|
105
|
-
key = Digest::MD5.hexdigest(Kernel::rand().to_s)
|
|
106
|
-
|
|
107
|
-
url = @p[0].name == 'url' ? @p.shift.value : nil
|
|
108
|
-
values = []
|
|
109
|
-
while @p.length > 0
|
|
110
|
-
topic = @p.shift.value
|
|
111
|
-
base = @p.shift
|
|
112
|
-
type = base.name
|
|
113
|
-
values += base.value.split(',').map { |i| File.join(topic,type[0..-2],i) }
|
|
114
|
-
end
|
|
115
|
-
@header = CPEE::Persistence::set_handler(id,opts,key,url,values)
|
|
116
109
|
|
|
117
|
-
|
|
110
|
+
if opts[:statemachine].readonly? id
|
|
111
|
+
@status = 423
|
|
112
|
+
else
|
|
113
|
+
key = Digest::MD5.hexdigest(Kernel::rand().to_s)
|
|
114
|
+
|
|
115
|
+
url = @p[0].name == 'url' ? @p.shift.value : nil
|
|
116
|
+
values = []
|
|
117
|
+
while @p.length > 0
|
|
118
|
+
topic = @p.shift.value
|
|
119
|
+
base = @p.shift
|
|
120
|
+
type = base.name
|
|
121
|
+
values += base.value.split(',').map { |i| File.join(topic,type[0..-2],i) }
|
|
122
|
+
end
|
|
123
|
+
@header = CPEE::Persistence::set_handler(id,opts,key,url,values)
|
|
124
|
+
|
|
125
|
+
Riddl::Parameter::Simple.new('key',key)
|
|
126
|
+
end
|
|
118
127
|
end
|
|
119
128
|
end #}}}
|
|
120
129
|
|
|
@@ -124,15 +133,19 @@ module CPEE
|
|
|
124
133
|
opts = @a[1]
|
|
125
134
|
key = @r.last
|
|
126
135
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
136
|
+
if CPEE::Persistence::exists_handler?(id,opts,key)
|
|
137
|
+
url = @p[0].name == 'url' ? @p.shift.value : nil
|
|
138
|
+
values = []
|
|
139
|
+
while @p.length > 0
|
|
140
|
+
topic = @p.shift.value
|
|
141
|
+
base = @p.shift
|
|
142
|
+
type = base.name
|
|
143
|
+
values += base.value.split(',').map { |i| File.join(topic,type[0..-2],i) }
|
|
144
|
+
end
|
|
145
|
+
@header = CPEE::Persistence::set_handler(id,opts,key,url,values,true)
|
|
146
|
+
else
|
|
147
|
+
@status = 404
|
|
134
148
|
end
|
|
135
|
-
@header = CPEE::Persistence::set_handler(id,opts,key,url,values,true)
|
|
136
149
|
end
|
|
137
150
|
end #}}}
|
|
138
151
|
|
|
@@ -146,41 +159,61 @@ module CPEE
|
|
|
146
159
|
opts = @a[1]
|
|
147
160
|
key = @r.last
|
|
148
161
|
|
|
149
|
-
|
|
162
|
+
if CPEE::Persistence::exists_handler?(id,opts,key)
|
|
163
|
+
DeleteSubscription::set(id,opts,key)
|
|
164
|
+
else
|
|
165
|
+
@status = 404
|
|
166
|
+
end
|
|
150
167
|
nil
|
|
151
168
|
end
|
|
152
169
|
end #}}}
|
|
153
170
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
171
|
+
def self::sse_distributor(opts) #{{{
|
|
172
|
+
conn = Redis.new(path: opts[:redis_path], db: opts[:redis_db])
|
|
173
|
+
conn.psubscribe('forward:*','event:state/change') do |on|
|
|
174
|
+
on.pmessage do |pat, what, message|
|
|
175
|
+
if pat == 'forward:*'
|
|
176
|
+
_, id, key = what.match(/forward(-end)?:([^\/]+)\/(.+)/).captures
|
|
177
|
+
opts.dig(:sse_connections,id.to_i,key)&.send message
|
|
178
|
+
elsif pat == 'event:state/change'
|
|
179
|
+
mess = JSON.parse(message[message.index(' ')+1..-1])
|
|
180
|
+
state = mess.dig('content','state')
|
|
181
|
+
if state == 'finished' || state == 'abandoned'
|
|
182
|
+
opts.dig(:sse_connections,mess.dig('instance').to_i)&.each do |key,sse|
|
|
183
|
+
EM.add_timer(2) do # just to be sure that all messages arrived
|
|
184
|
+
sse.close
|
|
185
|
+
end
|
|
167
186
|
end
|
|
168
187
|
end
|
|
169
188
|
end
|
|
170
|
-
@conn.close
|
|
171
189
|
end
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
190
|
+
end
|
|
191
|
+
conn.close
|
|
192
|
+
end #}}}
|
|
193
|
+
def self::sse_heartbeat(opts) #{{{
|
|
194
|
+
opts.dig(:sse_connections).each do |id,keys|
|
|
195
|
+
keys.each do |key,sse|
|
|
196
|
+
sse.send_with_id('heartbeat', '42') unless sse&.closed?
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
end #}}}
|
|
200
|
+
class SSE < Riddl::SSEImplementation #{{{
|
|
201
|
+
def onopen
|
|
202
|
+
@opts = @a[1]
|
|
203
|
+
@id = @a[0]
|
|
204
|
+
@key = @r[-2]
|
|
205
|
+
if !@opts[:statemachine].readonly?(@id) && CPEE::Persistence::exists_handler?(@id,@opts,@key)
|
|
206
|
+
@opts[:sse_connections][@id] ||= {}
|
|
207
|
+
@opts[:sse_connections][@id][@key] = self
|
|
208
|
+
true
|
|
209
|
+
else
|
|
210
|
+
false
|
|
177
211
|
end
|
|
178
212
|
end
|
|
179
213
|
|
|
180
214
|
def onclose
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
tredis.close
|
|
215
|
+
@opts.dig(:sse_connections,@id)&.delete(@key)
|
|
216
|
+
@opts.dig(:sse_connections)&.delete(@id) if @opts.dig(:sse_connections,@id)&.length == 0
|
|
184
217
|
DeleteSubscription::set(@id,@opts,@key)
|
|
185
218
|
end
|
|
186
219
|
end #}}}
|
data/lib/cpee/persistence.rb
CHANGED
|
@@ -125,6 +125,9 @@ module CPEE
|
|
|
125
125
|
def self::extract_handler(id,opts,key) #{{{
|
|
126
126
|
opts[:redis].smembers("instance:#{id}/handlers/#{key}")
|
|
127
127
|
end #}}}
|
|
128
|
+
def self::exists_handler?(id,opts,key) #{{{
|
|
129
|
+
opts[:redis].exists?("instance:#{id}/handlers/#{key}")
|
|
130
|
+
end #}}}
|
|
128
131
|
def self::extract_handlers(id,opts) #{{{
|
|
129
132
|
opts[:redis].smembers("instance:#{id}/handlers").map do |e|
|
|
130
133
|
[e, opts[:redis].get("instance:#{id}/handlers/#{e}/url")]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
189089
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
189071
|
|
@@ -39,7 +39,8 @@ Daemonite.new do |opts|
|
|
|
39
39
|
if url.nil? || url == ""
|
|
40
40
|
redis.publish("forward:#{instance}/#{key}",mess)
|
|
41
41
|
else
|
|
42
|
-
|
|
42
|
+
p "#{type}/#{topic}/#{event}-#{url}"
|
|
43
|
+
client = Riddl::Client.new(url)
|
|
43
44
|
client.post [
|
|
44
45
|
Riddl::Parameter::Simple::new('type',type),
|
|
45
46
|
Riddl::Parameter::Simple::new('topic',topic),
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
189081
|
|
@@ -70,7 +70,7 @@ Daemonite.new do |opts|
|
|
|
70
70
|
persist_handler instance, callback_key, m, redis
|
|
71
71
|
redis.publish("forward:#{instance}/#{subscription_key}",mess)
|
|
72
72
|
else
|
|
73
|
-
client = Riddl::Client.new(url
|
|
73
|
+
client = Riddl::Client.new(url)
|
|
74
74
|
callback = m['instance-url'] + '/callbacks/' + subscription_key
|
|
75
75
|
status, result, headers = (client.post [
|
|
76
76
|
Riddl::Header.new("CPEE-BASE",m['cpee']),
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
189085
|
data/server/server.conf
ADDED
data/server/server.pid
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
189185
|
data/tools/cpee
CHANGED
|
@@ -117,6 +117,16 @@ elsif command == 'convert'
|
|
|
117
117
|
doc.find('//x:start_git').each do |e|
|
|
118
118
|
e.text = 'https://centurio.work/flow-test/start/git/'
|
|
119
119
|
end rescue nil
|
|
120
|
+
doc.find('//d:finalize | //d:update | //d:prepare | //d:rescue').each do |e|
|
|
121
|
+
if e.parent.qname.name != 'code'
|
|
122
|
+
n = e.parent
|
|
123
|
+
if (x = n.find('d:code')).any?
|
|
124
|
+
x.first.add(e)
|
|
125
|
+
else
|
|
126
|
+
n.add('d:code').add(e)
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end rescue nil
|
|
120
130
|
|
|
121
131
|
doc.find('//p:*').each do |e|
|
|
122
132
|
e.namespaces.delete_all!
|
|
@@ -152,7 +162,7 @@ elsif command == 'archive'
|
|
|
152
162
|
XML::Smart.string(res.response_body) do |doc|
|
|
153
163
|
if doc.root.qname.to_s == "instances"
|
|
154
164
|
doc.root.children.each do |i|
|
|
155
|
-
if ["finished","abandoned"].include?(i.attributes['state'])
|
|
165
|
+
if ["finished","abandoned"].include?(i.attributes['state']) || (["ready"].include?(i.attributes['state']) && Time.parse(i.attributes['changed']).to_i < Time.now-(60*60*24))
|
|
156
166
|
prop = Typhoeus.get(File.join(base,name.to_s,i.attributes['id'],'properties','/'))
|
|
157
167
|
if prop.success?
|
|
158
168
|
File.write(File.join(p1,i.attributes['uuid'] + '.xml'),prop.response_body) if prop.headers['Content-Type'] =~ /^(text|application)\/xml/
|
|
@@ -165,11 +175,10 @@ elsif command == 'archive'
|
|
|
165
175
|
if prop.success?
|
|
166
176
|
xprop = XML::Smart::string(prop.response_body)
|
|
167
177
|
xprop.register_namespace 'p', 'http://cpee.org/ns/properties/2.0'
|
|
168
|
-
if ["finished","abandoned"].include?(xprop.find("string(/p:properties/p:state)"))
|
|
178
|
+
if ["finished","abandoned"].include?(xprop.find("string(/p:properties/p:state)")) || (["ready"].include?(xprop.find("string(/p:properties/p:state)")) && Time.parse(xprop.find("string(/p:properties/p:state/@changed)")) < Time.now-(60*60*12))
|
|
169
179
|
uuid = xprop.find("string(/p:properties/p:attributes/p:uuid)")
|
|
170
180
|
id = name.to_s
|
|
171
181
|
File.write(File.join(p1,uuid + '.xml'),prop.response_body) if prop.headers['Content-Type'] =~ /^(text|application)\/xml/
|
|
172
|
-
p File.join(base,name.to_s,'/')
|
|
173
182
|
Typhoeus.delete(File.join(base,name.to_s,'/'))
|
|
174
183
|
end
|
|
175
184
|
end
|
|
@@ -200,11 +209,10 @@ elsif command == 'abandon'
|
|
|
200
209
|
names << File.basename(p1)
|
|
201
210
|
end
|
|
202
211
|
names.each do |name|
|
|
203
|
-
|
|
204
|
-
if
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
Typhoeus.put(File.join(base,name.to_s,'properties','state','/'), headers: {'Content-Type' => 'application/x-www-form-urlencoded'}, body: "value=abandoned")
|
|
212
|
+
res1 = Typhoeus.get(File.join(base,name.to_s,'properties','state','/'))
|
|
213
|
+
if res1.success?
|
|
214
|
+
if res1.response_body == 'ready' || res1.response_body == 'stopped'
|
|
215
|
+
Typhoeus.put(File.join(base,name.to_s,'properties','state','/'), headers: {'Content-Type' => 'application/x-www-form-urlencoded'}, body: "value=abandoned")
|
|
208
216
|
end
|
|
209
217
|
end
|
|
210
218
|
end
|
|
@@ -246,6 +254,7 @@ elsif command == 'delete!'
|
|
|
246
254
|
elsif command == 'new'
|
|
247
255
|
if !File.exists?(p1)
|
|
248
256
|
FileUtils.cp_r("#{curpath}/server/",p1)
|
|
257
|
+
FileUtils.mkdir("#{p1}/archive") rescue nil
|
|
249
258
|
FileUtils.mkdir("#{p1}/instances") rescue nil
|
|
250
259
|
FileUtils.mkdir("#{p1}/resources") rescue nil
|
|
251
260
|
FileUtils.mkdir("#{p1}/handlerwrappers") rescue nil
|
|
@@ -256,9 +265,6 @@ elsif command == 'new'
|
|
|
256
265
|
cont.gsub!(/{CPEEWORKINGDIR}/,"#{File.realpath(p1)}")
|
|
257
266
|
cont.gsub!(/{CPEESERVER}/,"#{File.realpath(p1)}/server")
|
|
258
267
|
File.write("#{p1}/#{nam}",cont)
|
|
259
|
-
p f
|
|
260
|
-
p nam
|
|
261
|
-
p "#{p1}/#{nam}"
|
|
262
268
|
end
|
|
263
269
|
else
|
|
264
270
|
puts 'Directory already exists.'
|