dcell 0.12.0.pre → 0.13.0.pre

Sign up to get free protection for your applications and to get access to all the features.
data/.travis.yml CHANGED
@@ -1,13 +1,14 @@
1
1
  rvm:
2
- - 1.9.2
3
2
  - 1.9.3
4
3
  - ruby-head
5
4
  - jruby-19mode
6
5
  - jruby-head
6
+ - rbx-19mode
7
7
 
8
- # https://github.com/rubinius/rubinius/issues/1628
9
- # - rbx-18mode
10
- # - rbx-19mode
8
+ matrix:
9
+ allow_failures:
10
+ # rbx seems to be losing exception messages o_O
11
+ - rvm: rbx-19mode
11
12
 
12
13
  notifications:
13
14
  irc: "irc.freenode.org#celluloid"
data/CHANGES.md CHANGED
@@ -1,5 +1,9 @@
1
- HEAD
2
- ----
1
+ 0.13.0.pre
2
+ ----------
3
+ * First semi-stable release in nearly forever! Yay!
4
+ * Rip out the unstable gossip system, replace the original Zookeeper and
5
+ Redis adapters.
6
+ * Compatibility fixes with newer versions of the Celluloid suite
3
7
  * Switch default port to 7890 (7777 is heavily used by other programs)
4
8
 
5
9
  0.10.0
data/Gemfile CHANGED
@@ -1,9 +1,11 @@
1
1
  source "http://rubygems.org"
2
2
 
3
- gem 'celluloid', :git => 'git://github.com/celluloid/celluloid'
4
- gem 'celluloid-io', :git => 'git://github.com/celluloid/celluloid-io'
5
- gem 'celluloid-zmq', :git => 'git://github.com/celluloid/celluloid-zmq'
6
- gem 'reel', :git => 'git://github.com/celluloid/reel'
3
+ #gem 'celluloid', :git => 'git://github.com/celluloid/celluloid'
4
+ #gem 'celluloid-io', :git => 'git://github.com/celluloid/celluloid-io'
5
+ #gem 'celluloid-zmq', :git => 'git://github.com/celluloid/celluloid-zmq'
6
+ #gem 'reel', :git => 'git://github.com/celluloid/reel'
7
+
8
+ #gem 'ffi-rzmq', :git => 'git://github.com/chuckremes/ffi-rzmq.git'
7
9
 
8
10
  gem 'jruby-openssl', :platform => :jruby
9
11
 
data/README.md CHANGED
@@ -2,6 +2,7 @@
2
2
  =====
3
3
  [![Build Status](https://secure.travis-ci.org/celluloid/dcell.png?branch=master)](http://travis-ci.org/celluloid/dcell)
4
4
  [![Dependency Status](https://gemnasium.com/celluloid/dcell.png)](https://gemnasium.com/celluloid/dcell)
5
+ [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/celluloid/dcell)
5
6
 
6
7
  > "Objects can message objects transparently that live on other machines
7
8
  > over the network, and you don't have to worry about the networking gunk,
@@ -73,51 +74,70 @@ Inside of your Ruby program do:
73
74
  Example
74
75
  -------
75
76
 
76
- Create a ruby script with the following contents:
77
+ Copy and paste this into `itchy.rb` (or run `bundle exec examples/itchy.rb`):
77
78
 
78
- # node1.rb
79
+ ```ruby
80
+ require 'dcell'
79
81
 
80
- require 'dcell'
82
+ DCell.start :id => "itchy", :addr => "tcp://127.0.0.1:9001"
81
83
 
82
- class Duck
83
- include Celluloid
84
+ class Itchy
85
+ include Celluloid
84
86
 
85
- def quack
86
- puts "Quack!"
87
- end
88
- end
87
+ def initialize
88
+ puts "Ready for mayhem!"
89
+ @n = 0
90
+ end
89
91
 
90
- Duck.supervise_as :duck_actor
92
+ def fight
93
+ @n = (@n % 6) + 1
94
+ if @n <= 3
95
+ puts "Bite!"
96
+ else
97
+ puts "Fight!"
98
+ end
99
+ end
100
+ end
91
101
 
92
- DCell.start :id => "node1", :addr => "tcp://127.0.0.1:4000"
102
+ Itchy.supervise_as :itchy
103
+ sleep
104
+ ```
93
105
 
94
- sleep
106
+ You can now launch itchy with:
95
107
 
96
- Now save and run the script via the command line and open a new shell. In there, create another ruby script:
108
+ ```
109
+ ruby itchy.rb
110
+ ```
97
111
 
98
- # node2.rb
112
+ Now copy and paste the following into `scratchy.rb` (also in examples)
99
113
 
100
- require 'dcell'
114
+ ```ruby
115
+ require 'dcell'
101
116
 
102
- DCell.start :id => "node2", :addr => "tcp://127.0.0.1:4001", :directory => {:id => "node1", :addr => "tcp://127.0.0.1:4000"}
117
+ DCell.start :id => "scratchy", :addr => "tcp://127.0.0.1:9002"
118
+ itchy_node = DCell::Node["itchy"]
103
119
 
104
- loop {
105
- node = DCell::Node["node1"]
106
- duck = node[:duck_actor]
107
- duck.quack
108
- sleep 3
109
- }
120
+ puts "Fighting itchy! (check itchy's output)"
110
121
 
111
- When you run the second script in the second shell, you will see the following output in your first shell:
122
+ 6.times do
123
+ itchy_node[:itchy].fight
124
+ sleep 1
125
+ end
126
+ ```
112
127
 
113
- $ ruby node1.rb
114
- I, [2012-08-30T20:00:00.759342 #26124] INFO -- : Connected to node1
115
- I, [2012-08-30T20:00:04.454006 #26124] INFO -- : Connected to node2
116
- Quack!
117
- Quack!
118
- Quack!
128
+ Now run scratchy side-by-side with itchy. You should see this on itchy:
119
129
 
120
- The loop in the second script looks up the node we registered in the first script, takes the registered Duck actor and calls the `quack` method every three seconds.
130
+ ```
131
+ $ bundle exec examples/itchy.rb
132
+ Ready for mayhem!
133
+ I, [2012-12-25T22:52:45.362355 #74272] INFO -- : Connected to scratchy
134
+ Bite!
135
+ Bite!
136
+ Bite!
137
+ Fight!
138
+ Fight!
139
+ Fight!
140
+ ```
121
141
 
122
142
  This is a basic example how individual DCell::Nodes have registered Celluloid actors which can be accessed remotely by other DCell::Nodes.
123
143
 
data/dcell.gemspec CHANGED
@@ -16,12 +16,11 @@ 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_runtime_dependency "celluloid", "~> 0.12.0"
20
- gem.add_runtime_dependency "celluloid-zmq", "~> 0.12.0"
19
+ gem.add_runtime_dependency "celluloid", ">= 0.13.0.pre"
20
+ gem.add_runtime_dependency "celluloid-zmq", ">= 0.13.0.pre"
21
21
  gem.add_runtime_dependency "reel"
22
22
  gem.add_runtime_dependency "redis"
23
23
  gem.add_runtime_dependency "redis-namespace"
24
- gem.add_runtime_dependency "moneta"
25
24
 
26
25
  gem.add_development_dependency "rake"
27
26
  gem.add_development_dependency "rspec"
data/examples/itchy.rb ADDED
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env ruby
2
+ require 'dcell'
3
+
4
+ DCell.start :id => "itchy", :addr => "tcp://127.0.0.1:9001"
5
+
6
+ class Itchy
7
+ include Celluloid
8
+
9
+ def initialize
10
+ puts "Ready for mayhem!"
11
+ @n = 0
12
+ end
13
+
14
+ def fight
15
+ @n = (@n % 6) + 1
16
+ if @n <= 3
17
+ puts "Bite!"
18
+ else
19
+ puts "Fight!"
20
+ end
21
+ end
22
+ end
23
+
24
+ Itchy.supervise_as :itchy
25
+ sleep
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+ require 'dcell'
3
+
4
+ DCell.start :id => "scratchy", :addr => "tcp://127.0.0.1:9002"
5
+ itchy_node = DCell::Node["itchy"]
6
+
7
+ puts "Fighting itchy! (check itchy's output)"
8
+
9
+ 6.times do
10
+ itchy_node[:itchy].fight
11
+ sleep 1
12
+ end
data/lib/dcell.rb CHANGED
@@ -19,7 +19,7 @@ require 'dcell/server'
19
19
  require 'dcell/info_service'
20
20
 
21
21
  require 'dcell/registries/redis_adapter'
22
- require 'dcell/registries/moneta_adapter'
22
+ #require 'dcell/registries/moneta_adapter'
23
23
 
24
24
  require 'dcell/celluloid_ext'
25
25
 
@@ -14,10 +14,10 @@ module Celluloid
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
16
16
  alias_method :__respond_to?, :respond_to?
17
- def respond_to?(meth)
17
+ def respond_to?(meth, check_private = false)
18
18
  return false if meth == :marshal_dump
19
19
  return true if meth == :_dump
20
- __respond_to? meth
20
+ __respond_to?(meth, check_private)
21
21
  end
22
22
 
23
23
  # Dump an actor proxy via its mailbox
@@ -43,7 +43,7 @@ module Celluloid
43
43
 
44
44
  def self.find_actor(mailbox)
45
45
  ::Thread.list.each do |t|
46
- if actor = t[:actor]
46
+ if actor = t[:celluloid_actor]
47
47
  return actor if actor.mailbox == mailbox
48
48
  end
49
49
  end
@@ -52,11 +52,15 @@ module Celluloid
52
52
  end
53
53
 
54
54
  class Mailbox
55
+ def address
56
+ "#{@address}@#{DCell.id}"
57
+ end
58
+
55
59
  # This custom dumper registers actors with the DCell registry so they can
56
60
  # be reached remotely.
57
61
  def _dump(level)
58
- mailbox_id = DCell::Router.register self
59
- "#{mailbox_id}@#{DCell.id}"
62
+ DCell::Router.register self
63
+ address
60
64
  end
61
65
 
62
66
  # Create a mailbox proxy object which routes messages over DCell's overlay
@@ -7,7 +7,6 @@ module DCell
7
7
  # Web UI for DCell
8
8
  # TODO: rewrite this entire thing with less hax
9
9
  class Explorer < Reel::Server
10
- include Celluloid::IO # FIXME: this should really be unnecessary
11
10
  ASSET_ROOT = Pathname.new File.expand_path("../../../explorer", __FILE__)
12
11
 
13
12
  def initialize(host = "127.0.0.1", port = 7778)
@@ -9,7 +9,7 @@ module DCell
9
9
  def <<(message)
10
10
  node = Node[@node_id]
11
11
  node = Node.new(@node_id, @node_addr) unless node
12
- node.send_message! Message::Relay.new(self, message)
12
+ node.async.send_message Message::Relay.new(self, message)
13
13
  end
14
14
 
15
15
  def _dump(level)
@@ -4,7 +4,10 @@ module DCell
4
4
  class MailboxProxy
5
5
  class InvalidNodeError < StandardError; end
6
6
 
7
- def initialize(node_id, mailbox_id)
7
+ def initialize(address)
8
+ mailbox_id, node_id = address.split("@")
9
+
10
+ # Create a proxy to the mailbox on the remote node
8
11
  raise ArgumentError, "no mailbox_id given" unless mailbox_id
9
12
 
10
13
  @node_id = node_id
@@ -25,7 +28,7 @@ module DCell
25
28
 
26
29
  # Send a message to the mailbox
27
30
  def <<(message)
28
- @node.send_message! Message::Relay.new(self, message)
31
+ @node.async.send_message Message::Relay.new(self, message)
29
32
  end
30
33
 
31
34
  # Is the remote mailbox still alive?
@@ -39,17 +42,11 @@ module DCell
39
42
  end
40
43
 
41
44
  # Loader for custom marshal format
42
- def self._load(string)
43
- mailbox_id, node_id = string.split("@")
44
-
45
- if DCell.id == node_id
46
- # If we're on the local node, find the real mailbox
47
- mailbox = DCell::Router.find mailbox_id
48
- raise "tried to unmarshal dead Celluloid::Mailbox: #{mailbox_id}" unless mailbox
45
+ def self._load(address)
46
+ if mailbox = DCell::Router.find(address)
49
47
  mailbox
50
48
  else
51
- # Create a proxy to the mailbox on the remote node
52
- DCell::MailboxProxy.new(node_id, mailbox_id)
49
+ DCell::MailboxProxy.new(address)
53
50
  end
54
51
  end
55
52
  end
data/lib/dcell/node.rb CHANGED
@@ -5,6 +5,8 @@ module DCell
5
5
  include Celluloid::FSM
6
6
  attr_reader :id, :addr
7
7
 
8
+ finalizer :shutdown
9
+
8
10
  # FSM
9
11
  default_state :disconnected
10
12
  state :shutdown
@@ -41,7 +43,7 @@ module DCell
41
43
  attach self
42
44
  end
43
45
 
44
- def finalize
46
+ def shutdown
45
47
  transition :shutdown
46
48
  @socket.close if @socket
47
49
  end
data/lib/dcell/router.rb CHANGED
@@ -4,42 +4,32 @@ module DCell
4
4
  # Route incoming messages to their recipient actors
5
5
  class Router
6
6
  @mutex = Mutex.new
7
- @addresses = {}
8
7
  @mailboxes = {}
9
8
 
10
9
  class << self
11
10
  # Enter a mailbox into the registry
12
11
  def register(mailbox)
13
- @mutex.lock
14
- begin
15
- address = @addresses[mailbox.object_id]
16
- unless address
17
- address = Celluloid.uuid
18
- @addresses[mailbox.object_id] = address
19
- end
20
-
12
+ @mutex.synchronize do
13
+ address = mailbox.address
21
14
  ref = @mailboxes[address]
22
15
  @mailboxes[address] = WeakRef.new(mailbox) unless ref && ref.weakref_alive?
23
16
 
24
17
  address
25
- ensure
26
- @mutex.unlock rescue nil
27
18
  end
28
19
  end
29
20
 
30
21
  # Find a mailbox by its address
31
22
  def find(mailbox_address)
32
- @mutex.lock
33
- begin
34
- ref = @mailboxes[mailbox_address]
35
- return unless ref
36
- ref.__getobj__
37
- rescue WeakRef::RefError
38
- # The referenced actor is dead, so prune the registry
39
- @mailboxes.delete mailbox_address
40
- nil
41
- ensure
42
- @mutex.unlock rescue nil
23
+ @mutex.synchronize do
24
+ begin
25
+ ref = @mailboxes[mailbox_address]
26
+ return unless ref
27
+ ref.__getobj__
28
+ rescue WeakRef::RefError
29
+ # The referenced actor is dead, so prune the registry
30
+ @mailboxes.delete mailbox_address
31
+ nil
32
+ end
43
33
  end
44
34
  end
45
35
 
data/lib/dcell/server.rb CHANGED
@@ -3,6 +3,8 @@ module DCell
3
3
  class Server
4
4
  include Celluloid::ZMQ
5
5
 
6
+ finalizer :close
7
+
6
8
  # Bind to the given 0MQ address (in URL form ala tcp://host:port)
7
9
  def initialize
8
10
  # The gossip protocol is dependent on the node manager
@@ -18,16 +20,15 @@ module DCell
18
20
  raise
19
21
  end
20
22
 
21
- run!
23
+ async.run
22
24
  end
23
25
 
24
26
  # Wait for incoming 0MQ messages
25
27
  def run
26
- while true; handle_message! @socket.read; end
28
+ while true; async.handle_message @socket.read; end
27
29
  end
28
30
 
29
- # Shut down the server
30
- def finalize
31
+ def close
31
32
  @socket.close if @socket
32
33
  end
33
34
 
@@ -36,14 +37,14 @@ module DCell
36
37
  begin
37
38
  message = decode_message message
38
39
  rescue InvalidMessageError => ex
39
- Celluloid::Logger.warn("couldn't decode message: #{ex.class}: #{ex}")
40
+ Logger.crash("couldn't decode message", ex)
40
41
  return
41
42
  end
42
43
 
43
44
  begin
44
45
  message.dispatch
45
46
  rescue => ex
46
- Celluloid::Logger.crash("DCell::Server: message dispatch failed", ex)
47
+ Logger.crash("DCell::Server: message dispatch failed", ex)
47
48
  end
48
49
  end
49
50
 
data/lib/dcell/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module DCell
2
- VERSION = "0.12.0.pre"
2
+ VERSION = "0.13.0.pre"
3
3
  end
@@ -58,7 +58,7 @@ describe DCell::ActorProxy do
58
58
 
59
59
  sleep 0.1 # hax to prevent a race between exit handling and the next call
60
60
  @local_actor.crash_reason.should be_a(RuntimeError)
61
- @local_actor.crash_reason.to_s.should == "the spec purposely crashed me :("
61
+ @local_actor.crash_reason.message.should == "the spec purposely crashed me :("
62
62
  end
63
63
  end
64
64
  end
@@ -1,6 +1,8 @@
1
1
  require 'spec_helper'
2
2
 
3
+ =begin
3
4
  describe DCell::Registry::MonetaAdapter do
4
5
  subject { DCell::Registry::MonetaAdapter.new :env => "test" }
5
6
  it_behaves_like "a DCell registry"
6
7
  end
8
+ =end
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.12.0.pre
4
+ version: 0.13.0.pre
5
5
  prerelease: 7
6
6
  platform: ruby
7
7
  authors:
@@ -9,40 +9,40 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-11-01 00:00:00.000000000 Z
12
+ date: 2013-02-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: celluloid
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
- - - ~>
19
+ - - ! '>='
20
20
  - !ruby/object:Gem::Version
21
- version: 0.12.0
21
+ version: 0.13.0.pre
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
25
25
  none: false
26
26
  requirements:
27
- - - ~>
27
+ - - ! '>='
28
28
  - !ruby/object:Gem::Version
29
- version: 0.12.0
29
+ version: 0.13.0.pre
30
30
  - !ruby/object:Gem::Dependency
31
31
  name: celluloid-zmq
32
32
  requirement: !ruby/object:Gem::Requirement
33
33
  none: false
34
34
  requirements:
35
- - - ~>
35
+ - - ! '>='
36
36
  - !ruby/object:Gem::Version
37
- version: 0.12.0
37
+ version: 0.13.0.pre
38
38
  type: :runtime
39
39
  prerelease: false
40
40
  version_requirements: !ruby/object:Gem::Requirement
41
41
  none: false
42
42
  requirements:
43
- - - ~>
43
+ - - ! '>='
44
44
  - !ruby/object:Gem::Version
45
- version: 0.12.0
45
+ version: 0.13.0.pre
46
46
  - !ruby/object:Gem::Dependency
47
47
  name: reel
48
48
  requirement: !ruby/object:Gem::Requirement
@@ -91,22 +91,6 @@ dependencies:
91
91
  - - ! '>='
92
92
  - !ruby/object:Gem::Version
93
93
  version: '0'
94
- - !ruby/object:Gem::Dependency
95
- name: moneta
96
- requirement: !ruby/object:Gem::Requirement
97
- none: false
98
- requirements:
99
- - - ! '>='
100
- - !ruby/object:Gem::Version
101
- version: '0'
102
- type: :runtime
103
- prerelease: false
104
- version_requirements: !ruby/object:Gem::Requirement
105
- none: false
106
- requirements:
107
- - - ! '>='
108
- - !ruby/object:Gem::Version
109
- version: '0'
110
94
  - !ruby/object:Gem::Dependency
111
95
  name: rake
112
96
  requirement: !ruby/object:Gem::Requirement
@@ -158,6 +142,8 @@ files:
158
142
  - benchmarks/messaging.rb
159
143
  - benchmarks/receiver.rb
160
144
  - dcell.gemspec
145
+ - examples/itchy.rb
146
+ - examples/scratchy.rb
161
147
  - explorer/css/bootstrap-responsive.css
162
148
  - explorer/css/bootstrap-responsive.min.css
163
149
  - explorer/css/bootstrap.css
@@ -221,6 +207,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
221
207
  - - ! '>='
222
208
  - !ruby/object:Gem::Version
223
209
  version: '0'
210
+ segments:
211
+ - 0
212
+ hash: -1249899003760905439
224
213
  required_rubygems_version: !ruby/object:Gem::Requirement
225
214
  none: false
226
215
  requirements:
@@ -229,7 +218,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
229
218
  version: 1.3.1
230
219
  requirements: []
231
220
  rubyforge_project:
232
- rubygems_version: 1.8.24
221
+ rubygems_version: 1.8.23
233
222
  signing_key:
234
223
  specification_version: 3
235
224
  summary: An asynchronous distributed object framework based on Celluloid