celluloid-io 0.10.0 → 0.11.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.
data/.travis.yml CHANGED
@@ -1,3 +1,4 @@
1
+ script: rake ci
1
2
  rvm:
2
3
  - 1.9.3
3
4
  - ruby-head
@@ -8,3 +9,6 @@ rvm:
8
9
 
9
10
  # See https://github.com/rubinius/rubinius/issues/1611
10
11
  # - rbx-19mode
12
+
13
+ notifications:
14
+ irc: "irc.freenode.org#celluloid"
data/CHANGES.md CHANGED
@@ -1,3 +1,7 @@
1
+ 0.11.0
2
+ ------
3
+ * "Unofficial" SSL support (via nio4r 0.4.0)
4
+
1
5
  0.10.0
2
6
  ------
3
7
  * Read/write operations are now atomic across tasks
data/Gemfile CHANGED
@@ -1,6 +1,6 @@
1
1
  source :rubygems
2
2
 
3
- gem 'celluloid', :git => 'git://github.com/celluloid/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/README.md CHANGED
@@ -130,10 +130,9 @@ classes instead of the core Ruby TCPSocket and TCPServer classes.
130
130
  Status
131
131
  ------
132
132
 
133
- The rudiments of TCPServer and TCPSocket are in place and ready to use.
134
- Several methods are still missing. Making new connections with
135
- Celluloid::IO::TCPSocket.new works, however it presently does blocking DNS
136
- resolution and connect so it can stall the reactor loop.
133
+ The rudiments of TCPServer and TCPSocket are in place and ready to use. It is now
134
+ fully nonblocking, including DNS resolution, which effectively makes Celluloid::IO
135
+ feature complete as a nonblocking I/O system.
137
136
 
138
137
  Basic UDPSocket support is in place. On JRuby, recvfrom makes a blocking call
139
138
  as the underlying recvfrom_nonblock call is not supported by JRuby.
data/Rakefile CHANGED
@@ -3,3 +3,4 @@ require 'bundler/gem_tasks'
3
3
  Dir["tasks/**/*.task"].each { |task| load task }
4
4
 
5
5
  task :default => :spec
6
+ task :ci => %w(spec benchmark)
data/benchmarks/actor.rb CHANGED
@@ -25,7 +25,9 @@ end
25
25
  Benchmark.ips do |ips|
26
26
  ips.report("spawn") { ExampleActor.new.terminate }
27
27
  ips.report("calls") { example_actor.example_method }
28
- ips.report("async calls") { example_actor.example_method! }
28
+
29
+ # FIXME: deadlock?! o_O
30
+ ips.report("async calls") { example_actor.example_method! } unless RUBY_ENGINE == 'ruby'
29
31
 
30
32
  ips.report("messages") do |n|
31
33
  latch_in << n
data/celluloid-io.gemspec CHANGED
@@ -15,8 +15,8 @@ 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.10.0'
19
- gem.add_dependency 'nio4r', '>= 0.3.1'
18
+ gem.add_dependency 'celluloid', '~> 0.11.0'
19
+ gem.add_dependency 'nio4r', '>= 0.4.0'
20
20
 
21
21
  gem.add_development_dependency 'rake'
22
22
  gem.add_development_dependency 'rspec'
@@ -61,22 +61,32 @@ module Celluloid
61
61
  Actor.current.signal(self)
62
62
  end
63
63
 
64
- def read(length, buffer = nil)
64
+ def read(length = nil, buffer = nil)
65
65
  buffer ||= ''
66
66
  remaining = length
67
67
 
68
68
  acquire_ownership :r
69
69
  begin
70
- until remaining.zero?
71
- begin
72
- str = readpartial(remaining)
73
- rescue EOFError
74
- return if length == remaining
75
- return buffer
70
+ if length
71
+ until remaining.zero?
72
+ begin
73
+ str = readpartial(remaining)
74
+ rescue EOFError
75
+ return if length == remaining
76
+ return buffer
77
+ end
78
+
79
+ buffer << str
80
+ remaining -= str.length
81
+ end
82
+ else
83
+ while true
84
+ begin
85
+ buffer << read_nonblock(Socket::SO_RCVBUF)
86
+ rescue Errno::EAGAIN, EOFError
87
+ return buffer
88
+ end
76
89
  end
77
-
78
- buffer << str
79
- remaining -= str.length
80
90
  end
81
91
  ensure
82
92
  release_ownership :r
@@ -68,7 +68,10 @@ module Celluloid
68
68
  response = Resolv::DNS::Message.decode(data)
69
69
 
70
70
  addrs = []
71
- response.each_answer { |name, ttl, value| addrs << value.address }
71
+ # The answer might include IN::CNAME entries so filters them out
72
+ # to include IN::A & IN::AAAA entries only.
73
+ response.each_answer { |name, ttl, value| addrs << (value.respond_to?(:address) ? value.address : nil) }
74
+ addrs.compact!
72
75
 
73
76
  return if addrs.empty?
74
77
  return addrs.first if addrs.size == 1
@@ -19,7 +19,8 @@ module Celluloid
19
19
  @reactor.wakeup unless current_actor && current_actor.mailbox == self
20
20
  rescue IOError
21
21
  raise MailboxError, "dead recipient"
22
- ensure @mutex.unlock
22
+ ensure
23
+ @mutex.unlock rescue nil
23
24
  end
24
25
  nil
25
26
  end
@@ -33,14 +34,15 @@ module Celluloid
33
34
  @reactor.wakeup unless current_actor && current_actor.mailbox == self
34
35
  rescue IOError
35
36
  # Silently fail if messages are sent to dead actors
36
- ensure @mutex.unlock
37
+ ensure
38
+ @mutex.unlock rescue nil
37
39
  end
38
40
  nil
39
41
  end
40
42
 
41
43
  # Receive a message from the Mailbox
42
44
  def receive(timeout = nil, &block)
43
- message = next_message(&block)
45
+ message = next_message(block)
44
46
 
45
47
  until message
46
48
  if timeout
@@ -53,7 +55,7 @@ module Celluloid
53
55
  end
54
56
 
55
57
  @reactor.run_once(wait_interval)
56
- message = next_message(&block)
58
+ message = next_message(block)
57
59
  end
58
60
 
59
61
  message
@@ -61,6 +63,16 @@ module Celluloid
61
63
  shutdown # force shutdown of the mailbox
62
64
  raise MailboxShutdown, "mailbox shutdown called during receive"
63
65
  end
66
+
67
+ # Obtain the next message from the mailbox that matches the given block
68
+ def next_message(block)
69
+ @mutex.lock
70
+ begin
71
+ super(&block)
72
+ ensure
73
+ @mutex.unlock rescue nil
74
+ end
75
+ end
64
76
 
65
77
  # Cleanup any IO objects this Mailbox may be using
66
78
  def shutdown
@@ -1,5 +1,5 @@
1
1
  module Celluloid
2
2
  module IO
3
- VERSION = "0.10.0"
3
+ VERSION = "0.11.0"
4
4
  end
5
5
  end
data/logo.png CHANGED
Binary file
@@ -5,4 +5,22 @@ describe Celluloid::IO::DNSResolver do
5
5
  resolver = Celluloid::IO::DNSResolver.new
6
6
  resolver.resolve("celluloid.io").should == Resolv::IPv4.create("207.97.227.245")
7
7
  end
8
- end
8
+
9
+ it "resolves CNAME responses" do
10
+ resolver = Celluloid::IO::DNSResolver.new
11
+ results = resolver.resolve("www.google.com")
12
+ if results.is_a?(Array)
13
+ results.all? {|i| i.is_a?(Resolv::IPv4) }.should be_true
14
+ else
15
+ results.is_a?(Resolv::IPv4).should be_true
16
+ end
17
+ # www.yahoo.com will be resolved randomly whether multiple or
18
+ # single entry.
19
+ results = resolver.resolve("www.yahoo.com")
20
+ if results.is_a?(Array)
21
+ results.all? {|i| i.is_a?(Resolv::IPv4) }.should be_true
22
+ else
23
+ results.is_a?(Resolv::IPv4).should be_true
24
+ end
25
+ end
26
+ end
@@ -24,6 +24,20 @@ describe Celluloid::IO::TCPSocket do
24
24
  end
25
25
  end
26
26
 
27
+ it "read complete payload when nil size is given to #read" do
28
+ with_connected_sockets do |subject, peer|
29
+ peer << payload
30
+ within_io_actor { subject.read(nil) }.should eq payload
31
+ end
32
+ end
33
+
34
+ it "read complete payload when no size is given to #read" do
35
+ with_connected_sockets do |subject, peer|
36
+ peer << payload
37
+ within_io_actor { subject.read }.should eq payload
38
+ end
39
+ end
40
+
27
41
  it "reads data" do
28
42
  with_connected_sockets do |subject, peer|
29
43
  peer << payload
metadata CHANGED
@@ -1,71 +1,71 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: celluloid-io
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.0
5
- prerelease:
4
+ prerelease:
5
+ version: 0.11.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - Tony Arcieri
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-04-02 00:00:00.000000000 Z
12
+ date: 2012-06-19 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: celluloid
16
- requirement: &70278839545080 !ruby/object:Gem::Requirement
17
- none: false
16
+ version_requirements: &2056 !ruby/object:Gem::Requirement
18
17
  requirements:
