celluloid-io 0.16.0.pre → 0.16.0.pre2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8ef8df712ab13d7a2adca88bc42781b256074996
4
- data.tar.gz: edb9143049e62e5484f17ea870539a55af137ec7
3
+ metadata.gz: d2a7a8f3f757ee68efb8e2b599d2fb5d64ef17df
4
+ data.tar.gz: 30658a13260ae50f648c61faae35bfb157d84fb2
5
5
  SHA512:
6
- metadata.gz: f5965bae29ff210224fd7293f22a209e8582bd2c25bc2abbd83753609d473b90b910bc23b965ae5f945851898e113ae06bf31112f6525a3742e1ff3655ac7b40
7
- data.tar.gz: 93eee2a93b600f5e5a9851e6678c22049dd5dc2b844440bb68fb6ade354287158e6aeba5e78b136317856ac83b162fe195b65ea2c9da57d56b4f2c2721838b26
6
+ metadata.gz: 5a49e8683143d29b0ed3647ae1f65ec7c5c30272de50f45476d2e2204bc9b5f91074024939d2cce6971f650f0b029debf0417d01ded1d34e6a85812dd764bc38
7
+ data.tar.gz: f1f529f48d7c559721ad32a4f857bb35e04041892b021cdbd3578f2a55a87e8ba1ebb7960616b0bb2dc02bf0f24bab5ba40fe8dbc6578b6add2688385f395945
data/.rspec CHANGED
@@ -1,4 +1,5 @@
1
- --color
2
- --format documentation
1
+ --color
2
+ --format documentation
3
3
  --backtrace
4
- --default_path spec
4
+ --order random
5
+ --warnings
data/.travis.yml CHANGED
@@ -2,18 +2,18 @@ script: rake ci
2
2
  rvm:
3
3
  - 1.9.3
4
4
  - 2.0.0
5
- - 2.1.0
5
+ - 2.1.1
6
6
  - ruby-head
7
7
  - jruby
8
8
  - jruby-head
9
- - rbx
9
+ - rbx-2
10
10
 
11
11
  matrix:
12
12
  allow_failures:
13
13
  - rvm: ruby-head
14
14
  - rvm: jruby
15
15
  - rvm: jruby-head
16
- - rvm: rbx
16
+ - rvm: rbx-2
17
17
 
18
18
  notifications:
19
19
  irc: "irc.freenode.org#celluloid"
data/CHANGES.md CHANGED
@@ -1,5 +1,7 @@
1
- HEAD
2
- ----
1
+ 0.16.0.pre2 (2014-06-22)
2
+ ------------------------
3
+ * Fix bug handling simultaneous read/write interests
4
+ * Use Resolv::DNS::Config to obtain nameservers
3
5
  * Celluloid::IO.copy_stream support (uses a background thread)
4
6
 
5
7
  0.15.0 (2013-09-04)
@@ -1,11 +1,13 @@
1
+ require 'ipaddr'
1
2
  require 'resolv'
2
3
 
3
4
  module Celluloid
4
5
  module IO
5
6
  # Asynchronous DNS resolver using Celluloid::IO::UDPSocket
6
7
  class DNSResolver
7
- RESOLV_CONF = '/etc/resolv.conf'
8
- DNS_PORT = 53
8
+ # Maximum UDP packet we'll accept
9
+ MAX_PACKET_SIZE = 512
10
+ DNS_PORT = 53
9
11
 
10
12
  @mutex = Mutex.new
11
13
  @identifier = 1
@@ -14,19 +16,18 @@ module Celluloid
14
16
  @mutex.synchronize { @identifier = (@identifier + 1) & 0xFFFF }
15
17
  end
16
18
 
17
- def self.nameservers(config = RESOLV_CONF)
18
- File.read(config).scan(/^\s*nameserver\s+([0-9.:]+)/).flatten
19
+ def self.nameservers
20
+ Resolv::DNS::Config.default_config_hash[:nameserver]
19
21
  end
20
22
 
21
23
  def initialize
22
24
  @nameservers = self.class.nameservers
23
25
 
24
- # TODO: fall back on other nameservers if the first one is unavailable
25
- @server = @nameservers.first
26
+ @server = IPAddr.new(@nameservers.sample)
26
27
 
27
28
  # The non-blocking secret sauce is here, as this is actually a
28
29
  # Celluloid::IO::UDPSocket
29
- @socket = UDPSocket.new
30
+ @socket = UDPSocket.new(@server.family)
30
31
  end
31
32
 
32
33
  def resolve(hostname)
@@ -38,8 +39,8 @@ module Celluloid
38
39
  end
39
40
 
40
41
  query = build_query(hostname)
41
- @socket.send query.encode, 0, @server, DNS_PORT
42
- data, _ = @socket.recvfrom(512)
42
+ @socket.send query.encode, 0, @server.to_s, DNS_PORT
43
+ data, _ = @socket.recvfrom(MAX_PACKET_SIZE)
43
44
  response = Resolv::DNS::Message.decode(data)
44
45
 
45
46
  addrs = []
@@ -14,20 +14,25 @@ module Celluloid
14
14
 
