cpee 2.1.39 → 2.1.43

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/cockpit/config.json +1 -1
  3. data/cockpit/css/graph.css +13 -0
  4. data/cockpit/graph.html +1 -0
  5. data/cockpit/js/instance.js +94 -74
  6. data/cockpit/js_libs.zip +0 -0
  7. data/cockpit/themes/compact/symbols/start_event.svg +2 -2
  8. data/cockpit/themes/compact/symbols/test.svg +74 -0
  9. data/cockpit/themes/control/symbols/start_event.svg +2 -2
  10. data/cockpit/themes/control/symbols/test.svg +74 -0
  11. data/cockpit/themes/default/symbols/start_event.svg +2 -2
  12. data/cockpit/themes/default/symbols/test.svg +74 -0
  13. data/cockpit/themes/extended/symbols/start_event.svg +2 -2
  14. data/cockpit/themes/extended/symbols/test.svg +74 -0
  15. data/cockpit/themes/model/symbols/start_event.svg +2 -2
  16. data/cockpit/themes/model/symbols/test.svg +74 -0
  17. data/cockpit/themes/packed/symbols/start_event.svg +2 -2
  18. data/cockpit/themes/packed/symbols/test.svg +74 -0
  19. data/cockpit/themes/preset/symbols/start_event.svg +2 -2
  20. data/cockpit/themes/preset/symbols/test.svg +74 -0
  21. data/cpee.gemspec +3 -3
  22. data/lib/cpee/implementation.rb +54 -31
  23. data/lib/cpee/message.rb +13 -4
  24. data/server/executionhandlers/ruby/controller.rb +18 -13
  25. data/server/executionhandlers/ruby/dsl_to_dslx.xsl +1 -11
  26. data/server/executionhandlers/ruby/execution.rb +1 -0
  27. data/server/routing/end.rb +3 -2
  28. data/server/routing/forward-events.rb +20 -13
  29. data/server/routing/forward-votes.rb +4 -4
  30. data/server/routing/persist.rb +37 -29
  31. data/server/server.conf +1 -1
  32. data/server/server.pid +1 -0
  33. data/tools/cpee +52 -12
  34. metadata +17 -12
  35. data/server/executionhandlers/ruby/test.xml +0 -43
  36. data/server/routing/end.pid +0 -1
  37. data/server/routing/forward-events.pid +0 -1
  38. data/server/routing/forward-votes.pid +0 -1
  39. data/server/routing/persist.pid +0 -1
@@ -1,5 +1,5 @@
1
1
  <svg class="clickable" xmlns="http://www.w3.org/2000/svg">
2
2
  <circle cx="15" cy="15" r="14" class="cline stand"/>
3
- <rect x="7" y="9" width="16" height="12" class="black" style="fill: none"/>
4
- <path d="m 7,9 8,6 8,-6" class="black" style="fill: none"/>
3
+ <rect x="7" y="10" width="16" height="11" class="black" style="fill: none"/>
4
+ <path d="m 7,10 8,6 8,-6" class="black" style="fill: none"/>
5
5
  </svg>
