celluloid-io 0.9.0 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
data/.travis.yml CHANGED
@@ -1,10 +1,10 @@
1
1
  rvm:
2
- - 1.9.2
3
2
  - 1.9.3
4
3
  - ruby-head
5
4
  - jruby-19mode
6
- - jruby-head
7
5
 
8
- # Rubies I would like to support, but they deadlock
9
- # - rbx-18mode
6
+ # Getting a deadlock in the nonblocking connect code :(
7
+ # - jruby-head
8
+
9
+ # See https://github.com/rubinius/rubinius/issues/1611
10
10
  # - rbx-19mode
data/CHANGES.md CHANGED
@@ -1,3 +1,9 @@
1
+ 0.10.0
2
+ ------
3
+ * Read/write operations are now atomic across tasks
4
+ * True non-blocking connect support
5
+ * Non-blocking DNS resolution support
6
+
1
7
  0.9.0
2
8
  -----
3
9
  * TCPServer, TCPSocket, and UDPSocket classes in Celluloid::IO namespace
data/Gemfile CHANGED
@@ -1,6 +1,6 @@
1
1
  source :rubygems
2
2
 
3
- gem 'celluloid', :git => 'git://github.com/tarcieri/celluloid'
3
+ gem 'celluloid', :git => 'git://github.com/celluloid/celluloid'
4
4
 
5
5
  # Specify your gem's dependencies in celluloid-io.gemspec
6
6
  gemspec
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2011 Tony Arcieri
1
+ Copyright (c) 2012 Tony Arcieri
2
2
 
3
3
  MIT License
4
4
 
@@ -19,4 +19,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
19
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
20
  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
21
  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -1,12 +1,12 @@
1
- ![Celluloid](https://github.com/tarcieri/celluloid-io/raw/master/logo.png)
1
+ ![Celluloid](https://github.com/celluloid/celluloid-io/raw/master/logo.png)
2
2
  =============
3
- [![Build Status](https://secure.travis-ci.org/tarcieri/celluloid-io.png?branch=master)](http://travis-ci.org/tarcieri/celluloid-io)
4
- [![Dependency Status](https://gemnasium.com/tarcieri/celluloid-io.png)](https://gemnasium.com/tarcieri/celluloid-io)
3
+ [![Build Status](https://secure.travis-ci.org/celluloid/celluloid-io.png?branch=master)](http://travis-ci.org/celluloid/celluloid-io)
4
+ [![Dependency Status](https://gemnasium.com/celluloid/celluloid-io.png)](https://gemnasium.com/celluloid/celluloid-io)
5
5
 
6
6
  You don't have to choose between threaded and evented IO! Celluloid::IO
7
7
  provides an event-driven IO system for building fast, scalable network
8
8
  applications that integrates directly with the
9
- [Celluloid actor library](https://github.com/tarcieri/celluloid), making it
9
+ [Celluloid actor library](https://github.com/celluloid/celluloid), making it
10
10
  easy to combine both threaded and evented concepts. Celluloid::IO is ideal for
11
11
  servers which handle large numbers of mostly-idle connections, such as Websocket
12
12
  servers or chat/messaging systems.
@@ -38,7 +38,9 @@ Like Celluloid::IO? [Join the Google Group](http://groups.google.com/group/cellu
38
38
  Supported Platforms
39
39
  -------------------
40
40
 
41
- Celluloid::IO works on Ruby 1.9.2+, JRuby 1.6 (in 1.9 mode), and Rubinius 2.0.
41
+ Celluloid::IO requires Ruby 1.9 support on all Ruby VMs.
42
+
43
+ Supported VMs are Ruby 1.9.3, JRuby 1.6, and Rubinius 2.0.
42
44
 
43
45
  To use JRuby in 1.9 mode, you'll need to pass the "--1.9" command line option
44
46
  to the JRuby executable, or set the "JRUBY_OPTS=--1.9" environment variable.
@@ -85,7 +87,7 @@ end
85
87
  The very first thing including *Celluloid::IO* does is also include the
86
88
  *Celluloid* module, which promotes objects of this class to concurrent Celluloid
87
89
  actors each running in their own thread. Before trying to use Celluloid::IO
88
- you may want to [familiarize yourself with Celluloid in general](https://github.com/tarcieri/celluloid/).
90
+ you may want to [familiarize yourself with Celluloid in general](https://github.com/celluloid/celluloid/).
89
91
  Celluloid actors can each be thought of as being event loops. Celluloid::IO actors
90
92
  are heavier but have capabilities similar to other event loop-driven frameworks.
91
93
 
@@ -114,7 +116,7 @@ comes in three forms:
114
116
 
115
117
  * __Reactor + Fibers:__ Celluloid::IO is a combination of Actor and Reactor
116
118
  concepts. The blocking mechanism used by the mailboxes of Celluloid::IO
117
- actors is an [nio4r-powered reactor](https://github.com/tarcieri/celluloid-io/blob/master/lib/celluloid/io/reactor.rb).
119
+ actors is an [nio4r-powered reactor](https://github.com/celluloid/celluloid-io/blob/master/lib/celluloid/io/reactor.rb).
118
120
  When the current task needs to make a blocking I/O call, it first makes
119
121
  a non-blocking attempt, and if the socket isn't ready the current task
120
122
  is suspended until the reactor detects the operation is ready and resumes
@@ -149,7 +151,7 @@ Contributing to Celluloid::IO
149
151
  License
150
152
  -------
151
153
 
152
- Copyright (c) 2011 Tony Arcieri. Distributed under the MIT License. See
154
+ Copyright (c) 2012 Tony Arcieri. Distributed under the MIT License. See
153
155
  LICENSE.txt for further details.
154
156
 
155
157
  Contains code originally from the RubySpec project also under the MIT License
data/Rakefile CHANGED
@@ -1,7 +1,5 @@
1
1
  #!/usr/bin/env rake
2
2
  require 'bundler/gem_tasks'
3
- require 'rspec/core/rake_task'
3
+ Dir["tasks/**/*.task"].each { |task| load task }
4
4
 
5
- RSpec::Core::RakeTask.new
6
-
7
- task :default => :spec
5
+ task :default => :spec
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'bundler/setup'
5
+ require 'celluloid/io'
6
+ require 'benchmark/ips'
7
+
8
+ class ExampleActor
9
+ include Celluloid::IO
10
+ def example_method; end
11
+ end
12
+
13
+ example_actor = ExampleActor.new
14
+ mailbox = Celluloid::Mailbox.new
15
+
16
+ latch_in, latch_out = Queue.new, Queue.new
17
+ latch = Thread.new do
18
+ while true
19
+ n = latch_in.pop
20
+ for i in 0..n; mailbox.receive; end
21
+ latch_out << :done
22
+ end
23
+ end
24
+
25
+ Benchmark.ips do |ips|
26
+ ips.report("spawn") { ExampleActor.new.terminate }
27
+ ips.report("calls") { example_actor.example_method }
28
+ ips.report("async calls") { example_actor.example_method! }
29
+
30
+ ips.report("messages") do |n|
31
+ latch_in << n
32
+ for i in 0..n; mailbox << :message; end
33
+ latch_out.pop
34
+ end
35
+ end
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'bundler/setup'
5
+ require 'celluloid'
6
+ require 'benchmark/ips'
7
+ require File.expand_path("../../examples/ring", __FILE__)
8
+
9
+ # 512-node ring
10
+ ring = Ring.new 512
11
+
12
+ Benchmark.ips do |ips|
13
+ ips.report("ring-around") { |n| ring.run n }
14
+ end
data/celluloid-io.gemspec CHANGED
@@ -6,7 +6,7 @@ Gem::Specification.new do |gem|
6
6
  gem.email = ["tony.arcieri@gmail.com"]
7
7
  gem.description = "Evented IO for Celluloid actors"
8
8
  gem.summary = "Celluloid::IO allows you to monitor multiple IO objects within a Celluloid actor"
9
- gem.homepage = "http://github.com/tarcieri/celluloid-io"
9
+ gem.homepage = "http://github.com/celluloid/celluloid-io"
10
10
 
11
11
  gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
12
12
  gem.files = `git ls-files`.split("\n")
@@ -15,9 +15,10 @@ Gem::Specification.new do |gem|
15
15
  gem.require_paths = ["lib"]
16
16
  gem.version = Celluloid::IO::VERSION
17
17
 
18
- gem.add_dependency 'celluloid', '~> 0.9.0'
18
+ gem.add_dependency 'celluloid', '~> 0.10.0'
19
19
  gem.add_dependency 'nio4r', '>= 0.3.1'
20
20
 
21
21
  gem.add_development_dependency 'rake'
22
22
  gem.add_development_dependency 'rspec'
23
+ gem.add_development_dependency 'benchmark_suite'
23
24
  end
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'bundler/setup'
5
+ require 'celluloid/io'
6
+
7
+ class EchoClient
8
+ include Celluloid::IO
9
+
10
+ def initialize(host, port)
11
+ puts "*** Connecting to echo server on #{host}:#{port}"
12
+
13
+ @socket = TCPSocket.from_ruby_socket(::TCPSocket.new(host, port))
14
+ end
15
+
16
+ def echo(s)
17
+ @socket.write(s)
18
+ actor = Celluloid.current_actor
19
+ @socket.readpartial(4096)
20
+ end
21
+
22
+ end
23
+
24
+ client = EchoClient.new("127.0.0.1", 1234)
25
+ puts client.echo("TEST FOR ECHO")
data/lib/celluloid/io.rb CHANGED
@@ -1,8 +1,9 @@
1
+ require 'forwardable'
1
2
  require 'celluloid/io/version'
2
3
 
3
- require 'forwardable'
4
4
  require 'celluloid'
5
5
  require 'celluloid/io/common_methods'
6
+ require 'celluloid/io/dns_resolver'
6
7
  require 'celluloid/io/mailbox'
7
8
  require 'celluloid/io/reactor'
8
9
 
@@ -20,7 +21,7 @@ module Celluloid
20
21
 
21
22
  extend Forwardable
22
23
 
23
- # Wait for the given IO object to become readable/writeable
24
- def_delegators 'current_actor.mailbox.reactor', :wait_readable, :wait_writeable
24
+ # Wait for the given IO object to become readable/writable
25
+ def_delegators 'current_actor.mailbox.reactor', :wait_readable, :wait_writable
25
26
  end
26
27
  end
@@ -19,8 +19,6 @@ module Celluloid
19
19
 
20
20
  # Wait until the current object is writable
21
21
  def wait_writable
22
- actor = Thread.current[:actor]
23
-
24
22
  if evented?
25
23
  Celluloid.current_actor.wait_writable(self.to_io)
26
24
  else
@@ -28,20 +26,60 @@ module Celluloid
28
26
  end
29
27
  end
30
28
 
29
+ # Request exclusive control for a particular operation
30
+ # Type should be one of :r (read) or :w (write)
31
+ def acquire_ownership(type)
32
+ return unless Thread.current[:actor]
33
+
34
+ case type
35
+ when :r
36
+ ivar = :@read_owner
37
+ when :w
38
+ ivar = :@write_owner
39
+ else raise ArgumentError, "invalid ownership type: #{type}"
40
+ end
41
+
42
+ Actor.current.wait(self) while instance_variable_get(ivar)
43
+ instance_variable_set(ivar, Task.current)
44
+ end
45
+
46
+ # Release ownership for a particular operation
47
+ # Type should be one of :r (read) or :w (write)
48
+ def release_ownership(type)
49
+ return unless Thread.current[:actor]
50
+
51
+ case type
52
+ when :r
53
+ ivar = :@read_owner
54
+ when :w
55
+ ivar = :@write_owner
56
+ else raise ArgumentError, "invalid ownership type: #{type}"
57
+ end
58
+
59
+ raise "not owner" unless instance_variable_get(ivar) == Task.current
60
+ instance_variable_set(ivar, nil)
61
+ Actor.current.signal(self)
62
+ end
63
+
31
64
  def read(length, buffer = nil)
32
65
  buffer ||= ''
33
66
  remaining = length
34
67
 
35
- until remaining.zero?
36
- begin
37
- str = readpartial(remaining)
38
- rescue EOFError
39
- return if length == remaining
40
- return buffer
41
- end
68
+ acquire_ownership :r
69
+ begin
70
+ until remaining.zero?
71
+ begin
72
+ str = readpartial(remaining)
73
+ rescue EOFError
74
+ return if length == remaining
75
+ return buffer
76
+ end
42
77
 
43
- buffer << str
44
- remaining -= str.length
78
+ buffer << str
79
+ remaining -= str.length
80
+ end
81
+ ensure
82
+ release_ownership :r
45
83
  end
46
84
 
47
85
  buffer
@@ -65,27 +103,24 @@ module Celluloid
65
103
  total_written = 0
66
104
 
67
105
  remaining = string
68
- while total_written < length
69
- begin
70
- written = write_nonblock(remaining)
71
- rescue ::IO::WaitWritable
72
- wait_writable
73
- retry
74
- rescue EOFError
75
- return total_written
76
- end
106
+ acquire_ownership :w
77
107
 
78
- total_written += written
79
- if written < remaining.length
80
- # Avoid mutating string itself, but we can mutate the remaining data
81
- if remaining == string
82
- # Copy the remaining data so as to avoid mutating string
83
- # Note if we have a large amount of data remaining this could be slow
84
- remaining = string[written..-1]
85
- else
86
- remaining.slice!(0, written)
108
+ begin
109
+ while total_written < length
110
+ begin
111
+ written = write_nonblock(remaining)
112
+ rescue ::IO::WaitWritable
113
+ wait_writable
114
+ retry
115
+ rescue EOFError
116
+ return total_written
87
117
  end
118
+
119
+ total_written += written
120
+ remaining.slice!(0, written) if written < remaining.length
88
121
  end
122
+ ensure
123
+ release_ownership :w
89
124
  end
90
125
 
91
126
  total_written
@@ -0,0 +1,79 @@
1
+ require 'resolv'
2
+
3
+ module Celluloid
4
+ module IO
5
+ # Asynchronous DNS resolver using Celluloid::IO::UDPSocket
6
+ class DNSResolver
7
+ RESOLV_CONF = '/etc/resolv.conf'
8
+ HOSTS = '/etc/hosts'
9
+ DNS_PORT = 53
10
+
11
+ @mutex = Mutex.new
12
+ @identifier = 1
13
+
14
+ def self.generate_id
15
+ @mutex.synchronize { @identifier = (@identifier + 1) & 0xFFFF }
16
+ end
17
+
18
+ def self.nameservers(config = RESOLV_CONF)
19
+ File.read(config).scan(/^\s*nameserver\s+([0-9.:]+)/).flatten
20
+ end
21
+
22
+ def self.hosts(hostfile = HOSTS)
23
+ hosts = {}
24
+ File.open(hostfile) do |f|
25
+ f.each_line do |host_entry|
26
+ entries = host_entry.gsub(/#.*$/, '').gsub(/\s+/, ' ').split(' ')
27
+ addr = entries.shift
28
+ entries.each { |e| hosts[e] ||= addr }
29
+ end
30
+ end
31
+ hosts
32
+ end
33
+
34
+ def initialize
35
+ @nameservers, @hosts = self.class.nameservers, self.class.hosts
36
+
37
+ # TODO: fall back on other nameservers if the first one is unavailable
38
+ @server = @nameservers.first
39
+
40
+ # The non-blocking secret sauce is here, as this is actually a
41
+ # Celluloid::IO::UDPSocket
42
+ @socket = UDPSocket.new
43
+ end
44
+
45
+ def resolve(hostname)
46
+ host = @hosts[hostname]
47
+ if host
48
+ begin
49
+ return Resolv::IPv4.create(host)
50
+ rescue ArgumentError
51
+ end
52
+
53
+ begin
54
+ return Resolv::IPv6.create(host)
55
+ rescue ArgumentError
56
+ end
57
+
58
+ raise Resolv::ResolvError, "invalid entry in hosts file: #{host}"
59
+ end
60
+
61
+ query = Resolv::DNS::Message.new
62
+ query.id = self.class.generate_id
63
+ query.rd = 1
64
+ query.add_question hostname, Resolv::DNS::Resource::IN::A
65
+
66
+ @socket.send query.encode, 0, @server, DNS_PORT
67
+ data, _ = @socket.recvfrom(512)
68
+ response = Resolv::DNS::Message.decode(data)
69
+
70
+ addrs = []
71
+ response.each_answer { |name, ttl, value| addrs << value.address }
72
+
73
+ return if addrs.empty?
74
+ return addrs.first if addrs.size == 1
75
+ addrs
76
+ end
77
+ end
78
+ end
79
+ end
@@ -15,7 +15,8 @@ module Celluloid
15
15
  @mutex.lock
16
16
  begin
17
17
  @messages << message
18
- @reactor.wakeup
18
+ current_actor = Thread.current[:actor]
19
+ @reactor.wakeup unless current_actor && current_actor.mailbox == self
19
20
  rescue IOError
20
21
  raise MailboxError, "dead recipient"
21
22
  ensure @mutex.unlock
@@ -28,7 +29,8 @@ module Celluloid
28
29
  @mutex.lock
29
30
  begin
30
31
  @messages.unshift event
31
- @reactor.wakeup
32
+ current_actor = Thread.current[:actor]
33
+ @reactor.wakeup unless current_actor && current_actor.mailbox == self
32
34
  rescue IOError
33
35
  # Silently fail if messages are sent to dead actors
34
36
  ensure @mutex.unlock
@@ -21,8 +21,8 @@ module Celluloid
21
21
  wait io, :r
22
22
  end
23
23
 
24
- # Wait for the given IO object to become writeable
25
- def wait_writeable(io)
24
+ # Wait for the given IO object to become writable
25
+ def wait_writable(io)
26
26
  wait io, :w
27
27
  end
28
28
 
@@ -48,7 +48,7 @@ module Celluloid
48
48
  def run_once(timeout = nil)
49
49
  @selector.select(timeout) do |monitor|
50
50
  task = monitor.value
51
- @selector.deregister(monitor.io)
51
+ monitor.close
52
52
 
53
53
  if task.running?
54
54
  task.resume
@@ -1,4 +1,5 @@
1
1
  require 'socket'
2
+ require 'resolv'
2
3
 
3
4
  module Celluloid
4
5
  module IO
@@ -8,7 +9,7 @@ module Celluloid
8
9
  extend Forwardable
9
10
 
10
11
  def_delegators :@socket, :read_nonblock, :write_nonblock, :close, :closed?
11
- def_delegators :@socket, :addr, :peeraddr
12
+ def_delegators :@socket, :addr, :peeraddr, :setsockopt
12
13
 
13
14
  # Convert a Ruby TCPSocket into a Celluloid::IO::TCPSocket
14
15
  def self.from_ruby_socket(ruby_socket)
@@ -22,8 +23,51 @@ module Celluloid
22
23
  # and local_port are specified, then those parameters are used on the
23
24
  # local end to establish the connection.
24
25
  def initialize(remote_host, remote_port, local_host = nil, local_port = nil)
25
- # FIXME: not using non-blocking connect
26
- @socket = ::TCPSocket.new(remote_host, remote_port, local_host, local_port)
26
+ # Is it an IPv4 address?
27
+ begin
28
+ @addr = Resolv::IPv4.create(remote_host)
29
+ rescue ArgumentError
30
+ end
31
+
32
+ # Guess it's not IPv4! Is it IPv6?
33
+ unless @addr
34
+ begin
35
+ @addr = Resolv::IPv6.create(remote_host)
36
+ rescue ArgumentError
37
+ end
38
+ end
39
+
40
+ # Guess it's not an IP address, so let's try DNS
41
+ unless @addr
42
+ # TODO: suppport asynchronous DNS
43
+ # Even EventMachine doesn't do async DNS by default o_O
44
+ addrs = Array(DNSResolver.new.resolve(remote_host))
45
+ raise Resolv::ResolvError, "DNS result has no information for #{remote_host}" if addrs.empty?
46
+
47
+ # Pseudorandom round-robin DNS support :/
48
+ @addr = addrs[rand(addrs.size)]
49
+ end
50
+
51
+ case @addr
52
+ when Resolv::IPv4
53
+ family = Socket::AF_INET
54
+ when Resolv::IPv6
55
+ family = Socket::AF_INET6
56
+ else raise ArgumentError, "unsupported address class: #{@addr.class}"
57
+ end
58
+
59
+ @socket = Socket.new(family, Socket::SOCK_STREAM, 0)
60
+ @socket.bind Addrinfo.tcp(local_host, local_port) if local_host
61
+
62
+ begin
63
+ @socket.connect_nonblock Socket.sockaddr_in(remote_port, @addr.to_s)
64
+ rescue Errno::EINPROGRESS
65
+ wait_writable
66
+ retry
67
+ rescue Errno::EISCONN
68
+ # We're now connected! Yay exceptions for flow control
69
+ # NOTE: This is the approach the Ruby stdlib docs suggest ;_;
70
+ end
27
71
  end
28
72
 
29
73
  def to_io
@@ -1,5 +1,5 @@
1
1
  module Celluloid
2
2
  module IO
3
- VERSION = "0.9.0"
3
+ VERSION = "0.10.0"
4
4
  end
5
5
  end
data/logo.png CHANGED
Binary file
@@ -2,4 +2,4 @@ require 'spec_helper'
2
2
 
3
3
  describe Celluloid::IO do
4
4
  it_behaves_like "a Celluloid Actor", Celluloid::IO
5
- end
5
+ end
@@ -0,0 +1,8 @@
1
+ require 'spec_helper'
2
+
3
+ describe Celluloid::IO::DNSResolver do
4
+ it "resolves domain names" do
5
+ resolver = Celluloid::IO::DNSResolver.new
6
+ resolver.resolve("celluloid.io").should == Resolv::IPv4.create("207.97.227.245")
7
+ end
8
+ end
@@ -0,0 +1,19 @@
1
+ require 'timeout'
2
+
3
+ desc "Run Celluloid benchmarks"
4
+ task :benchmark do
5
+ # Travis has an out-of-date version of rbx that rashes on the benchmarks
6
+ exit 0 if ENV['CI'] and RUBY_ENGINE == 'rbx'
7
+
8
+ begin
9
+ Timeout.timeout(120) do
10
+ glob = File.expand_path("../../benchmarks/*.rb", __FILE__)
11
+ Dir[glob].each { |benchmark| load benchmark }
12
+ end
13
+ rescue Exception, Timeout::Error => ex
14
+ puts "ERROR: Couldn't complete benchmark: #{ex.class}: #{ex}"
15
+ puts " #{ex.backtrace.join("\n ")}"
16
+
17
+ exit 1 unless ENV['CI'] # Hax for running benchmarks on Travis
18
+ end
19
+ end
data/tasks/rspec.task ADDED
@@ -0,0 +1,7 @@
1
+ require 'rspec/core/rake_task'
2
+
3
+ RSpec::Core::RakeTask.new
4
+
5
+ RSpec::Core::RakeTask.new(:rcov) do |task|
6
+ task.rcov = true
7
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: celluloid-io
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.10.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,22 +9,22 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-02-21 00:00:00.000000000 Z
12
+ date: 2012-04-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: celluloid
16
- requirement: &70287081256280 !ruby/object:Gem::Requirement
16
+ requirement: &70278839545080 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
20
20
  - !ruby/object:Gem::Version
21
- version: 0.9.0
21
+ version: 0.10.0
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70287081256280
24
+ version_requirements: *70278839545080
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: nio4r
27
- requirement: &70287081254940 !ruby/object:Gem::Requirement
27
+ requirement: &70278839544320 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 0.3.1
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70287081254940
35
+ version_requirements: *70278839544320
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rake
38
- requirement: &70287081253700 !ruby/object:Gem::Requirement
38
+ requirement: &70278839543940 !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: :development
45
45
  prerelease: false
46
- version_requirements: *70287081253700
46
+ version_requirements: *70278839543940
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rspec
49
- requirement: &70287081251980 !ruby/object:Gem::Requirement
49
+ requirement: &70278839543480 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,7 +54,18 @@ dependencies:
54
54
  version: '0'
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *70287081251980
57
+ version_requirements: *70278839543480
58
+ - !ruby/object:Gem::Dependency
59
+ name: benchmark_suite
60
+ requirement: &70278839543020 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70278839543020
58
69
  description: Evented IO for Celluloid actors
59
70
  email:
60
71
  - tony.arcieri@gmail.com
@@ -70,10 +81,14 @@ files:
70
81
  - LICENSE.txt
71
82
  - README.md
72
83
  - Rakefile
84
+ - benchmarks/actor.rb
85
+ - benchmarks/ring.rb
73
86
  - celluloid-io.gemspec
87
+ - examples/echo_client.rb
74
88
  - examples/echo_server.rb
75
89
  - lib/celluloid/io.rb
76
90
  - lib/celluloid/io/common_methods.rb
91
+ - lib/celluloid/io/dns_resolver.rb
77
92
  - lib/celluloid/io/mailbox.rb
78
93
  - lib/celluloid/io/reactor.rb
79
94
  - lib/celluloid/io/tcp_server.rb
@@ -82,12 +97,15 @@ files:
82
97
  - lib/celluloid/io/version.rb
83
98
  - logo.png
84
99
  - spec/celluloid/io/actor_spec.rb
100
+ - spec/celluloid/io/dns_resolver_spec.rb
85
101
  - spec/celluloid/io/mailbox_spec.rb
86
102
  - spec/celluloid/io/tcp_server_spec.rb
87
103
  - spec/celluloid/io/tcp_socket_spec.rb
88
104
  - spec/celluloid/io/udp_socket_spec.rb
89
105
  - spec/spec_helper.rb
90
- homepage: http://github.com/tarcieri/celluloid-io
106
+ - tasks/benchmarks.task
107
+ - tasks/rspec.task
108
+ homepage: http://github.com/celluloid/celluloid-io
91
109
  licenses: []
92
110
  post_install_message:
93
111
  rdoc_options: []
@@ -107,16 +125,16 @@ required_rubygems_version: !ruby/object:Gem::Requirement
107
125
  version: '0'
108
126
  requirements: []
109
127
  rubyforge_project:
110
- rubygems_version: 1.8.10
128
+ rubygems_version: 1.8.17
111
129
  signing_key:
112
130
  specification_version: 3
113
131
  summary: Celluloid::IO allows you to monitor multiple IO objects within a Celluloid
114
132
  actor
115
133
  test_files:
116
134
  - spec/celluloid/io/actor_spec.rb
135
+ - spec/celluloid/io/dns_resolver_spec.rb
117
136
  - spec/celluloid/io/mailbox_spec.rb
118
137
  - spec/celluloid/io/tcp_server_spec.rb
119
138
  - spec/celluloid/io/tcp_socket_spec.rb
120
139
  - spec/celluloid/io/udp_socket_spec.rb
121
140
  - spec/spec_helper.rb
122
- has_rdoc: