dcell 0.16.0 → 0.16.1

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.
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: