dcell 0.9.0 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +4 -1
- data/CHANGES.md +11 -0
- data/Gemfile +6 -3
- data/LICENSE.txt +1 -1
- data/README.md +27 -243
- data/benchmarks/receiver.rb +2 -2
- data/dcell.gemspec +7 -7
- data/explorer/css/bootstrap-responsive.css +686 -0
- data/explorer/css/bootstrap-responsive.min.css +12 -0
- data/explorer/css/bootstrap.css +3990 -0
- data/explorer/css/bootstrap.min.css +689 -0
- data/explorer/css/explorer.css +28 -0
- data/explorer/ico/favicon.ico +0 -0
- data/explorer/img/glyphicons-halflings-white.png +0 -0
- data/explorer/img/glyphicons-halflings.png +0 -0
- data/explorer/img/logo.png +0 -0
- data/explorer/index.html.erb +94 -0
- data/explorer/js/bootstrap.js +1726 -0
- data/explorer/js/bootstrap.min.js +6 -0
- data/lib/dcell.rb +27 -2
- data/lib/dcell/celluloid_ext.rb +14 -3
- data/lib/dcell/directory.rb +15 -3
- data/lib/dcell/explorer.rb +76 -0
- data/lib/dcell/future_proxy.rb +32 -0
- data/lib/dcell/info_service.rb +117 -0
- data/lib/dcell/mailbox_proxy.rb +6 -7
- data/lib/dcell/messages.rb +5 -6
- data/lib/dcell/node.rb +25 -55
- data/lib/dcell/node_manager.rb +81 -0
- data/lib/dcell/registries/cassandra_adapter.rb +86 -0
- data/lib/dcell/registries/gossip/core.rb +235 -0
- data/lib/dcell/registries/gossip_adapter.rb +26 -0
- data/lib/dcell/registries/moneta_adapter.rb +0 -7
- data/lib/dcell/registries/redis_adapter.rb +0 -31
- data/lib/dcell/registries/zk_adapter.rb +1 -39
- data/lib/dcell/router.rb +37 -30
- data/lib/dcell/rpc.rb +23 -23
- data/lib/dcell/server.rb +5 -2
- data/lib/dcell/version.rb +1 -1
- data/logo.png +0 -0
- data/spec/dcell/actor_proxy_spec.rb +4 -0
- data/spec/dcell/celluloid_ext_spec.rb +11 -0
- data/spec/dcell/directory_spec.rb +1 -1
- data/spec/dcell/explorer_spec.rb +17 -0
- data/spec/dcell/global_spec.rb +4 -0
- data/spec/dcell/registries/gossip_adapter_spec.rb +6 -0
- data/spec/spec_helper.rb +14 -7
- data/spec/support/registry_examples.rb +0 -18
- data/tasks/cassandra.task +84 -0
- metadata +55 -35
- data/celluloid-zmq/.gitignore +0 -17
- data/celluloid-zmq/.rspec +0 -4
- data/celluloid-zmq/CHANGES.md +0 -31
- data/celluloid-zmq/Gemfile +0 -7
- data/celluloid-zmq/README.md +0 -56
- data/celluloid-zmq/Rakefile +0 -7
- data/celluloid-zmq/celluloid-zmq.gemspec +0 -28
- data/celluloid-zmq/lib/celluloid/zmq.rb +0 -36
- data/celluloid-zmq/lib/celluloid/zmq/reactor.rb +0 -90
- data/celluloid-zmq/lib/celluloid/zmq/sockets.rb +0 -130
- data/celluloid-zmq/lib/celluloid/zmq/version.rb +0 -5
- data/celluloid-zmq/lib/celluloid/zmq/waker.rb +0 -55
- data/celluloid-zmq/spec/celluloid/zmq/actor_spec.rb +0 -6
- data/celluloid-zmq/spec/spec_helper.rb +0 -2
@@ -1,36 +0,0 @@
|
|
1
|
-
require 'ffi-rzmq'
|
2
|
-
|
3
|
-
require 'celluloid/io'
|
4
|
-
require 'celluloid/zmq/reactor'
|
5
|
-
require 'celluloid/zmq/sockets'
|
6
|
-
require 'celluloid/zmq/version'
|
7
|
-
require 'celluloid/zmq/waker'
|
8
|
-
|
9
|
-
module Celluloid
|
10
|
-
# Actors which run alongside 0MQ sockets
|
11
|
-
module ZMQ
|
12
|
-
class << self
|
13
|
-
attr_writer :context
|
14
|
-
|
15
|
-
# Included hook to pull in Celluloid
|
16
|
-
def included(klass)
|
17
|
-
klass.send :include, ::Celluloid
|
18
|
-
klass.use_mailbox { Celluloid::IO::Mailbox.new ZMQ::Reactor.new }
|
19
|
-
end
|
20
|
-
|
21
|
-
# Obtain a 0MQ context (or lazily initialize it)
|
22
|
-
def context(threads = 1)
|
23
|
-
return @context if @context
|
24
|
-
@context = ::ZMQ::Context.new(threads)
|
25
|
-
at_exit { @context.terminate }
|
26
|
-
@context
|
27
|
-
end
|
28
|
-
alias_method :init, :context
|
29
|
-
end
|
30
|
-
|
31
|
-
extend Forwardable
|
32
|
-
|
33
|
-
# Wait for the given IO object to become readable/writeable
|
34
|
-
def_delegators 'current_actor.mailbox.reactor', :wait_readable, :wait_writeable
|
35
|
-
end
|
36
|
-
end
|
@@ -1,90 +0,0 @@
|
|
1
|
-
module Celluloid
|
2
|
-
module ZMQ
|
3
|
-
# React to incoming 0MQ and Celluloid events. This is kinda sorta supposed
|
4
|
-
# to resemble the Reactor design pattern.
|
5
|
-
class Reactor
|
6
|
-
extend Forwardable
|
7
|
-
|
8
|
-
def_delegator :@waker, :signal, :wakeup
|
9
|
-
def_delegator :@waker, :cleanup, :shutdown
|
10
|
-
|
11
|
-
def initialize
|
12
|
-
@waker = Waker.new
|
13
|
-
@poller = ::ZMQ::Poller.new
|
14
|
-
@readers = {}
|
15
|
-
@writers = {}
|
16
|
-
|
17
|
-
rc = @poller.register @waker.socket, ::ZMQ::POLLIN
|
18
|
-
unless ::ZMQ::Util.resultcode_ok? rc
|
19
|
-
raise "0MQ poll error: #{::ZMQ::Util.error_string}"
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
# Wait for the given ZMQ socket to become readable
|
24
|
-
def wait_readable(socket)
|
25
|
-
monitor_zmq socket, @readers, ::ZMQ::POLLIN
|
26
|
-
end
|
27
|
-
|
28
|
-
# Wait for the given ZMQ socket to become writeable
|
29
|
-
def wait_writeable(socket)
|
30
|
-
monitor_zmq socket, @writers, ::ZMQ::POLLOUT
|
31
|
-
end
|
32
|
-
|
33
|
-
# Monitor the given ZMQ socket with the given options
|
34
|
-
def monitor_zmq(socket, set, type)
|
35
|
-
if set.has_key? socket
|
36
|
-
raise ArgumentError, "another method is already waiting on #{socket.inspect}"
|
37
|
-
else
|
38
|
-
set[socket] = Task.current
|
39
|
-
end
|
40
|
-
|
41
|
-
@poller.register socket, type
|
42
|
-
|
43
|
-
Task.suspend :zmqwait
|
44
|
-
socket
|
45
|
-
end
|
46
|
-
|
47
|
-
# Run the reactor, waiting for events, and calling the given block if
|
48
|
-
# the reactor is awoken by the waker
|
49
|
-
def run_once(timeout = nil)
|
50
|
-
if timeout
|
51
|
-
timeout *= 1000 # Poller uses millisecond increments
|
52
|
-
else
|
53
|
-
timeout = :blocking
|
54
|
-
end
|
55
|
-
|
56
|
-
rc = @poller.poll(timeout)
|
57
|
-
|
58
|
-
unless ::ZMQ::Util.resultcode_ok? rc
|
59
|
-
raise IOError, "0MQ poll error: #{::ZMQ::Util.error_string}"
|
60
|
-
end
|
61
|
-
|
62
|
-
@poller.readables.each do |sock|
|
63
|
-
if sock == @waker.socket
|
64
|
-
@waker.wait
|
65
|
-
else
|
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
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
@poller.writables.each do |sock|
|
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
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
@@ -1,130 +0,0 @@
|
|
1
|
-
module Celluloid
|
2
|
-
module ZMQ
|
3
|
-
class Socket
|
4
|
-
# Create a new socket
|
5
|
-
def initialize(type)
|
6
|
-
@socket = Celluloid::ZMQ.context.socket ::ZMQ.const_get(type.to_s.upcase)
|
7
|
-
end
|
8
|
-
|
9
|
-
# Connect to the given 0MQ address
|
10
|
-
# Address should be in the form: tcp://1.2.3.4:5678/
|
11
|
-
def connect(addr)
|
12
|
-
puts "zomg connecting"
|
13
|
-
unless ::ZMQ::Util.resultcode_ok? @socket.connect addr
|
14
|
-
raise IOError, "error connecting to #{addr}: #{::ZMQ::Util.error_string}"
|
15
|
-
end
|
16
|
-
true
|
17
|
-
end
|
18
|
-
|
19
|
-
# Bind to the given 0MQ address
|
20
|
-
# Address should be in the form: tcp://1.2.3.4:5678/
|
21
|
-
def bind(addr)
|
22
|
-
unless ::ZMQ::Util.resultcode_ok? @socket.setsockopt(::ZMQ::LINGER, 0)
|
23
|
-
@socket.close
|
24
|
-
raise IOError, "couldn't set ZMQ::LINGER: #{::ZMQ::Util.error_string}"
|
25
|
-
end
|
26
|
-
|
27
|
-
unless ::ZMQ::Util.resultcode_ok? @socket.bind(addr)
|
28
|
-
raise IOError, "couldn't bind to #{addr}: #{::ZMQ::Util.error_string}"
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
# Close the socket
|
33
|
-
def close
|
34
|
-
@socket.close
|
35
|
-
end
|
36
|
-
|
37
|
-
# Does the 0MQ socket support evented operation?
|
38
|
-
def evented?
|
39
|
-
actor = Thread.current[:actor]
|
40
|
-
return unless actor
|
41
|
-
|
42
|
-
mailbox = actor.mailbox
|
43
|
-
mailbox.is_a?(Celluloid::IO::Mailbox) && mailbox.reactor.is_a?(Celluloid::ZMQ::Reactor)
|
44
|
-
end
|
45
|
-
|
46
|
-
# Hide ffi-rzmq internals
|
47
|
-
alias_method :inspect, :to_s
|
48
|
-
end
|
49
|
-
|
50
|
-
# Readable 0MQ sockets have a read method
|
51
|
-
module ReadableSocket
|
52
|
-
# Read a message from the socket
|
53
|
-
def read(buffer = '')
|
54
|
-
Celluloid.current_actor.wait_readable(@socket) if evented?
|
55
|
-
|
56
|
-
unless ::ZMQ::Util.resultcode_ok? @socket.recv_string buffer
|
57
|
-
raise IOError, "error receiving ZMQ string: #{::ZMQ::Util.error_string}"
|
58
|
-
end
|
59
|
-
buffer
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
# Writable 0MQ sockets have a send method
|
64
|
-
module WritableSocket
|
65
|
-
# Send a message to the socket
|
66
|
-
def send(message)
|
67
|
-
unless ::ZMQ::Util.resultcode_ok? @socket.send_string message
|
68
|
-
raise IOError, "error sending 0MQ message: #{::ZMQ::Util.error_string}"
|
69
|
-
end
|
70
|
-
|
71
|
-
message
|
72
|
-
end
|
73
|
-
alias_method :<<, :send
|
74
|
-
end
|
75
|
-
|
76
|
-
# ReqSockets are the counterpart of RepSockets (REQ/REP)
|
77
|
-
class ReqSocket < Socket
|
78
|
-
include ReadableSocket
|
79
|
-
|
80
|
-
def initialize
|
81
|
-
super :req
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
# RepSockets are the counterpart of ReqSockets (REQ/REP)
|
86
|
-
class RepSocket < Socket
|
87
|
-
include WritableSocket
|
88
|
-
|
89
|
-
def initialize
|
90
|
-
super :rep
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
# PushSockets are the counterpart of PullSockets (PUSH/PULL)
|
95
|
-
class PushSocket < Socket
|
96
|
-
include WritableSocket
|
97
|
-
|
98
|
-
def initialize
|
99
|
-
super :push
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
# PullSockets are the counterpart of PushSockets (PUSH/PULL)
|
104
|
-
class PullSocket < Socket
|
105
|
-
include ReadableSocket
|
106
|
-
|
107
|
-
def initialize
|
108
|
-
super :pull
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
# PubSockets are the counterpart of SubSockets (PUB/SUB)
|
113
|
-
class PubSocket < Socket
|
114
|
-
include WritableSocket
|
115
|
-
|
116
|
-
def initialize
|
117
|
-
super :pub
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
# SubSockets are the counterpart of PubSockets (PUB/SUB)
|
122
|
-
class SubSocket < Socket
|
123
|
-
include ReadableSocket
|
124
|
-
|
125
|
-
def initialize
|
126
|
-
super :sub
|
127
|
-
end
|
128
|
-
end
|
129
|
-
end
|
130
|
-
end
|
@@ -1,55 +0,0 @@
|
|
1
|
-
module Celluloid
|
2
|
-
module ZMQ
|
3
|
-
# You can't wake the dead
|
4
|
-
DeadWakerError = Class.new IOError
|
5
|
-
|
6
|
-
# Wakes up sleepy threads so that they can check their mailbox
|
7
|
-
# Works like a ConditionVariable, except it's implemented as a ZMQ socket
|
8
|
-
# so that it can be multiplexed alongside other ZMQ sockets
|
9
|
-
class Waker
|
10
|
-
PAYLOAD = "\0" # the payload doesn't matter, it's just a signal
|
11
|
-
|
12
|
-
def initialize
|
13
|
-
@sender = ZMQ.context.socket(::ZMQ::PAIR)
|
14
|
-
@receiver = ZMQ.context.socket(::ZMQ::PAIR)
|
15
|
-
|
16
|
-
@addr = "inproc://waker-#{object_id}"
|
17
|
-
@sender.bind @addr
|
18
|
-
@receiver.connect @addr
|
19
|
-
|
20
|
-
@sender_lock = Mutex.new
|
21
|
-
end
|
22
|
-
|
23
|
-
# Wakes up the thread that is waiting for this Waker
|
24
|
-
def signal
|
25
|
-
@sender_lock.synchronize do
|
26
|
-
unless ::ZMQ::Util.resultcode_ok? @sender.send_string PAYLOAD
|
27
|
-
raise DeadWakerError, "error sending 0MQ message: #{::ZMQ::Util.error_string}"
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
# 0MQ socket to wait for messages on
|
33
|
-
def socket
|
34
|
-
@receiver
|
35
|
-
end
|
36
|
-
|
37
|
-
# Wait for another thread to signal this Waker
|
38
|
-
def wait
|
39
|
-
message = ''
|
40
|
-
rc = @receiver.recv_string message
|
41
|
-
|
42
|
-
unless ::ZMQ::Util.resultcode_ok? rc and message == PAYLOAD
|
43
|
-
raise DeadWakerError, "error receiving ZMQ string: #{::ZMQ::Util.error_string}"
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
# Clean up the IO objects associated with this waker
|
48
|
-
def cleanup
|
49
|
-
@sender_lock.synchronize { @sender.close rescue nil }
|
50
|
-
@receiver.close rescue nil
|
51
|
-
nil
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|