@@ -0,0 +1,74 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <svg
3
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
4
+ xmlns:cc="http://creativecommons.org/ns#"
5
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
6
+ xmlns:svg="http://www.w3.org/2000/svg"
7
+ xmlns="http://www.w3.org/2000/svg"
8
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
9
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
10
+ class="clickable"
11
+ version="1.1"
12
+ id="svg10"
13
+ sodipodi:docname="test.svg"
14
+ inkscape:version="1.0.2 (e86c870879, 2021-01-15)">
15
+ <metadata
16
+ id="metadata16">
17
+ <rdf:RDF>
18
+ <cc:Work
19
+ rdf:about="">
20
+ <dc:format>image/svg+xml</dc:format>
21
+ <dc:type
22
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
23
+ </cc:Work>
24
+ </rdf:RDF>
25
+ </metadata>
26
+ <defs
27
+ id="defs14" />
28
+ <sodipodi:namedview
29
+ pagecolor="#ffffff"
30
+ bordercolor="#666666"
31
+ borderopacity="1"
32
+ objecttolerance="10"
33
+ gridtolerance="10"
34
+ guidetolerance="10"
35
+ inkscape:pageopacity="0"
36
+ inkscape:pageshadow="2"
37
+ inkscape:window-width="2062"
38
+ inkscape:window-height="1298"
39
+ id="namedview12"
40
+ showgrid="false"
41
+ inkscape:zoom="35.146667"
42
+ inkscape:cx="13.036699"
43
+ inkscape:cy="13.350011"
44
+ inkscape:window-x="0"
45
+ inkscape:window-y="27"
46
+ inkscape:window-maximized="0"
47
+ inkscape:current-layer="svg10" />
48
+ <rect
49
+ transform="rotate(45,14,12)"
50
+ x="7"
51
+ y="3"
52
+ width="21"
53
+ height="21"
54
+ class="cline hfill stand"
55
+ id="rect2"
56
+ style="fill:#3465a4" />
57
+ <circle
58
+ cx="15.5"
59
+ cy="15.5"
60
+ r="7"
61
+ class="stand"
62
+ id="circle4" />
63
+ <circle
64
+ cx="15.5"
65
+ cy="15.5"
66
+ r="7"
67
+ class="stand"
68
+ id="circle6" />
69
+ <path
70
+ d="m 15.500001,11.435193 3.825246,2.779205 -1.461114,4.496849 h -4.728265 l -1.461115,-4.496849 z"
71
+ class="stand"
72
+ id="path8"
73
+ style="fill:#ef2929;stroke-width:1" />
74
+ </svg>
@@ -1,5 +1,5 @@
1
1
  <svg class="clickable" xmlns="http://www.w3.org/2000/svg">
2
2
  <circle cx="15" cy="15" r="14" class="cline stand"/>
3
- <rect x="7" y="9" width="16" height="12" class="black" style="fill: none"/>
4
- <path d="m 7,9 8,6 8,-6" class="black" style="fill: none"/>
3
+ <rect x="7" y="10" width="16" height="11" class="black" style="fill: none"/>
4
+ <path d="m 7,10 8,6 8,-6" class="black" style="fill: none"/>
5
5
  </svg>
@@ -0,0 +1,74 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <svg
3
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
4
+ xmlns:cc="http://creativecommons.org/ns#"
5
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
6
+ xmlns:svg="http://www.w3.org/2000/svg"
7
+ xmlns="http://www.w3.org/2000/svg"
8
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
9
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
10
+ class="clickable"
11
+ version="1.1"
12
+ id="svg10"
13
+ sodipodi:docname="test.svg"
14
+ inkscape:version="1.0.2 (e86c870879, 2021-01-15)">
15
+ <metadata
16
+ id="metadata16">
17
+ <rdf:RDF>
18
+ <cc:Work
19
+ rdf:about="">
20
+ <dc:format>image/svg+xml</dc:format>
21
+ <dc:type
22
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
23
+ </cc:Work>
24
+ </rdf:RDF>
25
+ </metadata>
26
+ <defs
27
+ id="defs14" />
28
+ <sodipodi:namedview
29
+ pagecolor="#ffffff"
30
+ bordercolor="#666666"
31
+ borderopacity="1"
32
+ objecttolerance="10"
33
+ gridtolerance="10"
34
+ guidetolerance="10"
35
+ inkscape:pageopacity="0"
36
+ inkscape:pageshadow="2"
37
+ inkscape:window-width="2062"
38
+ inkscape:window-height="1298"
39
+ id="namedview12"
40
+ showgrid="false"
41
+ inkscape:zoom="35.146667"
42
+ inkscape:cx="13.036699"
43
+ inkscape:cy="13.350011"
44
+ inkscape:window-x="0"
45
+ inkscape:window-y="27"
46
+ inkscape:window-maximized="0"
47
+ inkscape:current-layer="svg10" />
48
+ <rect
49
+ transform="rotate(45,14,12)"
50
+ x="7"
51
+ y="3"
52
+ width="21"
53
+ height="21"
54
+ class="cline hfill stand"
55
+ id="rect2"
56
+ style="fill:#3465a4" />
57
+ <circle
58
+ cx="15.5"
59
+ cy="15.5"
60
+ r="7"
61
+ class="stand"
62
+ id="circle4" />
63
+ <circle
64
+ cx="15.5"
65
+ cy="15.5"
66
+ r="7"
67
+ class="stand"
68
+ id="circle6" />
69
+ <path
70
+ d="m 15.500001,11.435193 3.825246,2.779205 -1.461114,4.496849 h -4.728265 l -1.461115,-4.496849 z"
71
+ class="stand"
72
+ id="path8"
73
+ style="fill:#ef2929;stroke-width:1" />
74
+ </svg>
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.39"
3
+ s.version = "2.1.43"
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."
@@ -21,10 +21,10 @@ 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.114'
24
+ s.add_runtime_dependency 'riddl', '~> 0.126'
25
25
  s.add_runtime_dependency 'weel', '~> 1.99', '>= 1.99.99'
26
26
  s.add_runtime_dependency 'highline', '~> 2.0'
27
- s.add_runtime_dependency 'redis', '~> 4.1'
27
+ s.add_runtime_dependency 'redis', '~> 5.0'
28
28
  s.add_runtime_dependency 'rubyzip', '~>2'
29
29
  s.add_runtime_dependency 'charlock_holmes', '~>0'
30
30
  s.add_runtime_dependency 'mimemagic', '~>0'
@@ -54,7 +54,7 @@ module CPEE
54
54
  /p:properties/p:attributes/p:*
55
55
  }
56
56
  def self::implementation(opts)
57
- opts[:see_instances] ||= opts[:see_instances].nil? ? true : opts[:see_instances]
57
+ opts[:see_instances] ||= opts[:see_instances].nil? ? false : opts[:see_instances]
58
58
 
59
59
  opts[:instances] ||= File.expand_path(File.join(__dir__,'..','..','server','instances'))
60
60
  opts[:global_executionhandlers] ||= File.expand_path(File.join(__dir__,'..','..','server','executionhandlers'))
@@ -69,6 +69,9 @@ module CPEE
69
69
  opts[:watchdog_frequency] ||= 7
70
70
  opts[:watchdog_start_off] ||= false
71
71
  opts[:infinite_loop_stop] ||= 10000
72
+ opts[:workers] ||= 1
73
+ opts[:workers_single] ||= ['end','persist','forward-votes']
74
+ opts[:workers_multi] ||= ['forward-events']
72
75
 
73
76
  opts[:dashing_frequency] ||= 3
74
77
  opts[:dashing_target] ||= nil
@@ -107,11 +110,12 @@ module CPEE
107
110
  Dir[File.join(opts[:executionhandlers],'*','execution.rb')].each do |h|
108
111
  require h
109
112
  end unless opts[:executionhandlers].nil? || opts[:executionhandlers].strip == ''
113
+ CPEE::Message::set_workers(opts[:workers])
110
114
 
111
115
  parallel do
112
- CPEE::watch_services(opts[:watchdog_start_off],opts[:redis_url],File.join(opts[:basepath],opts[:redis_path]),opts[:redis_db])
116
+ CPEE::watch_services(opts[:watchdog_start_off],opts[:redis_url],File.join(opts[:basepath],opts[:redis_path]),opts[:redis_db],opts[:workers],opts[:workers_single],opts[:workers_multi])
113
117
  EM.add_periodic_timer(opts[:watchdog_frequency]) do ### start services
114
- CPEE::watch_services(opts[:watchdog_start_off],opts[:redis_url],File.join(opts[:basepath],opts[:redis_path]),opts[:redis_db])
118
+ CPEE::watch_services(opts[:watchdog_start_off],opts[:redis_url],File.join(opts[:basepath],opts[:redis_path]),opts[:redis_db],opts[:workers],opts[:workers_single],opts[:workers_multi])
115
119
  end
116
120
  EM.defer do ### catch all sse connections
117
121
  CPEE::Notifications::sse_distributor(opts)
@@ -200,31 +204,54 @@ module CPEE
200
204
  end
201
205
  end
202
206
 