19
18
  - - ~>
20
19
  - !ruby/object:Gem::Version
21
- version: 0.10.0
22
- type: :runtime
20
+ version: 0.11.0
21
+ none: false
22
+ requirement: *2056
23
23
  prerelease: false
24
- version_requirements: *70278839545080
24
+ type: :runtime
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: nio4r
27
- requirement: &70278839544320 !ruby/object:Gem::Requirement
28
- none: false
27
+ version_requirements: &2074 !ruby/object:Gem::Requirement
29
28
  requirements:
30
29
  - - ! '>='
31
30
  - !ruby/object:Gem::Version
32
- version: 0.3.1
33
- type: :runtime
31
+ version: 0.4.0
32
+ none: false
33
+ requirement: *2074
34
34
  prerelease: false
35
- version_requirements: *70278839544320
35
+ type: :runtime
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rake
38
- requirement: &70278839543940 !ruby/object:Gem::Requirement
39
- none: false
38
+ version_requirements: &2090 !ruby/object:Gem::Requirement
40
39
  requirements:
41
40
  - - ! '>='
42
41
  - !ruby/object:Gem::Version
43
42
  version: '0'
44
- type: :development
43
+ none: false
44
+ requirement: *2090
45
45
  prerelease: false
46
- version_requirements: *70278839543940
46
+ type: :development
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rspec
49
- requirement: &70278839543480 !ruby/object:Gem::Requirement
50
- none: false
49
+ version_requirements: &2108 !ruby/object:Gem::Requirement
51
50
  requirements:
52
51
  - - ! '>='
53
52
  - !ruby/object:Gem::Version
54
53
  version: '0'
55
- type: :development
54
+ none: false
55
+ requirement: *2108
56
56
  prerelease: false
57
- version_requirements: *70278839543480
57
+ type: :development
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: benchmark_suite
60
- requirement: &70278839543020 !ruby/object:Gem::Requirement
61
- none: false
60
+ version_requirements: &2124 !ruby/object:Gem::Requirement
62
61
  requirements:
63
62
  - - ! '>='
64
63
  - !ruby/object:Gem::Version
65
64
  version: '0'
66
- type: :development
65
+ none: false
66
+ requirement: *2124
67
67
  prerelease: false
68
- version_requirements: *70278839543020
68
+ type: :development
69
69
  description: Evented IO for Celluloid actors
70
70
  email:
71
71
  - tony.arcieri@gmail.com
@@ -82,7 +82,6 @@ files:
82
82
  - README.md
83
83
  - Rakefile
84
84
  - benchmarks/actor.rb
85
- - benchmarks/ring.rb
86
85
  - celluloid-io.gemspec
87
86
  - examples/echo_client.rb
88
87
  - examples/echo_server.rb
@@ -107,29 +106,28 @@ files:
107
106
  - tasks/rspec.task
108
107
  homepage: http://github.com/celluloid/celluloid-io
109
108
  licenses: []
110
- post_install_message:
109
+ post_install_message:
111
110
  rdoc_options: []
112
111
  require_paths:
113
112
  - lib
114
113
  required_ruby_version: !ruby/object:Gem::Requirement
115
- none: false
116
114
  requirements:
117
115
  - - ! '>='
118
116
  - !ruby/object:Gem::Version
119
117
  version: '0'
120
- required_rubygems_version: !ruby/object:Gem::Requirement
121
118
  none: false
119
+ required_rubygems_version: !ruby/object:Gem::Requirement
122
120
  requirements:
123
121
  - - ! '>='
124
122
  - !ruby/object:Gem::Version
125
123
  version: '0'
124
+ none: false
126
125
  requirements: []
127
- rubyforge_project:
128
- rubygems_version: 1.8.17
129
- signing_key:
126
+ rubyforge_project:
127
+ rubygems_version: 1.8.15
128
+ signing_key:
130
129
  specification_version: 3
131
- summary: Celluloid::IO allows you to monitor multiple IO objects within a Celluloid
132
- actor
130
+ summary: Celluloid::IO allows you to monitor multiple IO objects within a Celluloid actor
133
131
  test_files:
134
132
  - spec/celluloid/io/actor_spec.rb
135
133
  - spec/celluloid/io/dns_resolver_spec.rb
@@ -138,3 +136,4 @@ test_files:
138
136
  - spec/celluloid/io/tcp_socket_spec.rb
139
137
  - spec/celluloid/io/udp_socket_spec.rb
140
138
  - spec/spec_helper.rb
139
+ ...
data/benchmarks/ring.rb DELETED
@@ -1,14 +0,0 @@
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