Skip to content

Commit

Permalink
put node actors in the directory
Browse files Browse the repository at this point in the history
  • Loading branch information
niamster committed Feb 9, 2015
1 parent c878ce9 commit 44d337e
Show file tree
Hide file tree
Showing 9 changed files with 111 additions and 35 deletions.
7 changes: 4 additions & 3 deletions examples/itchy.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
#!/usr/bin/env ruby
require 'dcell'
require 'dcell/registries/redis_adapter'

require 'dcell/registries/redis_adapter'
registry = DCell::Registry::RedisAdapter.new :server => 'localhost'
DCell.start :id => "itchy", :registry => registry

class Itchy
include Celluloid
Expand All @@ -23,6 +22,8 @@ def fight
@n
end
end

Itchy.supervise_as :itchy

DCell.start :id => "itchy", :registry => registry

sleep
15 changes: 14 additions & 1 deletion lib/dcell.rb
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,17 @@ def local_actors
@actors.to_a
end

# Returns actors from multiple nodes
def find(actor)
actors = Array.new
Directory.each do |node|
next unless node.actors.include? actor
actors << Node[node.id][actor]
end
actors
end
alias_method :[], :find

def config(option)
unless @configuration
Logger.warn "DCell unconfigured, can't get #{option}"
Expand All @@ -106,7 +117,7 @@ def addr
# Updates server address of the node
def addr=(addr)
@configuration['addr'] = addr
Directory.set @configuration['id'], addr
Directory[id].address = addr
@me.update_server_address addr
end
alias_method :address=, :addr=
Expand Down Expand Up @@ -135,6 +146,7 @@ def generate_node_id

# Run the DCell application in the background
def run!
Directory[id].actors = local_actors
DCell::SupervisionGroup.run!
end

Expand All @@ -144,6 +156,7 @@ def start(options = {})
run!
end
end

extend ClassMethods

# DCell's actor dependencies
Expand Down
67 changes: 55 additions & 12 deletions lib/dcell/directory.rb
Original file line number Diff line number Diff line change
@@ -1,31 +1,74 @@
module DCell
# Node metadata helper
class DirectoryMeta
attr_reader :id, :address, :actors

def initialize(id, meta)
@id = id
if meta
@address = meta[:address]
@actors = meta[:actors].map {|a| a.to_sym}
else
@actors = Array.new
end
end

def address=(address)
@address = address
DCell.registry.set_node @id, self
end

def actors=(actors)
@actors = actors.map {|a| a.to_sym}
DCell.registry.set_node @id, self
end

def add_actor(actor)
@actors << actor.to_sym
DCell.registry.set_node @id, self
end
alias_method :<<, :add_actor

def to_msgpack(pk=nil)
{
:address => @address,
:actors => @actors,
}.to_msgpack(pk)
end
end

# Directory of nodes connected to the DCell cluster
module Directory
include Enumerable
extend self

# Get the URL for a particular Node ID
def get(node_id)
DCell.registry.get_node node_id
# Get the address for a particular Node ID
def find(id)
meta = DCell.registry.get_node(id)
DirectoryMeta.new(id, meta)
end
alias_method :[], :get

# Set the address of a particular Node ID
def set(node_id, addr)
DCell.registry.set_node node_id, addr
end
alias_method :[]=, :set
alias_method :[], :find

# List all of the node IDs in the directory
def all
DCell.registry.nodes
end

# Iterates over all registered nodes
def each
DCell.registry.nodes.each do |id|
yield Directory[id]
end
end

# Remove all nodes in the directory
def clear_all
DCell.registry.clear_all_nodes
end

def remove(node)
DCell.registry.remove_node node
# Remove information for a give Node ID
def remove(id)
DCell.registry.remove_node id
end
end
end
3 changes: 1 addition & 2 deletions lib/dcell/node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ def kill_actors
end

