celluloid-zmq 0.0.1 → 0.0.2

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.
data/CHANGES.md ADDED
@@ -0,0 +1,7 @@
1
+ 0.0.2
2
+ -----
3
+ * Pure blocking 0MQ reactor using a ZMQ::PAIR socket as the waker
4
+
5
+ 0.0.1
6
+ -----
7
+ * Initial release
@@ -19,7 +19,7 @@ Gem::Specification.new do |gem|
19
19
 
20
20
  gem.add_development_dependency "rake"
21
21
  gem.add_development_dependency "rspec", ">= 2.7.0"
22
-
22
+
23
23
  # Files
24
24
  ignores = File.read(".gitignore").split(/\r?\n/).reject{ |f| f =~ /^(#.+|\s*)$/ }.map {|f| Dir[f] }.flatten
25
25
  gem.files = (Dir['**/*','.gitignore'] - ignores).reject {|f| !File.file?(f) }
data/lib/celluloid/zmq.rb CHANGED
@@ -4,13 +4,24 @@ require 'celluloid'
4
4
  require 'celluloid/zmq/mailbox'
5
5
  require 'celluloid/zmq/reactor'
6
6
  require 'celluloid/zmq/version'
7
+ require 'celluloid/zmq/waker'
7
8
 
8
9
  module Celluloid
9
10
  # Actors which run alongside 0MQ sockets
10
11
  module ZMQ
11
- def self.included(klass)
12
- klass.send :include, ::Celluloid
13
- klass.use_mailbox Celluloid::ZMQ::Mailbox
12
+ class << self
13
+ attr_writer :context
14
+
15
+ # Included hook to pull in Celluloid
16
+ def included(klass)
17
+ klass.send :include, ::Celluloid
18
+ klass.use_mailbox Celluloid::ZMQ::Mailbox
19
+ end
20
+
21
+ # Obtain a 0MQ context (or lazily initialize it)
22
+ def context
23
+ @context ||= ::ZMQ::Context.new(1)
24
+ end
14
25
  end
15
26
 
16
27
  # Wait for the given IO object to become readable
@@ -5,9 +5,9 @@ module Celluloid
5
5
  def initialize
6
6
  @messages = []
7
7
  @lock = Mutex.new
8
- @waker = Celluloid::IO::Waker.new
8
+ @waker = Celluloid::ZMQ::Waker.new
9
9
  @reactor = Reactor.new(@waker)
10
10
  end
11
11
  end
12
12
  end
13
- end
13
+ end
@@ -9,14 +9,10 @@ module Celluloid
9
9
  @readers = {}
10
10
  @writers = {}
11
11
 
12
- # FIXME: The way things are presently implemented is super ghetto
13
- # The ZMQ::Poller should be able to wait on the waker somehow
14
- # but I can't get it to work :(
15
- #result = @poller.register(nil, ::ZMQ::POLLIN, @waker.io.fileno)
16
- #
17
- #unless ::ZMQ::Util.resultcode_ok?(result)
18
- # raise "couldn't register waker with 0MQ poller"
19
- #end
12
+ rc = @poller.register @waker.socket, ::ZMQ::POLLIN
13
+ unless ::ZMQ::Util.resultcode_ok? rc
14
+ raise "0MQ poll error: #{::ZMQ::Util.error_string}"
15
+ end
20
16
  end
21
17
 
22
18
  # Wait for the given ZMQ socket to become readable
@@ -47,26 +43,25 @@ module Celluloid
47
43
  # Run the reactor, waiting for events, and calling the given block if
48
44
  # the reactor is awoken by the waker
49
45
  def run_once(timeout = nil)
50
- # FIXME: This approach is super ghetto. Find some way to make the
51
- # ZMQ::Poller wait on the waker's file descriptor
52
- if @poller.size == 0
53
- readable, _ = select [@waker.io], [], [], timeout
54
- yield if readable and readable.include? @waker.io
55
- else
56
- if ::ZMQ::Util.resultcode_ok? @poller.poll(100)
57
- @poller.readables.each do |sock|
58
- fiber = @readers.delete sock
59
- fiber.resume if fiber
60
- end
46
+ timeout ||= :blocking
47
+ rc = @poller.poll(timeout)
61
48
 
62
- @poller.writables.each do |sock|
63
- fiber = @writers.delete sock
64
- fiber.resume if fiber
65
- end
49
+ unless ::ZMQ::Util.resultcode_ok? rc
50
+ raise IOError, "0MQ poll error: #{::ZMQ::Util.error_string}"
51
+ end
52
+
53
+ @poller.readables.each do |sock|
54
+ if sock == @waker.socket
55
+ yield
56
+ else
57
+ fiber = @readers.delete sock
58
+ fiber.resume if fiber
66
59
  end
60
+ end
67
61
 
68
- readable, _ = select [@waker.io], [], [], 0
69
- yield if readable and readable.include? @waker.io
62
+ @poller.writables.each do |sock|
63
+ fiber = @writers.delete sock
64
+ fiber.resume if fiber
70
65
  end
71
66
  end
72
67
  end
@@ -1,5 +1,5 @@
1
1
  module Celluloid
2
2
  module ZMQ
3
- VERSION = "0.0.1"
3
+ VERSION = "0.0.2"
4
4
  end
5
5
  end
@@ -0,0 +1,54 @@
1
+ module Celluloid
2
+ module ZMQ
3
+ class DeadWakerError < Celluloid::IO::DeadWakerError; end # You can't wake the dead
4
+
5
+ # Wakes up sleepy threads so that they can check their mailbox
6
+ # Works like a ConditionVariable, except it's implemented as a ZMQ socket
7
+ # so that it can be multiplexed alongside other ZMQ sockets
8
+ class Waker
9
+ PAYLOAD = "\0" # the payload doesn't matter, it's just a signal
10
+
11
+ def initialize
12
+ @sender = ZMQ.context.socket(::ZMQ::PAIR)
13
+ @receiver = ZMQ.context.socket(::ZMQ::PAIR)
14
+
15
+ @addr = "inproc://waker-#{object_id}"
16
+ @sender.bind @addr
17
+ @receiver.connect @addr
18
+
19
+ @sender_lock = Mutex.new
20
+ end
21
+
22
+ # Wakes up the thread that is waiting for this Waker
23
+ def signal
24
+ @sender_lock.synchronize do
25
+ unless ::ZMQ::Util.resultcode_ok? @sender.send_string PAYLOAD
26
+ raise DeadWakerError, "error sending 0MQ message: #{::ZMQ::Util.error_string}"
27
+ end
28
+ end
29
+ end
30
+
31
+ # 0MQ socket to wait for messages on
32
+ def socket
33
+ @receiver
34
+ end
35
+
36
+ # Wait for another thread to signal this Waker
37
+ def wait
38
+ message = ''
39
+ rc = @receiver.recv_string message
40
+
41
+ unless ::ZMQ::Util.resultcode_ok? rc and message == PAYLOAD
42
+ raise DeadWakerError, "error receiving ZMQ string: #{::ZMQ::Util.error_string}"
43
+ end
44
+ end
45
+
46
+ # Clean up the IO objects associated with this waker
47
+ def cleanup
48
+ @sender_lock.synchronize { @sender.close rescue nil }
49
+ @receiver.close rescue nil
50
+ nil
51
+ end
52
+ end
53
+ end
54
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: celluloid-zmq
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2011-12-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: celluloid
16
- requirement: &70334545596400 !ruby/object:Gem::Requirement
16
+ requirement: &70257579473040 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 0.6.2
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70334545596400
24
+ version_requirements: *70257579473040
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: ffi
27
- requirement: &70334545595980 !ruby/object:Gem::Requirement
27
+ requirement: &70257579472580 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70334545595980
35
+ version_requirements: *70257579472580
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: ffi-rzmq
38
- requirement: &70334545595500 !ruby/object:Gem::Requirement
38
+ requirement: &70257579472120 !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: *70334545595500
46
+ version_requirements: *70257579472120
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: redis
49
- requirement: &70334545595000 !ruby/object:Gem::Requirement
49
+ requirement: &70257579471700 !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: *70334545595000
57
+ version_requirements: *70257579471700
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: redis-namespace
60
- requirement: &70334545594480 !ruby/object:Gem::Requirement
60
+ requirement: &70257579471260 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: '0'
66
66
  type: :runtime
67
67
  prerelease: false
68
- version_requirements: *70334545594480
68
+ version_requirements: *70257579471260
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rake
71
- requirement: &70334545593840 !ruby/object:Gem::Requirement
71
+ requirement: &70257579470560 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: '0'
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *70334545593840
79
+ version_requirements: *70257579470560
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: rspec
82
- requirement: &70334545592940 !ruby/object:Gem::Requirement
82
+ requirement: &70257579469580 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ! '>='
@@ -87,7 +87,7 @@ dependencies:
87
87
  version: 2.7.0
88
88
  type: :development
89
89
  prerelease: false
90
- version_requirements: *70334545592940
90
+ version_requirements: *70257579469580
91
91
  description: Celluloid bindings to the ffi-rzmq library
92
92
  email:
93
93
  - tony.arcieri@gmail.com
@@ -96,10 +96,12 @@ extensions: []
96
96
  extra_rdoc_files: []
97
97
  files:
98
98
  - celluloid-zmq.gemspec
99
+ - CHANGES.md
99
100
  - Gemfile
100
101
  - lib/celluloid/zmq/mailbox.rb
101
102
  - lib/celluloid/zmq/reactor.rb
102
103
  - lib/celluloid/zmq/version.rb
104
+ - lib/celluloid/zmq/waker.rb
103
105
  - lib/celluloid/zmq.rb
104
106
  - Rakefile
105
107
  - README.md