cocaine-framework 0.12.0.pre.rc21 → 0.12.0.pre.rc23

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
  SHA1:
3
- metadata.gz: a4a179f9745f3965fb70ae9220bdb64dec34a21c
4
- data.tar.gz: 1c431053029bdbc7ecbb1ac8bd956aee17130253
3
+ metadata.gz: fad035dd2ae1a69642a32ea41d78d729ab8068e3
4
+ data.tar.gz: acf30fb66b54c84192b50424246790f12209c6f7
5
5
  SHA512:
6
- metadata.gz: edecbd8db23a9f4966483fd7949734fe77a2b8baec126344275c468ba153cab8d73e01b0e001e4de8ea3f0c0a25651c521318b3477c6320b0586260a661e5a7d
7
- data.tar.gz: 20b553e34d3323e86b9b21be2e4340e30e489393a9b871a8b7245ed0004a3a37884e80d3eae299f35f9e0943a3ee712a948a46f712dd61542feea56baefe19de
6
+ metadata.gz: b7d7691273798e932b95ed4b79a9373ffc7cc5a857cac5beb0a0de39a067985b7d1ffd6a9856c213b5059d11e47059104fdb71aa41362fcd78d9c3fb42902d8e
7
+ data.tar.gz: 219be3119f59aa609c83a1ab45eadae050e3fec4b6150138bd865d409c5a63791d76d31a655fc951502beb4cc05353c5ce38c52fecd7705096e3586b76bd5c6b
@@ -64,18 +64,62 @@ module Cocaine
64
64
  end
65
65
 
66
66
  module RPC
67
- CONTROL_CHANNEL = 1
67
+ module Version1
68
+ CONTROL_CHANNEL = 1
68
69
 
69
- HANDSHAKE = 0
70
+ module Messages
71
+ HANDSHAKE, HEARTBEAT, TERMINATE, INVOKE, CHUNK, ERROR, CHOKE = (0..6).to_a
72
+ end
73
+
74
+ class Dispatcher
75
+ def handshake(uuid)
76
+ [CONTROL_CHANNEL, 0, [uuid]]
77
+ end
78
+
79
+ def heartbeat
80
+ [CONTROL_CHANNEL, 1, []]
81
+ end
82
+
83
+ def terminate(errno, reason)
84
+ [CONTROL_CHANNEL, 2, [errno, reason]]
85
+ end
70
86
 
71
- HEARTBEAT = 0
72
- TERMINATE = 1
87
+ def process(span, id)
88
+ case id
89
+ when 1
90
+ :heartbeat
91
+ when 2
92
+ :terminate
93
+ when 3
94
+ :invoke
95
+ when 4
96
+ :chunk
97
+ when 5
98
+ :error
99
+ when 6
100
+ :choke
101
+ else
102
+ :unknown
103
+ end
104
+ end
105
+ end
106
+ end
73
107
 
74
- INVOKE = 0
108
+ module Version2
109
+ end
75
110
 
76
- CHUNK = 0
77
- ERROR = 1
78
- CHOKE = 2
111
+ def self.dispatcher(version)
112
+ case version
113
+ when 0
114
+ Version1::Dispatcher.new
115
+ else
116
+ raise Exception.new 'unsupported version number'
117
+ end
118
+ end
119
+
120
+ CHUNK = 4
121
+ ERROR = 5
122
+ CHOKE = 6
79
123
 