def move_node
addr = Directory[id]
addr = Directory[id].address
kill_actors
if addr
update_client_address addr
Expand Down Expand Up @@ -168,7 +168,6 @@ def find(name)
return nil if mailbox.kind_of? NilClass
actor = DCell::ActorProxy.new self, mailbox, methods
add_actor actor
actor
end
alias_method :[], :find

Expand Down
2 changes: 1 addition & 1 deletion lib/dcell/node_manager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class << self
# Finds a node by its node ID and adds to the cache
def find(id)
return DCell.me if id == DCell.id
addr = Directory[id]
addr = Directory[id].address
return nil unless addr
loop do
begin
Expand Down
5 changes: 5 additions & 0 deletions spec/dcell/dcell_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,9 @@
DCellMock.setup :registry => registry
DCellMock.id.should_not == nil
end

it "finds remote actors" do
actor = DCell[:test_actor].first
actor.value.should == 42
end
end
28 changes: 21 additions & 7 deletions spec/dcell/directory_spec.rb
Original file line number Diff line number Diff line change
@@ -1,20 +1,34 @@
describe DCell::Directory do
it "stores node addresses" do
DCell::Directory["foobar"] = "tcp://localhost:1870"
DCell::Directory["foobar"].should == "tcp://localhost:1870"
DCell::Directory["foobar"].address = "tcp://localhost:1870"
DCell::Directory["foobar"].address.should == "tcp://localhost:1870"
end

it "stores node actors" do
DCell::Directory["foobar"].actors = []
DCell::Directory["foobar"] << :one
DCell::Directory["foobar"] << :two
DCell::Directory["foobar"].actors.should == [:one, :two]

DCell::Directory["foobar"].actors = [:three, :four]
DCell::Directory["foobar"].actors.should == [:three, :four]
end

it "presents all stored addresses" do
DCell::Directory["foo"] = "tcp://fooaddress"
DCell::Directory["bar"] = "tcp://baraddress"
DCell::Directory["foo"].address = "tcp://fooaddress"
DCell::Directory["bar"].address = "tcp://baraddress"
DCell::Directory.all.should include("foo")
DCell::Directory.all.should include("bar")
DCell::Directory.map{|node| node.id}.should include("foo")
DCell::Directory.map{|node| node.id}.should include("bar")
end

it "clears node addresses" do
DCell::Directory["foo"] = "tcp://fooaddress"
DCell::Directory["foobar"].should == "tcp://localhost:1870"
DCell::Directory["foo"].address = "tcp://fooaddress"
DCell::Directory["foobar"].address.should == "tcp://localhost:1870"
["foo", "foobar"].each do |node|
DCell::Directory.remove node
end
DCell::Directory["foobar"].should_not == "tcp://localhost:1870"
DCell::Directory["foobar"].address.should_not == "tcp://localhost:1870"
end
end
13 changes: 7 additions & 6 deletions spec/support/registry_examples.rb
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
shared_context "a DCell registry" do
context "node registry" do
address = "tcp://localhost:7777"
meta = {address: address, actors: ["one", "two", "three"]}

before :each do
subject.clear_all_nodes
end

it "stores node addresses" do
address = "tcp://localhost:7777"

subject.set_node("foobar", address)
subject.get_node("foobar").should == address
it "stores node address and other properties" do
subject.set_node("foobar", meta)
subject.get_node("foobar").should == meta
end

it "stores the IDs of all nodes" do
subject.set_node("foobar", "tcp://localhost:7777")
subject.set_node("foobar", meta)
subject.nodes.should include "foobar"
end
end
Expand Down
6 changes: 3 additions & 3 deletions spec/test_node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,13 @@ def suicide(delay)
'Bazinga'
end
end
TestActor.supervise_as :test_actor

Celluloid.logger = nil
Celluloid.shutdown_timeout = 1

options = {:id => TEST_NODE[:id], :addr => "tcp://#{TEST_NODE[:addr]}:#{TEST_NODE[:port]}"}
options.merge! test_options
DCell.setup options
TestActor.supervise_as :test_actor
DCell.run!

DCell.start options
sleep

0 comments on commit 44d337e

Please sign in to comment.