dcell 0.7.1 → 0.8.0
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.
- data/.travis.yml +8 -0
- data/CHANGES.md +5 -0
- data/Rakefile +1 -1
- data/celluloid-zmq/CHANGES.md +4 -0
- data/celluloid-zmq/celluloid-zmq.gemspec +2 -2
- data/celluloid-zmq/lib/celluloid/zmq.rb +4 -9
- data/celluloid-zmq/lib/celluloid/zmq/mailbox.rb +1 -2
- data/celluloid-zmq/lib/celluloid/zmq/reactor.rb +26 -10
- data/celluloid-zmq/lib/celluloid/zmq/version.rb +1 -1
- data/celluloid-zmq/lib/celluloid/zmq/waker.rb +2 -1
- data/dcell.gemspec +3 -3
- data/lib/dcell.rb +9 -3
- data/lib/dcell/celluloid_ext.rb +12 -0
- data/lib/dcell/node.rb +4 -0
- data/lib/dcell/registries/redis_adapter.rb +1 -1
- data/lib/dcell/rpc.rb +66 -0
- data/lib/dcell/version.rb +1 -1
- data/spec/dcell/global_spec.rb +4 -0
- data/spec/test_node.rb +3 -3
- metadata +21 -20
- data/lib/dcell/application.rb +0 -6
data/.travis.yml
ADDED
data/CHANGES.md
CHANGED
data/Rakefile
CHANGED
data/celluloid-zmq/CHANGES.md
CHANGED
@@ -11,8 +11,8 @@ Gem::Specification.new do |gem|
|
|
11
11
|
gem.name = "celluloid-zmq"
|
12
12
|
gem.version = Celluloid::ZMQ::VERSION
|
13
13
|
|
14
|
-
gem.add_dependency "celluloid", "
|
15
|
-
gem.add_dependency "celluloid-io", "
|
14
|
+
gem.add_dependency "celluloid", "~> 0.8.0"
|
15
|
+
gem.add_dependency "celluloid-io", "~> 0.8.0"
|
16
16
|
gem.add_dependency "ffi"
|
17
17
|
gem.add_dependency "ffi-rzmq"
|
18
18
|
|
@@ -24,15 +24,10 @@ module Celluloid
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
-
|
28
|
-
def wait_readable(socket)
|
29
|
-
# Law of demeter be damned!
|
30
|
-
current_actor.mailbox.reactor.wait_readable(socket)
|
31
|
-
end
|
27
|
+
extend Forwardable
|
32
28
|
|
33
|
-
# Wait for the given IO object to become writeable
|
34
|
-
|
35
|
-
|
36
|
-
end
|
29
|
+
# Wait for the given IO object to become readable/writeable
|
30
|
+
def_delegators 'current_actor.mailbox.reactor',
|
31
|
+
:wait_readable, :wait_writeable
|
37
32
|
end
|
38
33
|
end
|
@@ -3,8 +3,13 @@ module Celluloid
|
|
3
3
|
# React to incoming 0MQ and Celluloid events. This is kinda sorta supposed
|
4
4
|
# to resemble the Reactor design pattern.
|
5
5
|
class Reactor
|
6
|
-
|
7
|
-
|
6
|
+
extend Forwardable
|
7
|
+
|
8
|
+
def_delegator :@waker, :signal, :wakeup
|
9
|
+
def_delegator :@waker, :cleanup, :shutdown
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@waker = Waker.new
|
8
13
|
@poller = ::ZMQ::Poller.new
|
9
14
|
@readers = {}
|
10
15
|
@writers = {}
|
@@ -30,13 +35,12 @@ module Celluloid
|
|
30
35
|
if set.has_key? socket
|
31
36
|
raise ArgumentError, "another method is already waiting on #{socket.inspect}"
|
32
37
|
else
|
33
|
-
set[socket] =
|
38
|
+
set[socket] = Task.current
|
34
39
|
end
|
35
40
|
|
36
41
|
@poller.register socket, type
|
37
|
-
Fiber.yield
|
38
42
|
|
39
|
-
|
43
|
+
Task.suspend :zmqwait
|
40
44
|
socket
|
41
45
|
end
|
42
46
|
|
@@ -57,16 +61,28 @@ module Celluloid
|
|
57
61
|
|
58
62
|
@poller.readables.each do |sock|
|
59
63
|
if sock == @waker.socket
|
60
|
-
|
64
|
+
@waker.wait
|
61
65
|
else
|
62
|
-
|
63
|
-
|
66
|
+
task = @readers.delete sock
|
67
|
+
@poller.deregister sock, ::ZMQ::POLLIN
|
68
|
+
|
69
|
+
if task
|
70
|
+
task.resume
|
71
|
+
else
|
72
|
+
Celluloid::Logger.debug "ZMQ error: got read event without associated reader"
|
73
|
+
end
|
64
74
|
end
|
65
75
|
end
|
66
76
|
|
67
77
|
@poller.writables.each do |sock|
|
68
|
-
|
69
|
-
|
78
|
+
task = @writers.delete sock
|
79
|
+
@poller.deregister sock, ::ZMQ::POLLOUT
|
80
|
+
|
81
|
+
if task
|
82
|
+
task.resume
|
83
|
+
else
|
84
|
+
Celluloid::Logger.debug "ZMQ error: got write event without associated reader"
|
85
|
+
end
|
70
86
|
end
|
71
87
|
end
|
72
88
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
module Celluloid
|
2
2
|
module ZMQ
|
3
|
-
|
3
|
+
# You can't wake the dead
|
4
|
+
DeadWakerError = Class.new IOError
|
4
5
|
|
5
6
|
# Wakes up sleepy threads so that they can check their mailbox
|
6
7
|
# Works like a ConditionVariable, except it's implemented as a ZMQ socket
|
data/dcell.gemspec
CHANGED
@@ -16,12 +16,12 @@ Gem::Specification.new do |gem|
|
|
16
16
|
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
17
17
|
gem.require_paths = ["lib"]
|
18
18
|
|
19
|
-
gem.add_dependency "celluloid", "
|
20
|
-
gem.add_dependency "celluloid-zmq", "
|
19
|
+
gem.add_dependency "celluloid", "~> 0.8.0"
|
20
|
+
gem.add_dependency "celluloid-zmq", "~> 0.8.0"
|
21
21
|
gem.add_dependency "redis"
|
22
22
|
gem.add_dependency "redis-namespace"
|
23
23
|
|
24
24
|
gem.add_development_dependency "rake"
|
25
|
-
gem.add_development_dependency "rspec", "
|
25
|
+
gem.add_development_dependency "rspec", "~> 2.7.0"
|
26
26
|
#gem.add_development_dependency "zk"
|
27
27
|
end
|
data/lib/dcell.rb
CHANGED
@@ -10,16 +10,17 @@ require 'dcell/node'
|
|
10
10
|
require 'dcell/global'
|
11
11
|
require 'dcell/responses'
|
12
12
|
require 'dcell/router'
|
13
|
+
require 'dcell/rpc'
|
13
14
|
require 'dcell/server'
|
14
15
|
|
15
16
|
require 'dcell/registries/redis_adapter'
|
16
|
-
require 'dcell/application'
|
17
17
|
require 'dcell/celluloid_ext'
|
18
18
|
|
19
19
|
# Distributed Celluloid
|
20
20
|
module DCell
|
21
21
|
DEFAULT_PORT = 7777 # Default DCell port
|
22
22
|
ZMQ_POOL_SIZE = 1 # DCell uses a fixed-size 0MQ thread pool
|
23
|
+
|
23
24
|
@zmq_context = Celluloid::ZMQ.context = ::ZMQ::Context.new(ZMQ_POOL_SIZE)
|
24
25
|
@config_lock = Mutex.new
|
25
26
|
|
@@ -78,12 +79,12 @@ module DCell
|
|
78
79
|
|
79
80
|
# Run the DCell application
|
80
81
|
def run
|
81
|
-
DCell::
|
82
|
+
DCell::Group.run
|
82
83
|
end
|
83
84
|
|
84
85
|
# Run the DCell application in the background
|
85
86
|
def run!
|
86
|
-
DCell::
|
87
|
+
DCell::Group.run!
|
87
88
|
end
|
88
89
|
|
89
90
|
# Start combines setup and run! into a single step
|
@@ -92,4 +93,9 @@ module DCell
|
|
92
93
|
run!
|
93
94
|
end
|
94
95
|
end
|
96
|
+
|
97
|
+
# DCell's actor dependencies
|
98
|
+
class Group < Celluloid::Group
|
99
|
+
supervise Server, :as => :dcell_server
|
100
|
+
end
|
95
101
|
end
|
data/lib/dcell/celluloid_ext.rb
CHANGED
@@ -54,4 +54,16 @@ module Celluloid
|
|
54
54
|
DCell::MailboxProxy._load(string)
|
55
55
|
end
|
56
56
|
end
|
57
|
+
|
58
|
+
class SyncCall
|
59
|
+
def _dump(level)
|
60
|
+
rpc_id = DCell::RPC::Manager.register self
|
61
|
+
payload = Marshal.dump([@caller,@method,@arguments,@block])
|
62
|
+
"#{rpc_id.to_s(16)}@#{DCell.id}:#{payload}"
|
63
|
+
end
|
64
|
+
|
65
|
+
def self._load(string)
|
66
|
+
DCell::RPC._load(string)
|
67
|
+
end
|
68
|
+
end
|
57
69
|
end
|
data/lib/dcell/node.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
module DCell
|
2
2
|
# A node in a DCell cluster
|
3
3
|
class Node
|
4
|
+
include Celluloid
|
4
5
|
include Celluloid::FSM
|
5
6
|
attr_reader :id, :addr
|
6
7
|
|
@@ -69,6 +70,9 @@ module DCell
|
|
69
70
|
@id, @addr = id, addr
|
70
71
|
@socket = nil
|
71
72
|
@heartbeat = nil
|
73
|
+
|
74
|
+
# Total hax to accommodate the new Celluloid::FSM API
|
75
|
+
attach self
|
72
76
|
end
|
73
77
|
|
74
78
|
def finalize
|
data/lib/dcell/rpc.rb
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'weakref'
|
2
|
+
|
3
|
+
module DCell
|
4
|
+
EPOCH = Time.new(2012, 1, 1, 0, 0, 0, "+00:00") # All things begin in 2012
|
5
|
+
|
6
|
+
class RPC < Celluloid::SyncCall
|
7
|
+
def initialize(id, caller, method, arguments, block)
|
8
|
+
@id, @caller, @method, @arguments, @block = id, caller, method, arguments, block
|
9
|
+
end
|
10
|
+
|
11
|
+
# Custom marshaller for compatibility with Celluloid::Mailbox marshalling
|
12
|
+
def _dump(level)
|
13
|
+
payload = Marshal.dump [@caller, @method, @arguments, @block]
|
14
|
+
"#{@id}:#{payload}"
|
15
|
+
end
|
16
|
+
|
17
|
+
# Loader for custom marshal format
|
18
|
+
def self._load(string)
|
19
|
+
id = string.slice!(0, string.index(":") + 1)
|
20
|
+
match = id.match(/^([0-9a-fA-F]+)@(.+?):$/)
|
21
|
+
raise ArgumentError, "couldn't parse call ID" unless match
|
22
|
+
|
23
|
+
call_id, node_id = match[1], match[2]
|
24
|
+
|
25
|
+
if DCell.id == node_id
|
26
|
+
Manager.claim Integer("0x#{call_id}")
|
27
|
+
else
|
28
|
+
caller, method, arguments, block = Marshal.load(string)
|
29
|
+
RPC.new("#{call_id}@#{node_id}", caller, method, arguments, block)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Tracks calls-in-flight
|
34
|
+
class Manager
|
35
|
+
@mutex = Mutex.new
|
36
|
+
@ids = {}
|
37
|
+
@calls = {}
|
38
|
+
@serial = Integer(Time.now - EPOCH) * 0x100000
|
39
|
+
|
40
|
+
def self.register(call)
|
41
|
+
@mutex.lock
|
42
|
+
call_id = @ids[call.object_id]
|
43
|
+
unless call_id
|
44
|
+
call_id = @serial
|
45
|
+
@serial += 1
|
46
|
+
@ids[call.object_id] = call_id
|
47
|
+
end
|
48
|
+
|
49
|
+
@calls[call_id] = WeakRef.new(call)
|
50
|
+
call_id
|
51
|
+
ensure
|
52
|
+
@mutex.unlock
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.claim(call_id)
|
56
|
+
@mutex.lock
|
57
|
+
ref = @calls.delete(call_id)
|
58
|
+
ref.__getobj__ if ref
|
59
|
+
rescue WeakRef::RefError
|
60
|
+
# Nothing to see here, folks
|
61
|
+
ensure
|
62
|
+
@mutex.unlock
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
data/lib/dcell/version.rb
CHANGED
data/spec/dcell/global_spec.rb
CHANGED
data/spec/test_node.rb
CHANGED
@@ -25,9 +25,9 @@ class TestActor
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
-
class
|
29
|
-
supervise DCell::
|
28
|
+
class TestGroup < Celluloid::Group
|
29
|
+
supervise DCell::Group
|
30
30
|
supervise TestActor, :as => :test_actor
|
31
31
|
end
|
32
32
|
|
33
|
-
|
33
|
+
TestGroup.run
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dcell
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,33 +9,33 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-01-
|
12
|
+
date: 2012-01-24 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: celluloid
|
16
|
-
requirement: &
|
16
|
+
requirement: &70247796045460 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
|
-
- -
|
19
|
+
- - ~>
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: 0.
|
21
|
+
version: 0.8.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70247796045460
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: celluloid-zmq
|
27
|
-
requirement: &
|
27
|
+
requirement: &70247796044740 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
|
-
- -
|
30
|
+
- - ~>
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: 0.
|
32
|
+
version: 0.8.0
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70247796044740
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: redis
|
38
|
-
requirement: &
|
38
|
+
requirement: &70247796043700 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70247796043700
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: redis-namespace
|
49
|
-
requirement: &
|
49
|
+
requirement: &70247796043240 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: '0'
|
55
55
|
type: :runtime
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70247796043240
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: rake
|
60
|
-
requirement: &
|
60
|
+
requirement: &70247796042780 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ! '>='
|
@@ -65,18 +65,18 @@ dependencies:
|
|
65
65
|
version: '0'
|
66
66
|
type: :development
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *70247796042780
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: rspec
|
71
|
-
requirement: &
|
71
|
+
requirement: &70247796042200 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
|
-
- -
|
74
|
+
- - ~>
|
75
75
|
- !ruby/object:Gem::Version
|
76
76
|
version: 2.7.0
|
77
77
|
type: :development
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *70247796042200
|
80
80
|
description: DCell is an distributed object framework based on Celluloid built on
|
81
81
|
0MQ and Zookeeper
|
82
82
|
email:
|
@@ -87,6 +87,7 @@ extra_rdoc_files: []
|
|
87
87
|
files:
|
88
88
|
- .gitignore
|
89
89
|
- .rspec
|
90
|
+
- .travis.yml
|
90
91
|
- CHANGES.md
|
91
92
|
- Gemfile
|
92
93
|
- LICENSE.txt
|
@@ -112,7 +113,6 @@ files:
|
|
112
113
|
- dcell.gemspec
|
113
114
|
- lib/dcell.rb
|
114
115
|
- lib/dcell/actor_proxy.rb
|
115
|
-
- lib/dcell/application.rb
|
116
116
|
- lib/dcell/celluloid_ext.rb
|
117
117
|
- lib/dcell/directory.rb
|
118
118
|
- lib/dcell/global.rb
|
@@ -123,6 +123,7 @@ files:
|
|
123
123
|
- lib/dcell/registries/zk_adapter.rb
|
124
124
|
- lib/dcell/responses.rb
|
125
125
|
- lib/dcell/router.rb
|
126
|
+
- lib/dcell/rpc.rb
|
126
127
|
- lib/dcell/rspec.rb
|
127
128
|
- lib/dcell/server.rb
|
128
129
|
- lib/dcell/version.rb
|