80
124
  RXTREE = {
81
125
  CHUNK => ['write', nil, {}],
@@ -203,7 +247,7 @@ module Cocaine
203
247
 
204
248
  def initialize(name, endpoints, dispatch)
205
249
  @name = name
206
- @dispatch = dispatch
250
+ @framing = dispatch
207
251
  @counter = 1
208
252
  @sessions = Hash.new
209
253
 
@@ -219,11 +263,9 @@ module Cocaine
219
263
  end
220
264
  end
221
265
 
222
- # TODO: I can check for common single-shot protocol here.
223
266
  dispatch.each do |id, (method, txtree, rxtree)|
224
267
  LOG.debug "Defined '#{method}' method for service #{self}"
225
268
  self.metaclass.send(:define_method, method) do |*args|
226
- LOG.debug "Invoking #{@name}.#{method}(#{args})"
227
269
  return invoke(id, *args)
228
270
  end
229
271
  end
@@ -237,6 +279,7 @@ module Cocaine
237
279
  private
238
280
  def run
239
281
  LOG.debug "Service '#{@name}' is running"
282
+
240
283
  unpacker = MessagePack::Unpacker.new
241
284
  loop do
242
285
  data = @socket.readpartial(4096)
@@ -252,21 +295,21 @@ module Cocaine
252
295
  end
253
296
  end
254
297
 
255
- def received(session, id, payload)
256
- LOG.debug "-> [#{session}, #{id}, #{payload}]"
257
- tx, rx = @sessions[session]
298
+ def received(span, id, payload, *extra)
299
+ LOG.debug "-> [#{span}, #{id}, #{payload}, #{extra}]"
300
+ tx, rx = @sessions[span]
258
301
  if rx
259
302
  rx.push id, payload
260
303
  else
261
- LOG.warn "Received message to closed session: [#{session}, #{id}, #{payload}]"
304
+ LOG.warn "Received message to closed session: [#{span}, #{id}, #{payload}]"
262
305
  end
263
306
  end
264
307
 
265
308
  def invoke(id, *args)
266
309
  reinitialize if @socket.nil?
267
310
 
268
- method, txtree, rxtree = @dispatch[id]
269
- LOG.debug "Invoking #{@name}[#{id}=#{method}] with #{args}"
311
+ method, txtree, rxtree = @framing[id]
312
+ LOG.debug "Invoking #{@name} '#{method}' method with #{id} id and #{args} args"
270
313
 
271
314
  txchan = TxChannel.new txtree, @counter, @socket
272
315
  rxchan = RxChannel.new rxtree, @counter do |session|
@@ -284,18 +327,20 @@ module Cocaine
284
327
 
285
328
  # [API]
286
329
  class Locator < DefinedService
287
- def initialize(host=nil, port=nil)
288
- super :locator, [[host || Default::Locator.host, port || Default::Locator.port]], Default::Locator::API
330
+ def initialize(endpoints = nil)
331
+ endpoints ||= [[Default::Locator.host, Default::Locator.port]]
332
+
333
+ super :locator, endpoints, Default::Locator::API
289
334
  end
290
335
  end
291
336
 
292
337
  # [API]
293
- # Service class. All you need is name and (optionally) locator endpoint.
338
+ # Service class. All you need is name and (optionally) locator endpoints.
294
339
  class Service < DefinedService
295
- def initialize(name, host=nil, port=nil)
296
- @options = { host: host, port: port }
340
+ def initialize(name, endpoints = nil)
341
+ @location = endpoints
297
342
 
298
- locator = Locator.new host, port
343
+ locator = Locator.new @location
299
344
  tx, rx = locator.resolve name
300
345
  id, payload = rx.recv
301
346
  if id == :error
@@ -309,7 +354,7 @@ module Cocaine
309
354
 
310
355
  protected
311
356
  def reinitialize
312
- initialize @name, @options[:host], @options[:port]
357
+ initialize @name
313
358
  end
314
359
  end
315
360
 
@@ -337,18 +382,22 @@ module Cocaine
337
382
  execute_block_on_receiver :on
338
383
  finalizer :finalize
339
384
 
340
- def initialize(app, uuid, endpoint)
341
- @app = app
342
- @uuid = uuid
343
- @endpoint = endpoint
385
+ def initialize(options)
386
+ @app = options[:app]
387
+ @uuid = options[:uuid]
388
+ @endpoint = options[:endpoint]
389
+
390
+ @framing = RPC::dispatcher options[:protocol]
391
+
344
392
  @actors = Hash.new
345
393
  @sessions = Hash.new
346
394
 
347
395
  timeout = 60.0
348
- @disown = after(60.0) do
349
- LOG.debug "Terminating due to disown timer expiration (#{timeout} sec)"
350
- # TODO: Hardcoded errno.
351
- exit 1
396
+
397
+ @disown = after timeout do
398
+ LOG.fatal "Terminating due to disown timer expiration (#{timeout} sec)"
399
+
400
+ exit Errno.ETIMEDOUT
352
401
  end
353
402
  end
354
403
 
@@ -358,7 +407,8 @@ module Cocaine
358
407
 
359
408
  def run
360
409
  LOG.debug "Starting worker '#{@app}' with uuid '#{@uuid}' at '#{@endpoint}'"
361
- @socket = UNIXSocket.open(@endpoint)
410
+
411
+ @socket = UNIXSocket.open @endpoint
362
412
  async.handshake
363
413
  async.health
364
414
  async.serve
@@ -367,13 +417,16 @@ module Cocaine
367
417
  private
368
418
  def handshake
369
419
  LOG.debug '<- Handshake'
370
- @socket.write MessagePack::pack([RPC::CONTROL_CHANNEL, RPC::HANDSHAKE, [@uuid]])
420
+
421
+ @socket.write MessagePack::pack @framing.handshake @uuid
371
422
  end
372
423
 
373
424
  def health
374
- heartbeat = MessagePack::pack([RPC::CONTROL_CHANNEL, RPC::HEARTBEAT, []])
425
+ heartbeat = MessagePack::pack @framing.heartbeat
426
+
375
427
  loop do
376
428
  LOG.debug '<- Heartbeat'
429
+
377
430
  @socket.write heartbeat
378
431
  sleep 5.0
379
432
  end
@@ -381,6 +434,7 @@ module Cocaine
381
434
 
382
435
  def serve
383
436
  unpacker = MessagePack::Unpacker.new
437
+
384
438
  loop do
385
439
  data = @socket.readpartial 4096
386
440
  unpacker.feed_each data do |decoded|
@@ -389,62 +443,32 @@ module Cocaine
389
443
  end
390
444
  end
391
445
 
392
- def received(session, id, payload)
393
- LOG.debug "-> Message(#{session}, #{id}, #{payload})"
446
+ def received(span, id, payload, *extra)
447
+ LOG.debug "-> Message(#{span}, #{id}, #{payload}, #{extra})"
394
448
 
395
- if session == RPC::CONTROL_CHANNEL
396
- control session, id, payload
397
- else
398
- rpc session, id, payload
399
- end
400
- end
401
-
402
- def control(session, id, payload)
403
- LOG.debug "Processing control [#{session}, #{id}, #{payload}] message"
404
-
405
- case id
406
- when RPC::HEARTBEAT
449
+ case @framing.process span, id
450
+ when :heartbeat
407
451
  @disown.reset
408
- when RPC::TERMINATE
452
+ when :terminate
409
453
  terminate *payload
454
+ when :invoke
455
+ invoke span, *payload
456
+ when :chunk
457
+ push span, id, *payload
458
+ when :error
459
+ push span, id, *payload
460
+ revoke span
461
+ when :choke
462
+ push span, id, []
463
+ revoke span
410
464
  else
411
- LOG.warn "Received unknown message: [#{session}, #{id}, #{payload}]"
412
- end
413
- end
414
-
415
- def rpc(session, id, payload)
416
- LOG.debug "Processing RPC [#{session}, #{id}, #{payload}] message"
417
-
418
- channels = @sessions.keys
419
- if channels.empty?
420
- min = max = 1
421
- else
422
- min, max = channels.min, channels.max
423
- end
424
-
425
- if session < min
426
- LOG.debug "Dropping session #{session} as unexpected"
427
- return
428
- end
429
-
430
- if session > max
431
- LOG.debug "Invoking new channel #{session}"
432
- invoke session, *payload
433
- return
434
- end
435
-
436
- case id
437
- when RPC::CHUNK, RPC::ERROR
438
- push session, id, *payload
439
- when RPC::CHOKE
440
- LOG.debug "Closing #{session} session"
441
- @sessions.delete session
442
- else
443
- LOG.warn "Received unknown message: [#{session}, #{id}, #{payload}]"
465
+ LOG.warn "Received unknown message: [#{span}, #{id}, #{payload}]"
444
466
  end
445
467
  end
446
468
 
447
469
  def invoke(session, event)
470
+ LOG.debug "Invoking new #{session} channel with #{event} event"
471
+
448
472
  actor = @actors[event]
449
473
  txchan = TxChannel.new RPC::TXTREE, session, @socket
450
474
  rxchan = RxChannel.new RPC::RXTREE, session do |session_|
@@ -472,9 +496,15 @@ module Cocaine
472
496
  end
473
497
  end
474
498
 
499
+ def revoke(span)
500
+ LOG.debug "Closing #{span} channel"
501
+ @sessions.delete span
502
+ end
503
+
475
504
  def terminate(errno, reason)
476
505
  LOG.warn "Terminating [#{errno}]: #{reason}"
477
- @socket.write MessagePack::pack([RPC::CONTROL_CHANNEL, RPC::TERMINATE, [errno, reason]])
506
+
507
+ @socket.write MessagePack::pack @framing.terminate errno, reason
478
508
  exit errno
479
509
  end
480
510
 
@@ -489,6 +519,8 @@ module Cocaine
489
519
  class WorkerFactory
490
520
  def self.create
491
521
  options = {}
522
+ options[:protocol] = 0
523
+
492
524
  OptionParser.new do |opts|
493
525
  opts.banner = 'Usage: <worker.rb> --app NAME --locator ADDRESS --uuid UUID --endpoint ENDPOINT'
494
526
 
@@ -508,22 +540,27 @@ module Cocaine
508
540
  options[:endpoint] = endpoint
509
541
  end
510
542
 
511
- opts.on('--protocol VERSION', 'Worker protocol version') do |protocol|
543
+ opts.on('--protocol VERSION', Integer, 'Worker protocol version') do |protocol|
512
544
  options[:protocol] = protocol
513
545
  end
546
+
547
+ opts.on_tail('--version', 'Show version the Framework version and exit') do
548
+ puts Cocaine::VERSION.join('.')
549
+ exit
550
+ end
514
551
  end.parse!
515
552
 
516
553
  Cocaine::LOG.debug "Options: #{options}"
517
554
  if options.empty? or options.any? { |option, value| value.nil? }
518
555
  Cocaine::LOG.error "Some options aren't specified, but should be. "\
519
556
  "Probably, you're trying to start your application manually. Try to restart your app using Cocaine."
520
- exit 1
557
+ exit Errno::EINVAL
521
558
  end
522
559
 
523
560
  Default::Locator.endpoints = options[:locator].split(',')
524
561
 
525
562
  Cocaine::LOG.debug "Setting default Locator endpoints to #{Default::Locator.endpoints}"
526
- return Worker.new(options[:app], options[:uuid], options[:endpoint])
563
+ return Worker.new(options)
527
564
  end
528
565
  end
529
566
 
@@ -1,4 +1,4 @@
1
1
  module Cocaine
2
2
  # Versions 0.12.0-rc17 and higher are only compatible with Node v2.
3
- VERSION = '0.12.0-rc21'
3
+ VERSION = '0.12.0-rc23'
4
4
  end
metadata CHANGED
@@ -1,99 +1,99 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cocaine-framework
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.0.pre.rc21
4
+ version: 0.12.0.pre.rc23
5
5
  platform: ruby
6
6
  authors:
7
7
  - Evgeny Safronov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-27 00:00:00.000000000 Z
11
+ date: 2015-06-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: rspec
14
+ name: msgpack
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '3.1'
20
- type: :development
19
+ version: '0.5'
20
+ type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '3.1'
26
+ version: '0.5'
27
27
  - !ruby/object:Gem::Dependency
28
- name: rake
28
+ name: celluloid
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
34
- type: :development
33
+ version: '0.16'
34
+ type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '10.0'
40
+ version: '0.16'
41
41
  - !ruby/object:Gem::Dependency
42
- name: bundler
42
+ name: celluloid-io
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '1.7'
48
- type: :development
47
+ version: '0.16'
48
+ type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '1.7'
54
+ version: '0.16'
55
55
  - !ruby/object:Gem::Dependency
56
- name: msgpack
56
+ name: rspec
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '0.5'
62
- type: :runtime
61
+ version: '3.2'
62
+ type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '0.5'
68
+ version: '3.2'
69
69
  - !ruby/object:Gem::Dependency
70
- name: celluloid
70
+ name: rake
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '0.16'
76
- type: :runtime
75
+ version: '10.0'
76
+ type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: '0.16'
82
+ version: '10.0'
83
83
  - !ruby/object:Gem::Dependency
84
- name: celluloid-io
84
+ name: bundler
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: '0.16'
90
- type: :runtime
89
+ version: '1.7'
90
+ type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: '0.16'
96
+ version: '1.7'
97
97
  description: |-
98
98
  Cocaine Framework is a framework for simplifying development both server-side and client-side
99
99
  applications.
@@ -127,7 +127,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
127
127
  version: 1.3.1
128
128
  requirements: []
129
129
  rubyforge_project:
130
- rubygems_version: 2.2.2
130
+ rubygems_version: 2.4.5
131
131
  signing_key:
132
132
  specification_version: 4
133
133
  summary: Ruby/Cocaine library