dcell 0.7.1 → 0.8.0

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.
@@ -0,0 +1,8 @@
1
+ rvm:
2
+ - 1.9.2
3
+ - 1.9.3
4
+ # - rbx crashing :(
5
+ - jruby
6
+ - ruby-head
7
+
8
+ env: "JRUBY_OPTS=--1.9"
data/CHANGES.md CHANGED
@@ -1,3 +1,8 @@
1
+ 0.8.0
2
+ -----
3
+ * Track calls in-flight with DCell::RPC and DCell::RPC::Manager
4
+ * Compatibility changes for Celluloid 0.8.0
5
+
1
6
  0.7.1
2
7
  -----
3
8
  * Bump version to match Celluloid
data/Rakefile CHANGED
@@ -1,4 +1,4 @@
1
1
  require "bundler/gem_tasks"
2
2
  Dir["tasks/**/*.task"].each { |task| load task }
3
3
 
4
- task :default => :spec
4
+ task :default => :spec
@@ -1,3 +1,7 @@
1
+ 0.8.0
2
+ -----
3
+ * Update to match internals of celluloid-io
4
+
1
5
  0.7.0
2
6
  -----
3
7
  * Use celluloid-io gem
@@ -11,8 +11,8 @@ Gem::Specification.new do |gem|
11
11
  gem.name = "celluloid-zmq"
12
12
  gem.version = Celluloid::ZMQ::VERSION
13
13
 
14
- gem.add_dependency "celluloid", ">= 0.7.0"
15
- gem.add_dependency "celluloid-io", ">= 0.7.0"
14
+ gem.add_dependency "celluloid", "~> 0.8.0"
15
+ gem.add_dependency "celluloid-io", "~> 0.8.0"
16
16
  gem.add_dependency "ffi"
17
17
  gem.add_dependency "ffi-rzmq"
18
18
 
@@ -24,15 +24,10 @@ module Celluloid
24
24
  end
25
25
  end
26
26
 
27
- # Wait for the given IO object to become readable
28
- def wait_readable(socket)
29
- # Law of demeter be damned!
30
- current_actor.mailbox.reactor.wait_readable(socket)
31
- end
27
+ extend Forwardable
32
28
 
33
- # Wait for the given IO object to become writeable
34
- def wait_writeable(socket)
35
- current_actor.mailbox.reactor.wait_writeable(socket)
36
- end
29
+ # Wait for the given IO object to become readable/writeable
30
+ def_delegators 'current_actor.mailbox.reactor',
31
+ :wait_readable, :wait_writeable
37
32
  end
38
33
  end
@@ -6,8 +6,7 @@ module Celluloid
6
6
  # More APIs and less monkeypatching would be useful here
7
7
  @messages = []
8
8
  @lock = Mutex.new
9
- @waker = Waker.new
10
- @reactor = Reactor.new(@waker)
9
+ @reactor = Reactor.new
11
10
  end
12
11
  end
13
12
  end
@@ -3,8 +3,13 @@ module Celluloid
3
3
  # React to incoming 0MQ and Celluloid events. This is kinda sorta supposed
4
4
  # to resemble the Reactor design pattern.
5
5
  class Reactor
6
- def initialize(waker)
7
- @waker = waker
6
+ extend Forwardable
7
+
8
+ def_delegator :@waker, :signal, :wakeup
9
+ def_delegator :@waker, :cleanup, :shutdown
10
+
11
+ def initialize
12
+ @waker = Waker.new
8
13
  @poller = ::ZMQ::Poller.new
9
14
  @readers = {}
10
15
  @writers = {}
@@ -30,13 +35,12 @@ module Celluloid
30
35
  if set.has_key? socket
31
36
  raise ArgumentError, "another method is already waiting on #{socket.inspect}"
32
37
  else
33
- set[socket] = Fiber.current
38
+ set[socket] = Task.current
34
39
  end
35
40
 
36
41
  @poller.register socket, type
37
- Fiber.yield
38
42
 
39
- @poller.deregister socket, type
43
+ Task.suspend :zmqwait
40
44
  socket
41
45
  end
42
46
 
@@ -57,16 +61,28 @@ module Celluloid
57
61
 
58
62
  @poller.readables.each do |sock|
59
63
  if sock == @waker.socket
60
- yield
64
+ @waker.wait
61
65
  else
62
- fiber = @readers.delete sock
63
- fiber.resume if fiber
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
64
74
  end
65
75
  end
66
76
 
67
77
  @poller.writables.each do |sock|
68
- fiber = @writers.delete sock
69
- fiber.resume if fiber
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
70
86
  end
71
87
  end
72
88
  end
@@ -1,5 +1,5 @@
1
1
  module Celluloid
2
2
  module ZMQ
3
- VERSION = "0.7.1"
3
+ VERSION = "0.8.0"
4
4
  end
5
5
  end
@@ -1,6 +1,7 @@
1
1
  module Celluloid
2
2
  module ZMQ
3
- class DeadWakerError < Celluloid::IO::DeadWakerError; end # You can't wake the dead
3
+ # You can't wake the dead
4
+ DeadWakerError = Class.new IOError
4
5
 
5
6
  # Wakes up sleepy threads so that they can check their mailbox
6
7
  # Works like a ConditionVariable, except it's implemented as a ZMQ socket
@@ -16,12 +16,12 @@ 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_dependency "celluloid", ">= 0.7.0"
20
- gem.add_dependency "celluloid-zmq", ">= 0.7.0"
19
+ gem.add_dependency "celluloid", "~> 0.8.0"
20
+ gem.add_dependency "celluloid-zmq", "~> 0.8.0"
21
21
  gem.add_dependency "redis"
22
22
  gem.add_dependency "redis-namespace"
23
23
 
24
24
  gem.add_development_dependency "rake"
25
- gem.add_development_dependency "rspec", ">= 2.7.0"
25
+ gem.add_development_dependency "rspec", "~> 2.7.0"
26
26
  #gem.add_development_dependency "zk"
27
27
  end
@@ -10,16 +10,17 @@ require 'dcell/node'
10
10
  require 'dcell/global'
11
11
  require 'dcell/responses'
12
12
  require 'dcell/router'
13
+ require 'dcell/rpc'
13
14
  require 'dcell/server'
14
15
 
15
16
  require 'dcell/registries/redis_adapter'
16
- require 'dcell/application'
17
17
  require 'dcell/celluloid_ext'
18
18
 
19
19
  # Distributed Celluloid
20
20
  module DCell
21
21
  DEFAULT_PORT = 7777 # Default DCell port
22
22
  ZMQ_POOL_SIZE = 1 # DCell uses a fixed-size 0MQ thread pool
23
+
23
24
  @zmq_context = Celluloid::ZMQ.context = ::ZMQ::Context.new(ZMQ_POOL_SIZE)
24
25
  @config_lock = Mutex.new
25
26
 
@@ -78,12 +79,12 @@ module DCell
78
79
 
79
80
  # Run the DCell application
80
81
  def run
81
- DCell::Application.run
82
+ DCell::Group.run
82
83
  end
83
84
 
84
85
  # Run the DCell application in the background
85
86
  def run!
86
- DCell::Application.run!
87
+ DCell::Group.run!
87
88
  end
88
89
 
89
90
  # Start combines setup and run! into a single step
@@ -92,4 +93,9 @@ module DCell
92
93
  run!
93
94
  end
94
95
  end
96
+
97
+ # DCell's actor dependencies
98
+ class Group < Celluloid::Group
99
+ supervise Server, :as => :dcell_server
100
+ end
95
101
  end
@@ -54,4 +54,16 @@ module Celluloid
54
54
  DCell::MailboxProxy._load(string)
55
55
  end
56
56
  end
57
+
58
+ class SyncCall
59
+ def _dump(level)
60
+ rpc_id = DCell::RPC::Manager.register self
61
+ payload = Marshal.dump([@caller,@method,@arguments,@block])
62
+ "#{rpc_id.to_s(16)}@#{DCell.id}:#{payload}"
63
+ end
64
+
65
+ def self._load(string)
66
+ DCell::RPC._load(string)
67
+ end
68
+ end
57
69
  end
@@ -1,6 +1,7 @@
1
1
  module DCell
2
2
  # A node in a DCell cluster
3
3
  class Node
4
+ include Celluloid
4
5
  include Celluloid::FSM
5
6
  attr_reader :id, :addr
6
7
 
@@ -69,6 +70,9 @@ module DCell
69
70
  @id, @addr = id, addr
70
71
  @socket = nil
71
72
  @heartbeat = nil
73
+
74
+ # Total hax to accommodate the new Celluloid::FSM API
75
+ attach self
72
76
  end
73
77
 
74
78
  def finalize
@@ -59,7 +59,7 @@ module DCell
59
59
 
60
60
  def get(key)
61
61
  string = @redis.hget 'globals', key.to_s
62
- Marshal.load string
62
+ Marshal.load string if string
63
63
  end
64
64
 
65
65
  # Set a global value
@@ -0,0 +1,66 @@
1
+ require 'weakref'
2
+
3
+ module DCell
4
+ EPOCH = Time.new(2012, 1, 1, 0, 0, 0, "+00:00") # All things begin in 2012
5
+
6
+ class RPC < Celluloid::SyncCall
7
+ def initialize(id, caller, method, arguments, block)
8
+ @id, @caller, @method, @arguments, @block = id, caller, method, arguments, block
9
+ end
10
+
11
+ # Custom marshaller for compatibility with Celluloid::Mailbox marshalling
12
+ def _dump(level)
13
+ payload = Marshal.dump [@caller, @method, @arguments, @block]
14
+ "#{@id}:#{payload}"
15
+ end
16
+
17
+ # Loader for custom marshal format
18
+ def self._load(string)
19
+ id = string.slice!(0, string.index(":") + 1)
20
+ match = id.match(/^([0-9a-fA-F]+)@(.+?):$/)
21
+ raise ArgumentError, "couldn't parse call ID" unless match
22
+
23
+ call_id, node_id = match[1], match[2]
24
+
25
+ if DCell.id == node_id
26
+ Manager.claim Integer("0x#{call_id}")
27
+ else
28
+ caller, method, arguments, block = Marshal.load(string)
29
+ RPC.new("#{call_id}@#{node_id}", caller, method, arguments, block)
30
+ end
31
+ end
32
+
33
+ # Tracks calls-in-flight
34
+ class Manager
35
+ @mutex = Mutex.new
36
+ @ids = {}
37
+ @calls = {}
38
+ @serial = Integer(Time.now - EPOCH) * 0x100000
39
+
40
+ def self.register(call)
41
+ @mutex.lock
42
+ call_id = @ids[call.object_id]
43
+ unless call_id
44
+ call_id = @serial
45
+ @serial += 1
46
+ @ids[call.object_id] = call_id
47
+ end
48
+
49
+ @calls[call_id] = WeakRef.new(call)
50
+ call_id
51
+ ensure
52
+ @mutex.unlock
53
+ end
54
+
55
+ def self.claim(call_id)
56
+ @mutex.lock
57
+ ref = @calls.delete(call_id)
58
+ ref.__getobj__ if ref
59
+ rescue WeakRef::RefError
60
+ # Nothing to see here, folks
61
+ ensure
62
+ @mutex.unlock
63
+ end
64
+ end
65
+ end
66
+ end
@@ -1,3 +1,3 @@
1
1
  module DCell
2
- VERSION = "0.7.1"
2
+ VERSION = "0.8.0"
3
3
  end
@@ -1,6 +1,10 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe DCell::Global do
4
+ it "can handle unexisting keys" do
5
+ expect { DCell::Global[:unexisting] }.to_not raise_exception
6
+ end
7
+
4
8
  it "stores values" do
5
9
  DCell::Global[:the_answer] = 42
6
10
  DCell::Global[:the_answer].should == 42
@@ -25,9 +25,9 @@ class TestActor
25
25
  end
26
26
  end
27
27
 
28
- class TestApplication < Celluloid::Application
29
- supervise DCell::Application
28
+ class TestGroup < Celluloid::Group
29
+ supervise DCell::Group
30
30
  supervise TestActor, :as => :test_actor
31
31
  end
32
32
 
33
- TestApplication.run
33
+ TestGroup.run
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.7.1
4
+ version: 0.8.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,33 +9,33 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-01-06 00:00:00.000000000 Z
12
+ date: 2012-01-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: celluloid
16
- requirement: &70286435226960 !ruby/object:Gem::Requirement
16
+ requirement: &70247796045460 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
- - - ! '>='
19
+ - - ~>
20
20
  - !ruby/object:Gem::Version
21
- version: 0.7.0
21
+ version: 0.8.0
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70286435226960
24
+ version_requirements: *70247796045460
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: celluloid-zmq
27
- requirement: &70286435226380 !ruby/object:Gem::Requirement
27
+ requirement: &70247796044740 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
- - - ! '>='
30
+ - - ~>
31
31
  - !ruby/object:Gem::Version
32
- version: 0.7.0
32
+ version: 0.8.0
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70286435226380
35
+ version_requirements: *70247796044740
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: redis
38
- requirement: &70286435225840 !ruby/object:Gem::Requirement
38
+ requirement: &70247796043700 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70286435225840
46
+ version_requirements: *70247796043700
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: redis-namespace
49
- requirement: &70286435225200 !ruby/object:Gem::Requirement
49
+ requirement: &70247796043240 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *70286435225200
57
+ version_requirements: *70247796043240
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: rake
60
- requirement: &70286435224680 !ruby/object:Gem::Requirement
60
+ requirement: &70247796042780 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,18 +65,18 @@ dependencies:
65
65
  version: '0'
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *70286435224680
68
+ version_requirements: *70247796042780
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rspec
71
- requirement: &70286435223880 !ruby/object:Gem::Requirement
71
+ requirement: &70247796042200 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
- - - ! '>='
74
+ - - ~>
75
75
  - !ruby/object:Gem::Version
76
76
  version: 2.7.0
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *70286435223880
79
+ version_requirements: *70247796042200
80
80
  description: DCell is an distributed object framework based on Celluloid built on
81
81
  0MQ and Zookeeper
82
82
  email:
@@ -87,6 +87,7 @@ extra_rdoc_files: []
87
87
  files:
88
88
  - .gitignore
89
89
  - .rspec
90
+ - .travis.yml
90
91
  - CHANGES.md
91
92
  - Gemfile
92
93
  - LICENSE.txt
@@ -112,7 +113,6 @@ files:
112
113
  - dcell.gemspec
113
114
  - lib/dcell.rb
114
115
  - lib/dcell/actor_proxy.rb
115
- - lib/dcell/application.rb
116
116
  - lib/dcell/celluloid_ext.rb
117
117
  - lib/dcell/directory.rb
118
118
  - lib/dcell/global.rb
@@ -123,6 +123,7 @@ files:
123
123
  - lib/dcell/registries/zk_adapter.rb
124
124
  - lib/dcell/responses.rb
125
125
  - lib/dcell/router.rb
126
+ - lib/dcell/rpc.rb
126
127
  - lib/dcell/rspec.rb
127
128
  - lib/dcell/server.rb
128
129
  - lib/dcell/version.rb
@@ -1,6 +0,0 @@
1
- module DCell
2
- # Actors which run when DCell is active
3
- class Application < Celluloid::Application
4
- supervise Server, :as => :dcell_server
5
- end
6
- end