203
- def self::watch_services(watchdog_start_off,url,path,db)
207
+ def self::watch_services(watchdog_start_off,url,path,db,workers,workers_single,workers_multi)
204
208
  return if watchdog_start_off
205
- EM.defer do
206
- Dir[File.join(__dir__,'..','..','server','routing','*.rb')].each do |s|
207
- s = s.sub(/\.rb$/,'')
208
- pid = (File.read(s + '.pid').to_i rescue nil)
209
- if (pid.nil? || !(Process.kill(0, pid) rescue false)) && !File.exist?(s + '.lock')
210
- if url.nil?
211
- system "#{s}.rb -p \"#{path}\" -d #{db} restart 1>/dev/null 2>&1"
212
- else
213
- system "#{s}.rb -u \"#{url}\" -d #{db} restart 1>/dev/null 2>&1"
214
- end
215
- puts "➡ Service #{File.basename(s,'.rb')} started ..."
216
- end
217
- end
209
+ EM.defer do
210
+ workers_single.each do |s|
211
+ s = File.join(__dir__,'..','..','server','routing',s)
212
+ next if File.exist?(s + '.lock')
213
+ pid = (File.read(s + '.pid').to_i rescue nil)
214
+ if (pid.nil? || !(Process.kill(0, pid) rescue false))
215
+ cmd = if url.nil?
216
+ "-p \"#{path}\" -d #{db} -w #{workers} restart 1>/dev/null 2>&1"
217
+ else
218
+ "-u \"#{url}\" -d #{db} -w #{workers} restart 1>/dev/null 2>&1"
219
+ end
220
+ system "#{s}.rb " + cmd + " 1>/dev/null 2>&1"
221
+ puts "➡ Service #{File.basename(s)} (#{cmd}) started ..."
222
+ end
223
+ end
224
+ workers_multi.each do |s|
225
+ s = File.join(__dir__,'..','..','server','routing',s.to_s)
226
+ next if File.exist?(s + '.lock')
227
+ (0...workers).each do |w|
228
+ w = '%02i' % w
229
+ pid = (File.read(s + '-' + w + '.pid').to_i rescue nil)
230
+ if (pid.nil? || !(Process.kill(0, pid) rescue false))
231
+ cmd = if url.nil?
232
+ "-p \"#{path}\" -d #{db} -w #{w} restart"
233
+ else
234
+ "-u \"#{url}\" -d #{db} -w #{w} restart"
235
+ end
236
+ system "#{s}.rb " + cmd + " 1>/dev/null 2>&1"
237
+ puts "➡ Service #{File.basename(s)}-#{w} (#{cmd}) started ..."
238
+ end
239
+ end
240
+ end
218
241
  end
219
242
  end
220
243
  def self::cleanup_services(watchdog_start_off)
221
244
  return if watchdog_start_off
222
- Dir[File.join(__dir__,'..','..','server','routing','*.rb')].each do |s|
223
- s = s.sub(/\.rb$/,'')
224
- pid = (File.read(s + '.pid').to_i rescue nil)
245
+ Dir[File.join(__dir__,'..','..','server','routing','*.pid')].each do |s|
246
+ pid = (File.read(s).to_i rescue nil)
225
247
  if !pid.nil? || (Process.kill(0, pid) rescue false)
226
- system "#{s}.rb stop 1>/dev/null 2>&1"
227
- puts "➡ Service #{File.basename(s,'.rb')} stopped ..."
248
+ f = s.sub(/(-(\d+))?\.pid$/,'.rb')
249
+ if $2.nil?
250
+ system "#{f} stop 1>/dev/null 2>&1"
251
+ else
252
+ system "#{f} -w #{$2} stop 1>/dev/null 2>&1"
253
+ end
254
+ puts "➡ Service #{File.basename(s,'.pid')} stopped ..."
228
255
  end
229
256
  end
230
257
  end
@@ -232,7 +259,6 @@ module CPEE
232
259
  class Instances < Riddl::Implementation #{{{
233
260
  def response
234
261
  opts = @a[0]
235
- pp @request[:env]['REMOTE_ADDR']
236
262
  if opts[:see_instances] || @h['SEE_INSTANCES'] == 'true'
237
263
  Riddl::Parameter::Complex.new("wis","text/xml") do
238
264
  ins = XML::Smart::string('<instances/>')
@@ -363,15 +389,12 @@ module CPEE
363
389
  CPEE::Message::send(:event,'state/change',File.join(opts[:url],'/'),id,content[:attributes]['uuid'],content[:attributes]['info'],content,redis)
364
390
  end
365
391
 
366
- EM::add_timer(30) do
367
- empt = CPEE::Persistence::keys(id,opts).to_a
368
- ### is there to avoid that returning calls get intro problems
369
- ### as we have add_timer now, it should work without this
370
- # empt.delete_if{|e| e =~ /\/handlers/ }
371
- redis.multi do |multi|
372
- multi.del empt
373
- multi.zrem 'instances', id
392
+ empt = CPEE::Persistence::keys(id,opts).to_a
393
+ redis.multi do |multi|
394
+ empt.each do |e|
395
+ multi.expire e, 30
374
396
  end
397
+ multi.zrem 'instances', id
375
398
  end
376
399
  end
377
400
  end #}}}
data/lib/cpee/message.rb CHANGED
@@ -18,7 +18,17 @@ module CPEE
18
18
  WHO = 'cpee'
19
19
  TYPE = 'instance'
20
20
 
21
- def self::send(type, event, cpee, instance, instance_uuid, instance_name, content={}, backend)
21
+ def self::set_workers(workers)
22
+ @@tworkers = (workers < 1 && workers > 99 ? 1 : workers).freeze
23
+ @@last = -1
24
+ end
25
+
26
+ def self::target
27
+ @@last < @@tworkers-1 ? @@last += 1 : @@last = 0
28
+ end
29
+
30
+ def self::send(type, event, cpee, instance, instance_uuid, instance_name, content={}, backend=nil)
31
+ target = '%02i' % CPEE::Message::target
22
32
  topic = ::File::dirname(event)
23
33
  name = ::File::basename(event)
24
34
  payload = {
@@ -33,7 +43,8 @@ module CPEE
33
43
  }
34
44
  payload[TYPE + '-uuid'] = instance_uuid if instance_uuid
35
45
  payload[TYPE + '-name'] = instance_name if instance_name
36
- backend.publish(type.to_s + ':' + event,
46
+
47
+ backend.publish(type.to_s + ':' + target + ':' + event.to_s,
37
48
  instance.to_s + ' ' +
38
49
  JSON::generate(payload)
39
50
  )
@@ -52,14 +63,12 @@ module CPEE
52
63
  'content' => content
53
64
  }
54
65
  client = Riddl::Client.new(backend)
55
- p backend
56
66
  client.post [
57
67
  Riddl::Parameter::Simple::new('type',type),
58
68
  Riddl::Parameter::Simple::new('topic',topic),
59
69
  Riddl::Parameter::Simple::new('event',name),
60
70
  Riddl::Parameter::Complex::new('notification','application/json',JSON::generate(payload))
61
71
  ]
62
- p backend + '------'
63
72
  end
64
73
  end
65
74
  end
@@ -35,6 +35,7 @@ def ⭐(a); ParaStruct.new(a); end
35
35
  class Controller
36
36
  def initialize(id,dir,opts)
37
37
  CPEE::redis_connect(opts,"Instance #{id}")
38
+ CPEE::Message::set_workers(opts[:workers])
38
39
 
39
40
  @redis = opts[:redis]
40
41
  @votes = []
@@ -58,23 +59,27 @@ class Controller
58
59
  @psredis = @opts[:redis_dyn].call "Instance #{@id} Callback Response"
59
60
  @psredis.psubscribe('callback-response:*','callback-end:*') do |on|
60
61
  on.pmessage do |pat, what, message|
61
- if pat == 'callback-response:*' && @callback_keys.has_key?(what[18..-1])
62
- index = message.index(' ')
63
- mess = message[index+1..-1]
64
- instance = message[0...index]
65
- m = JSON.parse(mess)
66
- resp = []
67
- m['content']['values'].each do |e|
68
- if e[1][0] == 'simple'
69
- resp << Riddl::Parameter::Simple.new(e[0],e[1][1])
70
- elsif e[1][0] == 'complex'
71
- resp << Riddl::Parameter::Complex.new(e[0],e[1][1],File.open(e[1][2]))
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 = message[0...index]
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],File.open(e[1][2]))
75
+ end
72
76
  end
77
+ @callback_keys[identifier].send(:callback,resp,m['content']['headers'])
73
78
  end
74
- @callback_keys[what[18..-1]].send(:callback,resp,m['content']['headers'])
75
79
  end
76
80
  if pat == 'callback-end:*'
77
- @callback_keys.delete(what[13..-1])
81
+ _, worker, identifier = what.split(':')
82
+ @callback_keys.delete(identifier)
78
83
  end
79
84
  end
80
85
  end
@@ -374,17 +374,7 @@
374
374
  <xsl:value-of select="$myspace+$myspacemultiplier"/>
375
375
  </xsl:with-param>
376
376
  </xsl:call-template>
377
- <xsl:text>parallel_branch</xsl:text>
378
- <xsl:if test="@pass">
379
- <xsl:text> </xsl:text>
380
- <xsl:value-of select="@pass"/>
381
- </xsl:if>
382
- <xsl:text> do</xsl:text>
383
- <xsl:if test="@local">
384
- <xsl:text> |</xsl:text>
385
- <xsl:value-of select="@local"/>
386
- <xsl:text>|</xsl:text>
387
- </xsl:if>
377
+ <xsl:text>parallel_branch data do |local|</xsl:text>
388
378
  <xsl:call-template name="print-newline"/>
389
379
  <xsl:apply-templates>
390
380
  <xsl:with-param name="myspace">
@@ -46,6 +46,7 @@ module CPEE
46
46
  :redis_url => opts[:redis_url],
47
47
  :redis_path => File.join(opts[:basepath],opts[:redis_path]),
48
48
  :redis_db => opts[:redis_db],
49
+ :workers => opts[:workers],
49
50
  :global_executionhandlers => opts[:global_executionhandlers],
50
51
  :executionhandlers => opts[:executionhandlers],
51
52
  :executionhandler => hw
@@ -23,7 +23,8 @@ Daemonite.new do |opts|
23
23
  opts[:runtime_opts] += [
24
24
  ["--url=URL", "-uURL", "Specify redis url", ->(p){ opts[:redis_url] = p }],
25
25
  ["--path=PATH", "-pPATH", "Specify redis path, e.g. /tmp/redis.sock", ->(p){ opts[:redis_path] = p }],
26
- ["--db=DB", "-dDB", "Specify redis db, e.g. 1", ->(p) { opts[:redis_db] = p.to_i }]
26
+ ["--db=DB", "-dDB", "Specify redis db, e.g. 1", ->(p) { opts[:redis_db] = p.to_i }],
27
+ ["--workers=NUM", "-wNUM", "Number of workers that are expected, e.g. 3", ->(p) { opts[:workers] = p.to_i }]
27
28
  ]
28
29
 
29
30
  on startup do
@@ -37,7 +38,7 @@ Daemonite.new do |opts|
37
38
  run do
38
39
  opts[:pubsubredis].psubscribe('callback-end:*') do |on|
39
40
  on.pmessage do |pat, what, message|
40
- _, key = what.split(':')
41
+ _, worker, key = what.split(':',3)
41
42
  index = message.index(' ')
42
43
  instance = message[0...index]
43
44
  opts[:redis].multi do |multi|
@@ -23,25 +23,30 @@ Daemonite.new do |opts|
23
23
  opts[:runtime_opts] += [
24
24
  ["--url=URL", "-uURL", "Specify redis url", ->(p){ opts[:redis_url] = p }],
25
25
  ["--path=PATH", "-pPATH", "Specify redis path, e.g. /tmp/redis.sock", ->(p){ opts[:redis_path] = p }],
26
- ["--db=DB", "-dDB", "Specify redis db, e.g. 1", ->(p) { opts[:redis_db] = p.to_i }]
26
+ ["--db=DB", "-dDB", "Specify redis db, e.g. 1", ->(p) { opts[:redis_db] = p.to_i }],
27
+ ["--worker=NUM", "-wNUM", "Specify the worker id, e.g. 0", ->(p) { opts[:worker] = p.to_i }]
27
28
  ]
28
29
 
30
+ on setup do
31
+ opts[:worker] ||= 0
32
+ opts[:worker] = ('%02i' % opts[:worker]).freeze
33
+ opts[:pidfile] = File.basename(opts[:pidfile],'.pid') + '-' + opts[:worker].to_s + '.pid'
34
+ end
35
+
29
36
  on startup do
30
37
  opts[:redis_path] ||= '/tmp/redis.sock'
31
38
  opts[:redis_db] ||= 1
32
-
33
39
  CPEE::redis_connect opts, 'Server Routing Forward Events'
34
40
  opts[:pubsubredis] = opts[:redis_dyn].call 'Server Routing Forward Events Sub'
35
41
  end
36
42
 
37
43
  run do
38
- opts[:pubsubredis].psubscribe('event:*') do |on|
44
+ opts[:pubsubredis].psubscribe("event:#{opts[:worker]}:*") do |on|
39
45
  on.pmessage do |pat, what, message|
40
46
  index = message.index(' ')
41
47
  mess = message[index+1..-1]
42
48
  instance = message[0...index]
43
- type = pat[0..-3]
44
- event = what[(type.length+1)..-1]
49
+ type, worker, event = what.split(':',3)
45
50
  topic = ::File::dirname(event)
46
51
  name = ::File::basename(event)
47
52
  long = File.join(topic,type,name)
@@ -51,14 +56,16 @@ Daemonite.new do |opts|
51
56
  if url.nil? || url == ""
52
57
  opts[:redis].publish("forward:#{instance}/#{key}",mess)
53
58
  else
54
- p "#{type}/#{topic}/#{event}-#{url}"
55
- client = Riddl::Client.new(url)
56
- client.post [
57
- Riddl::Parameter::Simple::new('type',type),
58
- Riddl::Parameter::Simple::new('topic',topic),
59
- Riddl::Parameter::Simple::new('event',name),
60
- Riddl::Parameter::Complex::new('notification','application/json',mess)
61
- ]
59
+ # Ractor.new(url,type,topic,name,mess) do |url,type,topic,name,mess|
60
+ # sadly typhoes does not support ractors
61
+ Thread.new do
62
+ Riddl::Client.new(url).post [
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
62
69
  end
63
70
  end
64
71
  end
@@ -49,7 +49,8 @@ Daemonite.new do |opts|
49
49
  opts[:runtime_opts] += [
50
50
  ["--url=URL", "-uURL", "Specify redis url", ->(p){ opts[:redis_url] = p }],
51
51
  ["--path=PATH", "-pPATH", "Specify redis path, e.g. /tmp/redis.sock", ->(p){ opts[:redis_path] = p }],
52
- ["--db=DB", "-dDB", "Specify redis db, e.g. 1", ->(p) { opts[:redis_db] = p.to_i }]
52
+ ["--db=DB", "-dDB", "Specify redis db, e.g. 1", ->(p) { opts[:redis_db] = p.to_i }],
53
+ ["--workers=NUM", "-wNUM", "Number of workers that are expected, e.g. 3", ->(p) { opts[:workers] = p.to_i }]
53
54
  ]
54
55
 
55
56
  on startup do
@@ -64,11 +65,10 @@ Daemonite.new do |opts|
64
65
  opts[:pubsubredis].psubscribe('vote:*') do |on|
65
66
  on.pmessage do |pat, what, message|
66
67
  index = message.index(' ')
68
+ instance = message[0...index]
67
69
  mess = message[index+1..-1]
68
70
 
69
- instance = message[0...index]
70
- type = pat[0..-3]
71
- event = what[(type.length+1)..-1]
71
+ type, worker, event = what.split(':',3)
72
72
  topic = ::File::dirname(event)
73
73
  name = ::File::basename(event)
74
74
  long = File.join(topic,type,name)