15
15
  def initialize
16
16
  @selector = NIO::Selector.new
17
+ @monitors = {}
17
18
  end
18
19
 
19
20
  # Wait for the given IO object to become readable
20
21
  def wait_readable(io)
21
- wait io, :r
22
+ wait io do |monitor|
23
+ monitor.wait_readable
24
+ end
22
25
  end
23
26
 
24
27
  # Wait for the given IO object to become writable
25
28
  def wait_writable(io)
26
- wait io, :w
29
+ wait io do |monitor|
30
+ monitor.wait_writable
31
+ end
27
32
  end
28
33
 
29
34
  # Wait for the given IO operation to complete
30
- def wait(io, set)
35
+ def wait(io)
31
36
  # zomg ugly type conversion :(
32
37
  unless io.is_a?(::IO) or io.is_a?(OpenSSL::SSL::SSLSocket)
33
38
  if io.respond_to? :to_io
@@ -39,21 +44,89 @@ module Celluloid
39
44
  raise TypeError, "can't convert #{io.class} into IO" unless io.is_a?(::IO)
40
45
  end
41
46
 
42
- monitor = @selector.register(io, set)
43
- monitor.value = Task.current
44
- Task.suspend :iowait
47
+ unless monitor = @monitors[io]
48
+ monitor = Monitor.new(@selector, io)
49
+ @monitors[io] = monitor
50
+ end
51
+
52
+ yield monitor
45
53
  end
46
54
 
47
55
  # Run the reactor, waiting for events or wakeup signal
48
56
  def run_once(timeout = nil)
49
57
  @selector.select(timeout) do |monitor|
50
- task = monitor.value
51
- monitor.close
58
+ monitor.value.resume
59
+ end
60
+ end
61
+
62
+ class Monitor
63
+ def initialize(selector, io)
64
+ @selector = selector
65
+ @io = io
66
+ @interests = {}
67
+ end
68
+
69
+ def wait_readable
70
+ wait :r
71
+ end
72
+
73
+ def wait_writable
74
+ wait :w
75
+ end
76
+
77
+ def wait(interest)
78
+ raise "Already waiting for #{interest.inspect}" if @interests.include?(interest)
79
+ @interests[interest] = Task.current
80
+ reregister
81
+ Task.suspend :iowait
82
+ end
83
+
84
+ def reregister
85
+ if @monitor
86
+ @monitor.close
87
+ @monitor = nil
88
+ end
89
+
90
+ if interests_symbol
91
+ @monitor = @selector.register(@io, interests_symbol)
92
+ @monitor.value = self
93
+ end
94
+ end
95
+
96
+ def interests_symbol
97
+ case @interests.keys
98
+ when [:r]
99
+ :r
100
+ when [:w]
101
+ :w
102
+ when [:r, :w]
103
+ :rw
104
+ end
105
+ end
106
+
107
+ def resume
108
+ raise "No monitor" unless @monitor
109
+
110
+ if @monitor.readable?
111
+ resume_for :r
112
+ end
113
+
114
+ if @monitor.writable?
115
+ resume_for :w
116
+ end
117
+
118
+ reregister
119
+ end
120
+
121
+ def resume_for(interest)
122
+ task = @interests.delete(interest)
52
123
 
53
- if task.running?
54
- task.resume
55
- else
56
- Logger.warn("reactor attempted to resume a dead task")
124
+ if task
125
+ if task.running?
126
+ task.resume
127
+ else
128
+ raise "reactor attempted to resume a dead task"
129
+ end
57
130
  end
58
131
  end
59
132
  end
@@ -8,7 +8,7 @@ module Celluloid
8
8
  extend Forwardable
9
9
 
10
10
  def_delegators :@socket, :read_nonblock, :write_nonblock, :close, :close_read, :close_write, :closed?
11
- def_delegators :@socket, :addr, :peeraddr, :setsockopt
11
+ def_delegators :@socket, :addr, :peeraddr, :setsockopt, :getsockname
12
12
 
13
13
  # Open a TCP socket, yielding it to the given block and closing it
14
14
  # automatically when done (if a block is given)
@@ -1,5 +1,5 @@
1
1
  module Celluloid
2
2
  module IO
3
- VERSION = "0.16.0.pre"
3
+ VERSION = "0.16.0.pre2"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: celluloid-io
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.16.0.pre
4
+ version: 0.16.0.pre2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tony Arcieri
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-03-29 00:00:00.000000000 Z
11
+ date: 2014-06-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: celluloid
@@ -184,7 +184,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
184
184
  version: 1.3.1
185
185
  requirements: []
186
186
  rubyforge_project:
187
- rubygems_version: 2.2.0
187
+ rubygems_version: 2.2.2
188
188
  signing_key:
189
189
  specification_version: 4
190
190
  summary: Celluloid::IO allows you to monitor multiple IO objects within a Celluloid
@@ -206,3 +206,4 @@ test_files:
206
206
  - spec/fixtures/server.crt
207
207
  - spec/fixtures/server.key
208
208
  - spec/spec_helper.rb
209
+ has_rdoc: