em-zeromq 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/.bnsignore ADDED
@@ -0,0 +1,18 @@
1
+ # The list of files that should be ignored by Mr Bones.
2
+ # Lines that start with '#' are comments.
3
+ #
4
+ # A .gitignore file can be used instead by setting it as the ignore
5
+ # file in your Rakefile:
6
+ #
7
+ # Bones {
8
+ # ignore_file '.gitignore'
9
+ # }
10
+ #
11
+ # For a project with a C extension, the following would be a good set of
12
+ # exclude patterns (uncomment them if you want to use them):
13
+ # *.[oa]
14
+ # *~
15
+ announcement.txt
16
+ coverage
17
+ doc
18
+ pkg
data/.gitignore ADDED
@@ -0,0 +1,8 @@
1
+ *.swp
2
+ *.swo
3
+ *.swn
4
+
5
+ *.rbc
6
+ *~
7
+
8
+ pkg
data/History.txt ADDED
@@ -0,0 +1,4 @@
1
+ == 1.0.0 / 2011-01-29
2
+
3
+ * 1 major enhancement
4
+ * Birthday!
data/README.md ADDED
@@ -0,0 +1,80 @@
1
+ # em-zeromq #
2
+
3
+ Low level event machine support for ZeroMQ
4
+
5
+ ## Description: ##
6
+
7
+ WARNING THIS IS ALPHA QUALITY AT THE MOMENT
8
+
9
+ A minimal test case passes, the basics of this are working.
10
+ It needs work for sure, for instance, you cannot remove a socket yet
11
+
12
+
13
+ ## Using: ##
14
+
15
+ You must use either rubinius, jruby, or 1.9.x rubies. 1.8.7 unfixable issues.
16
+
17
+ If you use 1.9.x, be sure to install the ffi gem first.
18
+
19
+ For all rubies install ffi-rzmq and eventmachine as well.
20
+
21
+ This only works with ZeroMQ 2.1.x which is still unreleased
22
+ Build+Install ZeroMQ 2.1 from HEAD ( https://github.com/zeromq/zeromq2 )
23
+
24
+ Run the specs, see specs for examples
25
+
26
+ Want to help out? Ask! Much work to be done here
27
+
28
+ ## Example ##
29
+
30
+ require 'rubygems'
31
+ require 'em-zeromq'
32
+
33
+ Thread.abort_on_exception = true
34
+
35
+ class EMTestPullHandler
36
+ attr_reader :received
37
+ def on_readable(socket, messages)
38
+ messages.each do |m|
39
+ puts m.copy_out_string
40
+ end
41
+ end
42
+ end
43
+ class EMTestPushHandler
44
+ def on_writable(socket)
45
+ end
46
+ end
47
+ EM.run do
48
+ ZCTX = ZMQ::Context.new 1
49
+ push = EM::ZeroMQ.create ZCTX, ZMQ::PUSH, :bind, 'tcp://127.0.0.1:2091', EMTestPushHandler.new
50
+ pull = EM::ZeroMQ.create ZCTX, ZMQ::PULL, :connect, 'tcp://127.0.0.1:2091', EMTestPullHandler.new
51
+
52
+ EM::PeriodicTimer.new(1) {
53
+ push.socket.send_string "Hello World! #{Time.now}", ZMQ::NOBLOCK
54
+ }
55
+ end
56
+
57
+ ## License: ##
58
+
59
+ (The MIT License)
60
+
61
+ Copyright (c) 2009 FIXME (different license?)
62
+
63
+ Permission is hereby granted, free of charge, to any person obtaining
64
+ a copy of this software and associated documentation files (the
65
+ 'Software'), to deal in the Software without restriction, including
66
+ without limitation the rights to use, copy, modify, merge, publish,
67
+ distribute, sublicense, and/or sell copies of the Software, and to
68
+ permit persons to whom the Software is furnished to do so, subject to
69
+ the following conditions:
70
+
71
+ The above copyright notice and this permission notice shall be
72
+ included in all copies or substantial portions of the Software.
73
+
74
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
75
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
76
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
77
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
78
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
79
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
80
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,20 @@
1
+
2
+ begin
3
+ require 'bones'
4
+ rescue LoadError
5
+ abort '### Please install the "bones" gem ###'
6
+ end
7
+
8
+ #task :default => 'test:run'
9
+ task 'gem:release' => 'test:run'
10
+
11
+ #depend_on 'ffi-rzmq', '0.7.0'
12
+ #depend_on 'eventmachine'
13
+
14
+ Bones {
15
+ name 'em-zeromq'
16
+ authors 'Andrew Cholakian'
17
+ email 'andrew@andrewvc.com'
18
+ url 'https://github.com/andrewvc/em-zeromq'
19
+ }
20
+
data/bin/em-zeromq ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.expand_path(
4
+ File.join(File.dirname(__FILE__), %w[.. lib em-zeromq]))
5
+
6
+ # Put your code here
7
+
data/em-zeromq.gemspec ADDED
@@ -0,0 +1,36 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{em-zeromq}
5
+ s.version = "0.0.1"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Andrew Cholakian"]
9
+ s.date = %q{2011-02-01}
10
+ s.default_executable = %q{em-zeromq}
11
+ s.description = %q{Low level event machine support for ZeroMQ}
12
+ s.email = %q{andrew@andrewvc.com}
13
+ s.executables = ["em-zeromq"]
14
+ s.extra_rdoc_files = ["History.txt", "bin/em-zeromq", "lib/em-zeromq/.connection.rb.swp", "version.txt"]
15
+ s.files = [".Rakefile.swo", ".bnsignore", "History.txt", "README.md", "Rakefile", "bin/em-zeromq", "example/simple.rb", "lib/em-zeromq.rb", "lib/em-zeromq/.connection.rb.swp", "lib/em-zeromq/connection.rb", "lib/em-zeromq/zeromq.rb", "spec/.pub_sub_spec.rb.swp", "spec/pub_sub_spec.rb", "spec/push_pull_spec.rb", "spec/spec_helper.rb", "test/test_em-zeromq.rb", "version.txt"]
16
+ s.homepage = %q{https://github.com/andrewvc/em-zeromq}
17
+ s.rdoc_options = ["--main", "README.md"]
18
+ s.require_paths = ["lib"]
19
+ s.rubyforge_project = %q{em-zeromq}
20
+ s.rubygems_version = %q{1.3.7}
21
+ s.summary = %q{Low level event machine support for ZeroMQ}
22
+ s.test_files = ["test/test_em-zeromq.rb"]
23
+
24
+ if s.respond_to? :specification_version then
25
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
26
+ s.specification_version = 3
27
+
28
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
29
+ s.add_development_dependency(%q<bones>, [">= 3.5.4"])
30
+ else
31
+ s.add_dependency(%q<bones>, [">= 3.5.4"])
32
+ end
33
+ else
34
+ s.add_dependency(%q<bones>, [">= 3.5.4"])
35
+ end
36
+ end
data/example/simple.rb ADDED
@@ -0,0 +1,27 @@
1
+ require 'rubygems'
2
+ require 'em-zeromq'
3
+
4
+ Thread.abort_on_exception = true
5
+
6
+ class EMTestPullHandler
7
+ attr_reader :received
8
+ def on_readable(socket, messages)
9
+ messages.each do |m|
10
+ puts m.copy_out_string
11
+ end
12
+ end
13
+ end
14
+ class EMTestPushHandler
15
+ def on_writable(socket)
16
+ end
17
+ end
18
+ EM.run do
19
+ ZCTX = ZMQ::Context.new 1
20
+ push = EM::ZeroMQ.create ZCTX, ZMQ::PUSH, :bind, 'tcp://127.0.0.1:2091', EMTestPushHandler.new
21
+ pull = EM::ZeroMQ.create ZCTX, ZMQ::PULL, :connect, 'tcp://127.0.0.1:2091', EMTestPullHandler.new
22
+
23
+ EM::PeriodicTimer.new(1) {
24
+ push.socket.send_string "Hello World! #{Time.now}", ZMQ::NOBLOCK
25
+ }
26
+ end
27
+
data/lib/em-zeromq.rb ADDED
@@ -0,0 +1,67 @@
1
+ require 'eventmachine'
2
+ require 'ffi-rzmq'
3
+
4
+ module EmZeromq
5
+
6
+ # :stopdoc:
7
+ LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
8
+ PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
9
+ # :startdoc:
10
+
11
+ # Returns the version string for the library.
12
+ #
13
+ def self.version
14
+ @version ||= File.read(path('version.txt')).strip
15
+ end
16
+
17
+ # Returns the library path for the module. If any arguments are given,
18
+ # they will be joined to the end of the libray path using
19
+ # <tt>File.join</tt>.
20
+ #
21
+ def self.libpath( *args, &block )
22
+ rv = args.empty? ? LIBPATH : ::File.join(LIBPATH, args.flatten)
23
+ if block
24
+ begin
25
+ $LOAD_PATH.unshift LIBPATH
26
+ rv = block.call
27
+ ensure
28
+ $LOAD_PATH.shift
29
+ end
30
+ end
31
+ return rv
32
+ end
33
+
34
+ # Returns the lpath for the module. If any arguments are given,
35
+ # they will be joined to the end of the path using
36
+ # <tt>File.join</tt>.
37
+ #
38
+ def self.path( *args, &block )
39
+ rv = args.empty? ? PATH : ::File.join(PATH, args.flatten)
40
+ if block
41
+ begin
42
+ $LOAD_PATH.unshift PATH
43
+ rv = block.call
44
+ ensure
45
+ $LOAD_PATH.shift
46
+ end
47
+ end
48
+ return rv
49
+ end
50
+
51
+ # Utility method used to require all files ending in .rb that lie in the
52
+ # directory below this file that has the same name as the filename passed
53
+ # in. Optionally, a specific _directory_ name can be passed in such that
54
+ # the _filename_ does not have to be equivalent to the directory.
55
+ #
56
+ def self.require_all_libs_relative_to( fname, dir = nil )
57
+ dir ||= ::File.basename(fname, '.*')
58
+ search_me = ::File.expand_path(
59
+ ::File.join(::File.dirname(fname), dir, '**', '*.rb'))
60
+
61
+ Dir.glob(search_me).sort.each {|rb| require rb}
62
+ end
63
+
64
+ end # module EmZeromq
65
+
66
+ EmZeromq.require_all_libs_relative_to(__FILE__)
67
+
@@ -0,0 +1,73 @@
1
+
2
+ module EventMachine
3
+ module ZeroMQ
4
+ class Connection < EventMachine::Connection
5
+ attr_accessor :on_readable, :on_writable, :handler
6
+ attr_reader :socket, :socket_type, :address
7
+
8
+ def initialize(socket, socket_type, address, handler)
9
+ @socket = socket
10
+ @socket_type = socket_type
11
+ @handler = handler
12
+ @address = address
13
+ end
14
+
15
+ def notify_readable
16
+ return unless read_capable?
17
+ #return unless (@socket.getsockopt(ZMQ::EVENTS) & ZMQ::POLLOUT) == ZMQ::POLLOUT
18
+
19
+ msg_parts = []
20
+
21
+ loop do
22
+ msg = get_message
23
+ if msg
24
+ msg_parts << msg
25
+ while @socket.more_parts?
26
+ msg = get_message
27
+ if msg
28
+ msg_parts << msg
29
+ else
30
+ raise "Multi-part message missing a message!"
31
+ end
32
+ end
33
+
34
+ @handler.on_readable(@socket, msg_parts)
35
+ else
36
+ break
37
+ end
38
+ end
39
+ end
40
+
41
+ def get_message
42
+ msg = ZMQ::Message.new
43
+ msg_recvd = @socket.recv(msg, ZMQ::NOBLOCK)
44
+ msg_recvd ? msg : nil
45
+ end
46
+
47
+ def deregister_writable
48
+ self.notify_writable = false
49
+ end
50
+
51
+ def register_writable
52
+ if (@socket.getsockopt(ZMQ::EVENTS) & ZMQ::POLLOUT) == ZMQ::POLLOUT
53
+ notify_writable
54
+ end
55
+ self.notify_writable = true
56
+ end
57
+
58
+ def notify_writable
59
+ @handler.on_writable(@socket)
60
+ end
61
+
62
+ private
63
+
64
+ def read_capable?
65
+ @read_capable ||= EM::ZeroMQ::READABLE_TYPES.include? @socket_type
66
+ end
67
+
68
+ def write_capable?
69
+ @write_capable ||= EM::ZeroMQ::WRITABLE_TYPES.include? @socket_type
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,30 @@
1
+ module EventMachine
2
+ module ZeroMQ
3
+ READABLE_TYPES = [ZMQ::SUB, ZMQ::PULL, ZMQ::REQ, ZMQ::REP, ZMQ::XREQ, ZMQ::XREP, ZMQ::PAIR]
4
+ WRITABLE_TYPES = [ZMQ::PUB, ZMQ::PUSH, ZMQ::REQ, ZMQ::REP, ZMQ::XREQ, ZMQ::XREP, ZMQ::PAIR]
5
+
6
+ def self.create(context, socket_type, bind_or_connect, address, handler)
7
+ socket = context.socket socket_type
8
+
9
+ unless [:bind, :connect].include?(bind_or_connect)
10
+ raise ArgumentError, "Invalid Option '#{bind_or_connect}' try :bind or :connect"
11
+ end
12
+
13
+ if bind_or_connect == :bind
14
+ socket.bind address
15
+ else
16
+ socket.connect address
17
+ end
18
+
19
+ conn = EM.watch(socket.getsockopt(ZMQ::FD), EventMachine::ZeroMQ::Connection, socket, socket_type, address, handler)
20
+ conn.notify_readable = true if EM::ZeroMQ::READABLE_TYPES.include? socket_type
21
+
22
+ #Given the nature of ZMQ this isn't that useful, and will generally
23
+ #cause perf problems as it repeatedly triggers. If people really want to
24
+ #use it, they should do so explicitly
25
+ conn.notify_writable = false
26
+ conn
27
+ end
28
+
29
+ end
30
+ end
@@ -0,0 +1,74 @@
1
+ require File.join(File.dirname(__FILE__), %w[spec_helper])
2
+
3
+ describe EventMachine::ZeroMQ do
4
+ class EMTestSubHandler
5
+ attr_reader :received
6
+ def initialize
7
+ @received = []
8
+ end
9
+ def on_readable(socket, messages)
10
+ @received += messages
11
+ end
12
+ end
13
+ class EMTestPubHandler
14
+ def initialize(&block)
15
+ @on_writable_callback = block
16
+ end
17
+ def on_writable(socket)
18
+ @on_writable_callback.call(socket) if @on_writable_callback
19
+ end
20
+ end
21
+
22
+ def make_sub(addr, b_or_c, handler=EMTestSubHandler.new)
23
+ conn = EM::ZeroMQ.create SPEC_CTX, ZMQ::SUB, b_or_c, addr, handler
24
+ conn.socket.setsockopt(ZMQ::SUBSCRIBE,'')
25
+ conn
26
+ end
27
+
28
+ def make_pub(addr, b_or_c, handler=EMTestPubHandler.new)
29
+ EM::ZeroMQ.create SPEC_CTX, ZMQ::PUB, b_or_c, addr, handler
30
+ end
31
+
32
+ it "Should instantiate a connection given valid opts" do
33
+ sub_conn = nil
34
+ run_reactor(2) do
35
+ sub_conn = make_sub(rand_addr, :bind, EMTestSubHandler.new)
36
+ end
37
+ sub_conn.should be_a(EventMachine::ZeroMQ::Connection)
38
+ end
39
+
40
+ describe "sending/receiving a single message via PUB/SUB" do
41
+ before(:all) do
42
+ results = {}
43
+ @test_message = test_message = "TMsg#{rand(999)}"
44
+
45
+ run_reactor(0.5) do
46
+ results[:sub_hndlr] = pull_hndlr = EMTestSubHandler.new
47
+ sub_conn = make_sub rand_addr, :bind, pull_hndlr
48
+ pub_conn = make_pub sub_conn.address, :connect
49
+
50
+ pub_conn.socket.send_string test_message, ZMQ::NOBLOCK
51
+
52
+ EM::Timer.new(0.1) { results[:specs_ran] = true }
53
+ end
54
+
55
+ @results = results
56
+ end
57
+
58
+ it "should run completely" do
59
+ @results[:specs_ran].should be_true
60
+ end
61
+
62
+ it "should receive one message" do
63
+ @results[:sub_hndlr].received.length.should == 1
64
+ end
65
+
66
+ it "should receive the message as a ZMQ::Message" do
67
+ @results[:sub_hndlr].received.first.should be_a(ZMQ::Message)
68
+ end
69
+
70
+ it "should receive the message intact" do
71
+ @results[:sub_hndlr].received.first.copy_out_string.should == @test_message
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,72 @@
1
+ require File.join(File.dirname(__FILE__), %w[spec_helper])
2
+
3
+ describe EventMachine::ZeroMQ do
4
+ class EMTestPullHandler
5
+ attr_reader :received
6
+ def initialize
7
+ @received = []
8
+ end
9
+ def on_readable(socket, messages)
10
+ @received += messages
11
+ end
12
+ end
13
+ class EMTestPushHandler
14
+ def initialize(&block)
15
+ @on_writable_callback = block
16
+ end
17
+ def on_writable(socket)
18
+ @on_writable_callback.call(socket) if @on_writable_callback
19
+ end
20
+ end
21
+
22
+ def make_pull(addr, b_or_c, handler=EMTestPullHandler.new)
23
+ EM::ZeroMQ.create SPEC_CTX, ZMQ::PULL, b_or_c, addr, handler
24
+ end
25
+
26
+ def make_push(addr, b_or_c, handler=EMTestPushHandler.new)
27
+ EM::ZeroMQ.create SPEC_CTX, ZMQ::PUSH, b_or_c, addr, handler
28
+ end
29
+
30
+ it "Should instantiate a connection given valid opts" do
31
+ pull_conn = nil
32
+ run_reactor do
33
+ pull_conn = make_pull(rand_addr, :bind, EMTestPullHandler.new)
34
+ end
35
+ pull_conn.should be_a(EventMachine::ZeroMQ::Connection)
36
+ end
37
+
38
+ describe "sending/receiving a single message via PUB/SUB" do
39
+ before(:all) do
40
+ results = {}
41
+ @test_message = test_message = "TMsg#{rand(999)}"
42
+
43
+ run_reactor(0.5) do
44
+ results[:pull_hndlr] = pull_hndlr = EMTestPullHandler.new
45
+ pull_conn = make_pull rand_addr, :bind, pull_hndlr
46
+ push_conn = make_push pull_conn.address, :connect
47
+
48
+ push_conn.socket.send_string test_message, ZMQ::NOBLOCK
49
+
50
+ EM::Timer.new(0.1) { results[:specs_ran] = true }
51
+ end
52
+
53
+ @results = results
54
+ end
55
+
56
+ it "should run completely" do
57
+ @results[:specs_ran].should be_true
58
+ end
59
+
60
+ it "should receive one message" do
61
+ @results[:pull_hndlr].received.length.should == 1
62
+ end
63
+
64
+ it "should receive the message as a ZMQ::Message" do
65
+ @results[:pull_hndlr].received.first.should be_a(ZMQ::Message)
66
+ end
67
+
68
+ it "should receive the message intact" do
69
+ @results[:pull_hndlr].received.first.copy_out_string.should == @test_message
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,42 @@
1
+ require 'set'
2
+ Thread.abort_on_exception = true
3
+
4
+ require File.expand_path(
5
+ File.join(File.dirname(__FILE__), %w[.. lib em-zeromq]))
6
+
7
+ def run_reactor(time=0.2,&block)
8
+ Thread.new do
9
+ EM.run do
10
+ yield
11
+ end
12
+ end
13
+ sleep time
14
+ EM.stop rescue nil
15
+ sleep 0.1
16
+ end
17
+
18
+ USED_RAND_ADDRS = Set.new
19
+ def rand_addr(scheme='tcp')
20
+ addr = nil
21
+ loop do
22
+ case scheme
23
+ when 'tcp'
24
+ addr = "tcp://127.0.0.1:#{rand(10_000) + 20_000}"
25
+ when 'inproc'
26
+ addr = "inproc://testinp-#{rand(10_000) + 20_000}"
27
+ end
28
+
29
+ if USED_RAND_ADDRS.include? addr
30
+ next
31
+ else
32
+ USED_RAND_ADDRS << addr
33
+ break
34
+ end
35
+ end
36
+ addr
37
+ end
38
+
39
+ SPEC_CTX = ZMQ::Context.new 1
40
+ def spec_ctx
41
+ SPEC_CTX
42
+ end
File without changes
data/version.txt ADDED
@@ -0,0 +1 @@
1
+ 0.1.1
metadata ADDED
@@ -0,0 +1,96 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: em-zeromq
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 1
9
+ version: 0.1.1
10
+ platform: ruby
11
+ authors:
12
+ - Andrew Cholakian
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2011-02-01 00:00:00 -08:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: bones
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 3
30
+ - 6
31
+ - 2
32
+ version: 3.6.2
33
+ type: :development
34
+ version_requirements: *id001
35
+ description: Low level event machine support for ZeroMQ
36
+ email: andrew@andrewvc.com
37
+ executables:
38
+ - em-zeromq
39
+ extensions: []
40
+
41
+ extra_rdoc_files:
42
+ - History.txt
43
+ - bin/em-zeromq
44
+ files:
45
+ - .Rakefile.swo
46
+ - .bnsignore
47
+ - .gitignore
48
+ - History.txt
49
+ - README.md
50
+ - Rakefile
51
+ - bin/em-zeromq
52
+ - em-zeromq.gemspec
53
+ - example/simple.rb
54
+ - lib/em-zeromq.rb
55
+ - lib/em-zeromq/connection.rb
56
+ - lib/em-zeromq/zeromq.rb
57
+ - spec/pub_sub_spec.rb
58
+ - spec/push_pull_spec.rb
59
+ - spec/spec_helper.rb
60
+ - test/test_em-zeromq.rb
61
+ - version.txt
62
+ has_rdoc: true
63
+ homepage: https://github.com/andrewvc/em-zeromq
64
+ licenses: []
65
+
66
+ post_install_message:
67
+ rdoc_options:
68
+ - --main
69
+ - README.md
70
+ require_paths:
71
+ - lib
72
+ required_ruby_version: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ segments:
78
+ - 0
79
+ version: "0"
80
+ required_rubygems_version: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ segments:
86
+ - 0
87
+ version: "0"
88
+ requirements: []
89
+
90
+ rubyforge_project: em-zeromq
91
+ rubygems_version: 1.3.7
92
+ signing_key:
93
+ specification_version: 3
94
+ summary: Low level event machine support for ZeroMQ
95
+ test_files:
96
+ - test/test_em-zeromq.rb