dcell 0.16.0 → 0.16.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9999eedc6fc4f7c1debdedd7e1018cc7cec0ed15
4
- data.tar.gz: 9aa0515298bd46ed83766af9ce7e8e5b96ba924a
3
+ metadata.gz: 5b7abd2458deb859bd4f406ee25e70e2a2acefb1
4
+ data.tar.gz: 37da6fd6c1177b19898b048eade8700fd965cd25
5
5
  SHA512:
6
- metadata.gz: 3af037c3b4a032cf8ded2086f538aa57f71168370e0a11f01c54a1eaa4b587d42782d7ff2a16a2a4f2c7af9ae7b82e3c8ee0a2148e3c2ad6ffb181d096598a16
7
- data.tar.gz: 866b10be6c0dea652423187a43df0eaa2794f79db7db9ee6de599d7f0e93db80db9bd012270d754a044fd9383cfbf50ec3a73d88d06d529ca78394976f2d3c95
6
+ metadata.gz: a37879c2a2962fcf4dbcb6b424357b1686e4689a4cefcb6627936d08c66ac998ccc0faac64d1c54d5eb26b3df8de7656fa5991677c7f9ad87493e2433b9a139b
7
+ data.tar.gz: 9566d8144677141bc87a371f3f8ba70641b78538e804ed79f3481417dd04e5b06aea6124980227e913789925ae5f5ea821258fd24dd25dfc5e2377f3bf5e2db9
data/.rspec CHANGED
@@ -1,4 +1,4 @@
1
1
  --color
2
2
  --format documentation
3
3
  --backtrace
4
- --default_path spec
4
+ --warnings
@@ -1,5 +1,11 @@
1
+ language: ruby
2
+
1
3
  before_install: sudo apt-get install libzmq3-dev
2
4
 
5
+ services:
6
+ - mongodb
7
+ - redis-server
8
+
3
9
  rvm:
4
10
  - 1.9.3
5
11
  - 2.0.0
@@ -15,5 +21,10 @@ matrix:
15
21
  - rvm: jruby-19mode
16
22
  - rvm: rbx-19mode # rbx seems to be losing exception messages o_O
17
23
 
18
- notifications:
19
- irc: "irc.freenode.org#celluloid"
24
+ branches:
25
+ only:
26
+ - master
27
+
28
+ env:
29
+ - DCELL_TEST_ADAPTER=redis
30
+ - DCELL_TEST_ADAPTER=mongodb
data/CHANGES.md CHANGED
@@ -1,3 +1,7 @@
1
+ 0.16.1 (2014-12-17)
2
+ -------------------
3
+ * Bugfixes for Celluloid 0.16 compatibility
4
+
1
5
  0.16.0 (2014-09-04)
2
6
  -------------------
3
7
  * Timeouts for cell discovery
data/Gemfile CHANGED
@@ -1,10 +1,10 @@
1
1
  source "http://rubygems.org"
2
2
 
3
- gem 'celluloid', github: 'celluloid/celluloid', branch: 'master'
4
- gem 'celluloid-io', github: 'celluloid/celluloid-io', branch: 'master'
5
- gem 'celluloid-zmq', github: 'celluloid/celluloid-zmq', branch: 'master'
3
+ gem 'celluloid', github: 'celluloid/celluloid', tag: 'v0.16.0'
4
+ gem 'celluloid-io', github: 'celluloid/celluloid-io', tag: 'v0.16.1'
5
+ gem 'celluloid-zmq', github: 'celluloid/celluloid-zmq', tag: 'v0.16.0'
6
6
  gem 'celluloid-redis', github: 'celluloid/celluloid-redis', branch: 'master'
7
- gem 'reel', github: 'celluloid/reel', branch: 'master'
7
+ gem 'reel', github: 'celluloid/reel', tag: 'v0.4.0'
8
8
 
9
9
  #gem 'ffi-rzmq', github: 'chuckremes/ffi-rzmq'
10
10
 
@@ -15,3 +15,4 @@ gem 'coveralls', require: false
15
15
  gemspec
16
16
 
17
17
  gem 'zk'
18
+ gem 'mongoid'
data/README.md CHANGED
@@ -2,7 +2,6 @@
2
2
  =====
3
3
  [![Gem Version](https://badge.fury.io/rb/dcell.png)](http://rubygems.org/gems/dcell)
4
4
  [![Build Status](https://secure.travis-ci.org/celluloid/dcell.png?branch=master)](http://travis-ci.org/celluloid/dcell)
5
- [![Dependency Status](https://gemnasium.com/celluloid/dcell.png)](https://gemnasium.com/celluloid/dcell)
6
5
  [![Code Climate](https://codeclimate.com/github/celluloid/dcell.png)](https://codeclimate.com/github/celluloid/dcell)
7
6
  [![Coverage Status](https://coveralls.io/repos/celluloid/dcell/badge.png?branch=master)](https://coveralls.io/r/celluloid/dcell)
8
7
 
@@ -17,12 +17,13 @@ Gem::Specification.new do |gem|
17
17
  gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
18
  gem.require_paths = ["lib"]
19
19
 
20
- gem.add_runtime_dependency "celluloid", ">= 0.16.0"
21
- gem.add_runtime_dependency "celluloid-zmq", ">= 0.16.0"
22
- gem.add_runtime_dependency "reel"
20
+ gem.add_runtime_dependency "celluloid", "~> 0.16.0"
21
+ gem.add_runtime_dependency "celluloid-zmq", "~> 0.16.0"
22
+ gem.add_runtime_dependency "reel", "~> 0.4.0"
23
+ gem.add_runtime_dependency "http", "~> 0.5.0"
23
24
  gem.add_runtime_dependency "celluloid-redis"
24
25
  gem.add_runtime_dependency "redis-namespace"
25
26
 
26
27
  gem.add_development_dependency "rake"
27
- gem.add_development_dependency "rspec"
28
+ gem.add_development_dependency "rspec", "~> 2.14.0"
28
29
  end
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  require 'dcell'
3
3
 
4
- DCell.start :id => "itchy", :addr => "tcp://127.0.0.1:9001"
4
+ DCell.start :id => "itchy"
5
5
 
6
6
  class Itchy
7
7
  include Celluloid
@@ -12,12 +12,13 @@ class Itchy
12
12
  end
13
13
 
14
14
  def fight
15
- @n = (@n % 6) + 1
16
- if @n <= 3
15
+ @n += 1
16
+ if @n % 6 == 0
17
17
  puts "Bite!"
18
18
  else
19
19
  puts "Fight!"
20
20
  end
21
+ @n
21
22
  end
22
23
  end
23
24
 
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env ruby
2
2
  require 'dcell'
3
3
 
4
- DCell.start :id => "scratchy", :addr => "tcp://127.0.0.1:9002"
4
+ DCell.start
5
5
  itchy_node = DCell::Node["itchy"]
6
6
 
7
7
  puts "Fighting itchy! (check itchy's output)"
8
8
 
9
- 6.times do
10
- itchy_node[:itchy].fight
9
+ 300.times do
10
+ puts itchy_node[:itchy].fight
11
11
  sleep 1
12
12
  end
@@ -1,6 +1,8 @@
1
1
  require 'celluloid'
2
2
  require 'reel'
3
3
  require 'celluloid/zmq'
4
+ require 'socket'
5
+ require 'securerandom'
4
6
 
5
7
  Celluloid::ZMQ.init
6
8
 
@@ -27,7 +29,6 @@ require 'dcell/celluloid_ext'
27
29
  module DCell
28
30
  class NotConfiguredError < RuntimeError; end # Not configured yet
29
31
 
30
- DEFAULT_PORT = 7777 # Default DCell port
31
32
  @config_lock = Mutex.new
32
33
 
33
34
  class << self
@@ -45,11 +46,11 @@ module DCell
45
46
  @config_lock.synchronize do
46
47
  @configuration = {
47
48
  'id' => generate_node_id,
48
- 'addr' => "tcp://127.0.0.1:#{DEFAULT_PORT}",
49
+ 'addr' => "tcp://127.0.0.1:*",
49
50
  'registry' => {'adapter' => 'redis', 'server' => 'localhost'}
50
51
  }.merge(options)
51
52
 
52
- @me = Node.new @configuration['id'], @configuration['addr']
53
+ @me = Node.new @configuration['id'], nil
53
54
 
54
55
  registry_adapter = @configuration['registry'][:adapter] || @configuration['registry']['adapter']
55
56
  raise ArgumentError, "no registry adapter given in config" unless registry_adapter
@@ -64,8 +65,7 @@ module DCell
64
65
 
65
66
  @registry = registry_class.new(@configuration['registry'])
66
67
 
67
- addr = @configuration['public'] || @configuration['addr']
68
- DCell::Directory.set @configuration['id'], addr
68
+ ObjectSpace.define_finalizer(me, proc {Directory.remove @configuration['id']})
69
69
  end
70
70
 
71
71
  me
@@ -81,9 +81,22 @@ module DCell
81
81
  def addr; @configuration['addr']; end
82
82
  alias_method :address, :addr
83
83
 
84
+ def addr=(addr)
85
+ @configuration['addr'] = addr
86
+ @me.update_server_address addr
87
+ end
88
+ alias_method :address=, :addr=
89
+
84
90
  # Attempt to generate a unique node ID for this machine
85
91
  def generate_node_id
86
- `hostname`.strip # Super creative I know
92
+ # a little bit more creative
93
+ if @registry.respond_to? :unique
94
+ @registry.unique
95
+ else
96
+ digest = Digest::SHA512.new
97
+ seed = Socket.gethostname + rand.to_s + Time.now.to_s + SecureRandom.hex
98
+ digest.update(seed).to_s
99
+ end
87
100
  end
88
101
 
89
102
  # Run the DCell application
@@ -1,6 +1,6 @@
1
1
  module DCell
2
2
  # Proxy object for actors that live on remote nodes
3
- class ActorProxy < Celluloid::ActorProxy; end
3
+ class CellProxy < Celluloid::CellProxy; end
4
4
 
5
5
  class ThreadHandleProxy
6
6
  def kill
@@ -23,7 +23,8 @@ module DCell
23
23
  @mailbox = mailbox
24
24
  @thread = ThreadHandleProxy.new
25
25
  @subject = SubjectProxy.new
26
+ @proxy = Celluloid::ActorProxy.new(@thread, @mailbox)
26
27
  end
27
- attr_reader :mailbox, :thread, :subject
28
+ attr_reader :mailbox, :thread, :subject, :proxy
28
29
  end
29
30
  end
@@ -9,7 +9,7 @@
9
9
  # DCell overlay network back to the node where the actor actually exists
10
10
 
11
11
  module Celluloid
12
- class ActorProxy
12
+ class CellProxy
13
13
  # Marshal uses respond_to? to determine if this object supports _dump so
14
14
  # unfortunately we have to monkeypatch in _dump support as the proxy
15
15
  # itself normally jacks respond_to? and proxies to the actor
@@ -33,11 +33,12 @@ module Celluloid
33
33
  case mailbox
34
34
  when ::DCell::MailboxProxy
35
35
  actor = ::DCell::Actor.new(mailbox)
36
- ::DCell::ActorProxy.new actor, mailbox
36
+ ::DCell::CellProxy.new actor.proxy, mailbox, actor.subject.class.to_s
37
37
  when ::Celluloid::Mailbox
38
38
  actor = find_actor(mailbox)
39
- ::Celluloid::ActorProxy.new(actor)
40
- else ::Kernel.raise "funny, I did not expect to see a #{mailbox.class} here"
39
+ ::Celluloid::CellProxy.new actor.proxy, mailbox, actor.behavior.subject.class.to_s
40
+ else
41
+ ::Kernel.raise "funny, I did not expect to see a #{mailbox.class} here"
41
42
  end
42
43
  end
43
44
 
@@ -19,5 +19,13 @@ module DCell
19
19
  def all
20
20
  DCell.registry.nodes
21
21
  end
22
+
23
+ def clear_all
24
+ DCell.registry.clear_all_nodes
25
+ end
26
+
27
+ def remove(node)
28
+ DCell.registry.remove_node node
29
+ end
22
30
  end
23
31
  end
@@ -6,7 +6,7 @@ require 'erb'
6
6
  module DCell
7
7
  # Web UI for DCell
8
8
  # TODO: rewrite this entire thing with less hax
9
- class Explorer < Reel::Server::HTTP
9
+ class Explorer < Reel::Server
10
10
  ASSET_ROOT = Pathname.new File.expand_path("../../../explorer", __FILE__)
11
11
 
12
12
  def initialize(host = "127.0.0.1", port = 7778)
@@ -18,6 +18,7 @@ module DCell
18
18
  Celluloid::Logger.info "Connected to #{id}"
19
19
  end
20
20
  state :partitioned do
21
+ @heartbeat.cancel
21
22
  Celluloid::Logger.warn "Communication with #{id} interrupted"
22
23
  end
23
24
 
@@ -32,7 +33,7 @@ module DCell
32
33
  include Enumerable
33
34
  extend Forwardable
34
35
 
35
- def_delegators "Celluloid::Actor[:node_manager]", :all, :each, :find, :[]
36
+ def_delegators "Celluloid::Actor[:node_manager]", :all, :each, :find, :[], :remove, :update
36
37
  def_delegators "Celluloid::Actor[:node_manager]", :heartbeat_rate, :heartbeat_timeout
37
38
  end
38
39
 
@@ -45,6 +46,15 @@ module DCell
45
46
  attach self
46
47
  end
47
48
 
49
+ def update_client_address( addr )
50
+ @addr = addr
51
+ send_heartbeat
52
+ end
53
+
54
+ def update_server_address(addr)
55
+ @addr = addr
56
+ end
57
+
48
58
  def shutdown
49
59
  transition :shutdown
50
60
  @socket.close if @socket
@@ -4,6 +4,8 @@ module DCell
4
4
  include Celluloid::ZMQ
5
5
  include Enumerable
6
6
 
7
+ trap_exit :node_died
8
+
7
9
  attr_reader :heartbeat_rate, :heartbeat_timeout
8
10
 
9
11
  def initialize
@@ -39,11 +41,39 @@ module DCell
39
41
  node = DCell.me
40
42
  else
41
43
  node = Node.new(id, addr)
44
+ self.link node
42
45
  end
43
46
 
44
47
  @nodes[id] ||= node
45
48
  @nodes[id]
46
49
  end
47
50
  alias_method :[], :find
51
+
52
+ def node_died(node, reason)
53
+ if reason.nil? # wtf?
54
+ # this wtf error seems to come from node socket writes
55
+ # when the socket is not reachable anymore
56
+ Celluloid::logger.debug "wtf?"
57
+ return
58
+ end
59
+ # Handle dead node???
60
+ end
61
+
62
+ def update(id)
63
+ addr = Directory[id]
64
+ return unless addr
65
+ if ( node = @nodes[id] ) and node.alive?
66
+ node.update_client_address( addr )
67
+ else
68
+ @nodes[id] = Node.new( id, addr )
69
+ end
70
+ end
71
+
72
+ def remove(id)
73
+ if @nodes[id]
74
+ @nodes[id].terminate if @nodes[id].alive?
75
+ @nodes.delete(id)
76
+ end
77
+ end
48
78
  end
49
79
  end
@@ -48,12 +48,16 @@ module DCell
48
48
  @global_registry = GlobalRegistry.new(cass, columnfamily)
49
49
  end
50
50
 
51
- def clear_nodes
52
- @node_registry.clear
51
+ def remove_node(node)
52
+ @node_registry.remove node
53
+ end
54
+
55
+ def clear_all_nodes
56
+ @node_registry.clear_all
53
57
  end
54
58
 
55
59
  def clear_globals
56
- @global_registry.clear
60
+ @global_registry.clear_all
57
61
  end
58
62
 
59
63
  class NodeRegistry
@@ -74,7 +78,11 @@ module DCell
74
78
  @cass.get(@cf, "nodes").keys
75
79
  end
76
80
 
77
- def clear
81
+ def remove(node)
82
+ @cass.remove @cf, "nodes", { node_id => node }
83
+ end
84
+
85
+ def clear_all
78
86
  @cass.del @cf, "nodes"
79
87
  end
80
88
  end
@@ -105,7 +113,7 @@ module DCell
105
113
  @cass.get(@cf, "globals").keys
106
114
  end
107
115
 
108
- def clear
116
+ def clear_all
109
117
  @cass.del @cf, "globals"
110
118
  end
111
119
  end
@@ -0,0 +1,85 @@
1
+ require 'mongoid'
2
+
3
+ module DCell
4
+ module Registry
5
+ class MongodbAdapter
6
+ # Setup connection to mongodb
7
+ # config: path to mongoid configuration file
8
+ # env: mongoid environment to use
9
+ def initialize(options)
10
+ if options[:config]
11
+ Mongoid.load! options[:config], options[:env]
12
+ elsif options[:db]
13
+ Mongoid.connect_to options[:db]
14
+ end
15
+ if options[:options]
16
+ Mongoid.options = options[:options]
17
+ end
18
+ end
19
+
20
+ class DCellNode
21
+ include Mongoid::Document
22
+
23
+ field :key, type: String
24
+ field :value, type: Hash
25
+ end
26
+
27
+ class DCellGlobal
28
+ include Mongoid::Document
29
+
30
+ field :key, type: String
31
+ field :value, type: Hash
32
+ end
33
+
34
+ class Proxy
35
+ class << self
36
+ def set(storage, key, value)
37
+ entry = storage.find_or_create_by(key: key)
38
+ entry.value = {'v' => value}
39
+ entry.save!
40
+ value
41
+ end
42
+
43
+ def get(storage, key)
44
+ first = storage.where(key: key).first
45
+ if first and first.value
46
+ return first.value['v']
47
+ end
48
+ nil
49
+ end
50
+
51
+ def all(storage)
52
+ keys = []
53
+ storage.each do |entry|
54
+ keys << entry.key
55
+ end
56
+ keys
57
+ end
58
+
59
+ def remove(storage, key)
60
+ begin
61
+ storage.where(key: key).delete
62
+ rescue
63
+ end
64
+ end
65
+
66
+ def clear_all(storage)
67
+ storage.delete_all
68
+ end
69
+ end
70
+ end
71
+
72
+ def get_node(node_id); Proxy.get(DCellNode, node_id) end
73
+ def set_node(node_id, addr); Proxy.set(DCellNode, node_id, addr) end
74
+ def nodes; Proxy.all(DCellNode) end
75
+ def remove_node(node_id); Proxy.remove(DCellNode, node_id) end
76
+ def clear_all_nodes; Proxy.clear_all(DCellNode) end
77
+
78
+ def get_global(key); Proxy.get(DCellGlobal, key) end
79
+ def set_global(key, value); Proxy.set(DCellGlobal, key, value) end
80
+ def global_keys; Proxy.all(DCellGlobal) end
81
+ def clear_globals; Proxy.clear_all(DCellGlobal) end
82
+
83
+ end
84
+ end
85
+ end
@@ -19,12 +19,16 @@ module DCell
19
19
  @global_registry = GlobalRegistry.new(@redis)
20
20
  end
21
21
 
22
- def clear_nodes
23
- @node_registry.clear
22
+ def remove_node(node)
23
+ @node_registry.remove node
24
+ end
25
+
26
+ def clear_all_nodes
27
+ @node_registry.clear_all
24
28
  end
25
29
 
26
30
  def clear_globals
27
- @global_registry.clear
31
+ @global_registry.clear_all
28
32
  end
29
33
 
30
34
  class NodeRegistry
@@ -44,7 +48,11 @@ module DCell
44
48
  @redis.hkeys 'nodes'
45
49
  end
46
50
 
47
- def clear
51
+ def remove(node)
52
+ @redis.hdel 'nodes', node
53
+ end
54
+
55
+ def clear_all
48
56
  @redis.del 'nodes'
49
57
  end
50
58
  end
@@ -74,7 +82,7 @@ module DCell
74
82
  @redis.hkeys 'globals'
75
83
  end
76
84
 
77
- def clear
85
+ def clear_all
78
86
  @redis.del 'globals'
79
87
  end
80
88
  end
@@ -46,15 +46,36 @@ module DCell
46
46
  @base_path = File.join(base_path, name.to_s)
47
47
  @ephemeral = ephemeral
48
48
  @zk.mkdir_p @base_path
49
+ @events = {}
50
+ end
51
+
52
+ def register(key)
53
+ path = "#{@base_path}/#{key}"
54
+ @events[path] ||= @zk.register(path) do |event|
55
+ key = event.path.match(/#{@base_path}\/(\w+)/)[1]
56
+ @events[event.path].unsubscribe
57
+ @events[event.path] = nil
58
+ if event.node_changed?
59
+ Celluloid::logger.debug "zk callback: node changed!"
60
+ Node.update(key)
61
+ end
62
+ if event.node_deleted?
63
+ Celluloid::logger.debug "zk callback: node deleted!"
64
+ Node.remove(key)
65
+ end
66
+
67
+ end
49
68
  end
50
69
 
51
70
  def get(key)
52
- result, _ = @zk.get("#{@base_path}/#{key}")
71
+ register(key)
72
+ result, _ = @zk.get("#{@base_path}/#{key}", watch: true)
53
73
  Marshal.load result
54
74
  rescue ZK::Exceptions::NoNode
55
75
  end
56
76
 
57
77
  def set(key, value)
78
+ register(key)
58
79
  path = "#{@base_path}/#{key}"
59
80
  string = Marshal.dump value
60
81
  @zk.set path, string
@@ -66,7 +87,21 @@ module DCell
66
87
  @zk.children @base_path
67
88
  end
68
89
 
69
- def clear
90
+ def remove(key)
91
+ keys.each do |key|
92
+ path = "#{@base_path}/#{key}"
93
+ @zk.delete path
94
+ end
95
+ end
96
+
97
+ def clear_all
98
+ # delete znodes so any registered
99
+ # callback is triggered
100
+ all.each do |key|
101
+ remove key
102
+ end
103
+ @events.values.compact.each(&:unsubscribe)
104
+ @events.clear
70
105
  @zk.rm_rf @base_path
71
106
  @zk.mkdir_p @base_path
72
107
  end
@@ -75,12 +110,13 @@ module DCell
75
110
  def get_node(node_id); @node_registry.get(node_id) end
76
111
  def set_node(node_id, addr); @node_registry.set(node_id, addr) end
77
112
  def nodes; @node_registry.all end
78
- def clear_nodes; @node_registry.clear end
113
+ def remove_node(node_id); @node_registry.clear(node_id) end
114
+ def clear_all_nodes; @node_registry.clear_all end
79
115
 
80
116
  def get_global(key); @global_registry.get(key) end
81
117
  def set_global(key, value); @global_registry.set(key, value) end
82
118
  def global_keys; @global_registry.all end
83
- def clear_globals; @global_registry.clear end
119
+ def clear_globals; @global_registry.clear_all end
84
120
 
85
121
  end
86
122
  end
@@ -10,11 +10,13 @@ module DCell
10
10
  # The gossip protocol is dependent on the node manager
11
11
  link Celluloid::Actor[:node_manager]
12
12
 
13
- @addr = DCell.addr
14
13
  @socket = PullSocket.new
15
14
 
16
15
  begin
17
- @socket.bind(@addr)
16
+ @socket.bind(DCell.addr)
17
+ real_addr = @socket.get(::ZMQ::LAST_ENDPOINT).strip
18
+ DCell::Directory.set DCell.id, real_addr
19
+ DCell.addr = real_addr
18
20
  rescue IOError
19
21
  @socket.close
20
22
  raise
@@ -1,3 +1,3 @@
1
1
  module DCell
2
- VERSION = "0.16.0"
2
+ VERSION = "0.16.1"
3
3
  end
@@ -1,9 +1,9 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe DCell::ActorProxy do
3
+ describe DCell::CellProxy do
4
4
  before :all do
5
- @node = DCell::Node['test_node']
6
- @node.id.should == 'test_node'
5
+ @node = DCell::Node[TEST_NODE[:id]]
6
+ @node.id.should == TEST_NODE[:id]
7
7
  @remote_actor = @node[:test_actor]
8
8
 
9
9
  class LocalActor
@@ -12,7 +12,7 @@ describe Celluloid, "extensions" do
12
12
  @marshal = WillKane.new
13
13
  end
14
14
 
15
- it "marshals Celluloid::ActorProxy objects" do
15
+ it "marshals Celluloid::CellProxy objects" do
16
16
  string = Marshal.dump(@marshal)
17
17
  Marshal.load(string).should be_alive
18
18
  end
@@ -5,4 +5,18 @@ describe DCell::Directory do
5
5
  DCell::Directory["foobar"] = "tcp://localhost:1870"
6
6
  DCell::Directory["foobar"].should == "tcp://localhost:1870"
7
7
  end
8
- end
8
+ it "presents all stored addresses" do
9
+ DCell::Directory["foo"] = "tcp://fooaddress"
10
+ DCell::Directory["bar"] = "tcp://baraddress"
11
+ DCell::Directory.all.should include("foo")
12
+ DCell::Directory.all.should include("bar")
13
+ end
14
+ it "clears node addresses" do
15
+ DCell::Directory["foo"] = "tcp://fooaddress"
16
+ DCell::Directory["foobar"].should == "tcp://localhost:1870"
17
+ ["foo", "foobar"].each do |node|
18
+ DCell::Directory.remove node
19
+ end
20
+ DCell::Directory["foobar"].should_not == "tcp://localhost:1870"
21
+ end
22
+ end
@@ -12,6 +12,6 @@ describe DCell::Explorer do
12
12
 
13
13
  it "reports the current node's status" do
14
14
  response = Net::HTTP.get URI(EXPLORER_BASE)
15
- response[%r{<h1><.*?> ([\w\.\-]+)<\/h1>}, 1].should == DCell.id
15
+ response[%r{<a href="/nodes/(.*?)">}, 1].should == DCell.id
16
16
  end
17
17
  end
@@ -10,7 +10,7 @@ describe DCell::Global do
10
10
  DCell::Global[:the_answer].should == 42
11
11
 
12
12
  # Double check the global value is available on all nodes
13
- node = DCell::Node['test_node']
13
+ node = DCell::Node[TEST_NODE[:id]]
14
14
  node[:test_actor].the_answer.should == 42
15
15
  end
16
16
 
@@ -2,8 +2,8 @@ require 'spec_helper'
2
2
 
3
3
  describe DCell::Node do
4
4
  before do
5
- @node = DCell::Node['test_node']
6
- @node.id.should == 'test_node'
5
+ @node = DCell::Node[TEST_NODE[:id]]
6
+ @node.id.should == TEST_NODE[:id]
7
7
  end
8
8
 
9
9
  it "finds all available nodes" do
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+ require 'dcell/registries/mongodb_adapter'
3
+
4
+ describe DCell::Registry::MongodbAdapter, :pending => TEST_ADEPTER != 'mongodb' && "no mongodb" do
5
+ subject { DCell::Registry::MongodbAdapter.new TEST_DB[:mongodb] }
6
+ it_behaves_like "a DCell registry"
7
+ end
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe DCell::Registry::RedisAdapter do
4
- subject { DCell::Registry::RedisAdapter.new :env => 'test' }
3
+ describe DCell::Registry::RedisAdapter, :pending => TEST_ADEPTER != 'redis' && "no redis" do
4
+ subject { DCell::Registry::RedisAdapter.new TEST_DB[:redis] }
5
5
  it_behaves_like "a DCell registry"
6
- end
6
+ end
@@ -1,7 +1,28 @@
1
1
  require 'spec_helper'
2
2
  require 'dcell/registries/zk_adapter'
3
3
 
4
- describe DCell::Registry::ZkAdapter, :pending => ENV["CI"] && "no zookeeper" do
5
- subject { DCell::Registry::ZkAdapter.new :server => 'localhost', :env => 'test' }
6
- it_behaves_like "a DCell registry"
4
+ describe DCell::Registry::ZkAdapter, :pending => TEST_ADEPTER != 'zk' && "no zookeeper" do
5
+ subject { DCell::Registry::ZkAdapter.new TEST_DB[:zk] }
6
+ it_behaves_like "a DCell registry" do
7
+ context "when one znode changes" do
8
+ it "updates a node" do
9
+ expect(DCell::Node).to receive(:update).with("foo")
10
+ subject.set_node("foo", "tcp://fooaddress")
11
+ # WARNING: only by calling get_node we renew the watcher
12
+ subject.get_node("foo").should eq("tcp://fooaddress")
13
+ subject.set_node("foo", "tcp://newaddress")
14
+ sleep 0.8 # takes some time to zookeeper watchers to take full effect
15
+ end
16
+ end
17
+ context "when one znode is deleted" do
18
+ it "deletes a node" do
19
+ expect(DCell::Node).to receive(:remove).with("foo")
20
+ subject.set_node("foo", "tcp://fooaddress")
21
+ # WARNING: only by calling get_node we renew the watcher
22
+ subject.get_node("foo").should eq("tcp://fooaddress")
23
+ subject.remove_node "foo"
24
+ sleep 0.8 # takes some time to zookeeper watchers to take full effect
25
+ end
26
+ end
27
+ end
7
28
  end
@@ -0,0 +1,10 @@
1
+ TEST_DB = {
2
+ :redis => {:server => 'localhost', :env => 'test'},
3
+ :zk => {:server => 'localhost', :env => 'test'},
4
+ :mongodb => {:db => 'dcell-test'},
5
+ }
6
+ TEST_NODE = {
7
+ :id => 'test_node',
8
+ :addr => "127.0.0.1",
9
+ :port => 21264,
10
+ }
@@ -0,0 +1,13 @@
1
+ TEST_ADEPTER = ENV['DCELL_TEST_ADAPTER'] || 'redis'
2
+
3
+ require "dcell/registries/#{TEST_ADEPTER}_adapter"
4
+
5
+ def test_db_options
6
+ options = {}
7
+ adapter = TEST_ADEPTER
8
+ if adapter
9
+ options[:registry] = {:adapter => adapter}
10
+ options[:registry].merge! TEST_DB[adapter.to_sym]
11
+ end
12
+ options
13
+ end
@@ -4,12 +4,19 @@ require 'coveralls'
4
4
  Coveralls.wear!
5
5
 
6
6
  require 'dcell'
7
+ Dir['./spec/options/*.rb'].map { |f| require f }
7
8
  Dir['./spec/support/*.rb'].map { |f| require f }
8
9
 
9
10
  RSpec.configure do |config|
10
11
  config.before(:suite) do
11
- DCell.setup
12
- DCell.run!
12
+ options = {}
13
+ options.merge! test_db_options
14
+ begin
15
+ DCell.start options
16
+ rescue => e
17
+ puts e
18
+ raise
19
+ end
13
20
 
14
21
  TestNode.start
15
22
  TestNode.wait_until_ready
@@ -2,8 +2,6 @@
2
2
  require 'rubygems'
3
3
 
4
4
  module TestNode
5
- PORT = 21264
6
-
7
5
  def self.start
8
6
  @pid = Process.spawn Gem.ruby, File.expand_path("../../test_node.rb", __FILE__)
9
7
  unless @pid
@@ -18,7 +16,7 @@ module TestNode
18
16
  socket = nil
19
17
  30.times do
20
18
  begin
21
- socket = TCPSocket.open("127.0.0.1", PORT)
19
+ socket = TCPSocket.open(TEST_NODE[:addr], TEST_NODE[:port])
22
20
  break if socket
23
21
  rescue Errno::ECONNREFUSED
24
22
  STDERR.print "."
@@ -1,7 +1,7 @@
1
1
  shared_context "a DCell registry" do
2
2
  context "node registry" do
3
3
  before :each do
4
- subject.clear_nodes
4
+ subject.clear_all_nodes
5
5
  end
6
6
 
7
7
  it "stores node addresses" do
@@ -6,7 +6,11 @@ require 'bundler'
6
6
  Bundler.setup
7
7
 
8
8
  require 'dcell'
9
- DCell.start :id => 'test_node', :addr => 'tcp://127.0.0.1:21264'
9
+ Dir['./spec/options/*.rb'].map { |f| require f }
10
+
11
+ options = {:id => TEST_NODE[:id], :addr => "tcp://#{TEST_NODE[:addr]}:#{TEST_NODE[:port]}"}
12
+ options.merge! test_db_options
13
+ DCell.start options
10
14
 
11
15
  class TestActor
12
16
  include Celluloid
@@ -31,4 +35,4 @@ class TestActor
31
35
  end
32
36
 
33
37
  TestActor.supervise_as :test_actor
34
- sleep
38
+ sleep
metadata CHANGED
@@ -1,57 +1,71 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dcell
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.16.0
4
+ version: 0.16.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tony Arcieri
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-09-05 00:00:00.000000000 Z
11
+ date: 2014-12-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: celluloid
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: 0.16.0
20
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
26
  version: 0.16.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: celluloid-zmq
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
33
  version: 0.16.0
34
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
40
  version: 0.16.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: reel
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">="
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '0'
47
+ version: 0.4.0
48
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: '0'
54
+ version: 0.4.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: http
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.5.0
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.5.0
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: celluloid-redis
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -98,16 +112,16 @@ dependencies:
98
112
  name: rspec
99
113
  requirement: !ruby/object:Gem::Requirement
100
114
  requirements:
101
- - - ">="
115
+ - - "~>"
102
116
  - !ruby/object:Gem::Version
103
- version: '0'
117
+ version: 2.14.0
104
118
  type: :development
105
119
  prerelease: false
106
120
  version_requirements: !ruby/object:Gem::Requirement
107
121
  requirements:
108
- - - ">="
122
+ - - "~>"
109
123
  - !ruby/object:Gem::Version
110
- version: '0'
124
+ version: 2.14.0
111
125
  description: DCell is an distributed object framework based on Celluloid built on
112
126
  0MQ and Zookeeper
113
127
  email:
@@ -155,6 +169,7 @@ files:
155
169
  - lib/dcell/node.rb
156
170
  - lib/dcell/node_manager.rb
157
171
  - lib/dcell/registries/cassandra_adapter.rb
172
+ - lib/dcell/registries/mongodb_adapter.rb
158
173
  - lib/dcell/registries/redis_adapter.rb
159
174
  - lib/dcell/registries/zk_adapter.rb
160
175
  - lib/dcell/responses.rb
@@ -170,8 +185,11 @@ files:
170
185
  - spec/dcell/explorer_spec.rb
171
186
  - spec/dcell/global_spec.rb
172
187
  - spec/dcell/node_spec.rb
188
+ - spec/dcell/registries/mongodb_adapter_spec.rb
173
189
  - spec/dcell/registries/redis_adapter_spec.rb
174
190
  - spec/dcell/registries/zk_adapter_spec.rb
191
+ - spec/options/01-options.rb
192
+ - spec/options/02-registry.rb
175
193
  - spec/spec_helper.rb
176
194
  - spec/support/helpers.rb
177
195
  - spec/support/registry_examples.rb
@@ -210,10 +228,12 @@ test_files:
210
228
  - spec/dcell/explorer_spec.rb
211
229
  - spec/dcell/global_spec.rb
212
230
  - spec/dcell/node_spec.rb
231
+ - spec/dcell/registries/mongodb_adapter_spec.rb
213
232
  - spec/dcell/registries/redis_adapter_spec.rb
214
233
  - spec/dcell/registries/zk_adapter_spec.rb
234
+ - spec/options/01-options.rb
235
+ - spec/options/02-registry.rb
215
236
  - spec/spec_helper.rb
216
237
  - spec/support/helpers.rb
217
238
  - spec/support/registry_examples.rb
218
239
  - spec/test_node.rb
219
- has_rdoc: