cocaine-framework 0.12.0.pre.rc21 → 0.12.0.pre.rc23
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/cocaine/cocaine.rb +124 -87
- data/lib/cocaine/version.rb +1 -1
- metadata +27 -27
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fad035dd2ae1a69642a32ea41d78d729ab8068e3
|
4
|
+
data.tar.gz: acf30fb66b54c84192b50424246790f12209c6f7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b7d7691273798e932b95ed4b79a9373ffc7cc5a857cac5beb0a0de39a067985b7d1ffd6a9856c213b5059d11e47059104fdb71aa41362fcd78d9c3fb42902d8e
|
7
|
+
data.tar.gz: 219be3119f59aa609c83a1ab45eadae050e3fec4b6150138bd865d409c5a63791d76d31a655fc951502beb4cc05353c5ce38c52fecd7705096e3586b76bd5c6b
|
data/lib/cocaine/cocaine.rb
CHANGED
@@ -64,18 +64,62 @@ module Cocaine
|
|
64
64
|
end
|
65
65
|
|
66
66
|
module RPC
|
67
|
-
|
67
|
+
module Version1
|
68
|
+
CONTROL_CHANNEL = 1
|
68
69
|
|
69
|
-
|
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
|
-
|
72
|
-
|
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
|
-
|
108
|
+
module Version2
|
109
|
+
end
|
75
110
|
|
76
|
-
|
77
|
-
|
78
|
-
|
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
|
-
@
|
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(
|
256
|
-
LOG.debug "-> [#{
|
257
|
-
tx, rx = @sessions[
|
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: [#{
|
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 = @
|
269
|
-
LOG.debug "Invoking #{@name}
|
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(
|
288
|
-
|
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
|
338
|
+
# Service class. All you need is name and (optionally) locator endpoints.
|
294
339
|
class Service < DefinedService
|
295
|
-
def initialize(name,
|
296
|
-
@
|
340
|
+
def initialize(name, endpoints = nil)
|
341
|
+
@location = endpoints
|
297
342
|
|
298
|
-
locator = Locator.new
|
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
|
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(
|
341
|
-
@app
|
342
|
-
@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
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
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
|
-
|
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
|
-
|
420
|
+
|
421
|
+
@socket.write MessagePack::pack @framing.handshake @uuid
|
371
422
|
end
|
372
423
|
|
373
424
|
def health
|
374
|
-
heartbeat = MessagePack::pack
|
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(
|
393
|
-
LOG.debug "-> Message(#{
|
446
|
+
def received(span, id, payload, *extra)
|
447
|
+
LOG.debug "-> Message(#{span}, #{id}, #{payload}, #{extra})"
|
394
448
|
|
395
|
-
|
396
|
-
|
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
|
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: [#{
|
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
|
-
|
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
|
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
|
563
|
+
return Worker.new(options)
|
527
564
|
end
|
528
565
|
end
|
529
566
|
|
data/lib/cocaine/version.rb
CHANGED
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.
|
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-
|
11
|
+
date: 2015-06-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: msgpack
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
20
|
-
type: :
|
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: '
|
26
|
+
version: '0.5'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: celluloid
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
34
|
-
type: :
|
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: '
|
40
|
+
version: '0.16'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: celluloid-io
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
48
|
-
type: :
|
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: '
|
54
|
+
version: '0.16'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: rspec
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
62
|
-
type: :
|
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: '
|
68
|
+
version: '3.2'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: rake
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: '0
|
76
|
-
type: :
|
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
|
82
|
+
version: '10.0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
84
|
+
name: bundler
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: '
|
90
|
-
type: :
|
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: '
|
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.
|
130
|
+
rubygems_version: 2.4.5
|
131
131
|
signing_key:
|
132
132
|
specification_version: 4
|
133
133
|
summary: Ruby/Cocaine library
|