cool.io 1.0.0 → 1.9.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.
Files changed (83) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/test.yaml +54 -0
  3. data/.gitignore +30 -0
  4. data/.rspec +3 -0
  5. data/{CHANGES → CHANGES.md} +175 -79
  6. data/{README.markdown → README.md} +43 -49
  7. data/Rakefile +44 -69
  8. data/appveyor.yml +18 -0
  9. data/cool.io.gemspec +18 -131
  10. data/examples/callbacked_echo_server.rb +24 -0
  11. data/ext/cool.io/buffer.c +781 -0
  12. data/ext/cool.io/cool.io.h +13 -0
  13. data/ext/cool.io/cool.io_ext.c +1 -0
  14. data/ext/cool.io/ev_wrap.h +4 -2
  15. data/ext/cool.io/extconf.rb +27 -16
  16. data/ext/cool.io/iowatcher.c +17 -8
  17. data/ext/cool.io/loop.c +36 -84
  18. data/ext/cool.io/stat_watcher.c +103 -25
  19. data/ext/cool.io/timer_watcher.c +3 -3
  20. data/ext/cool.io/utils.c +5 -0
  21. data/ext/cool.io/watcher.h +1 -1
  22. data/ext/libev/Changes +152 -3
  23. data/ext/libev/LICENSE +2 -1
  24. data/ext/libev/README +8 -8
  25. data/ext/libev/ev.c +1719 -348
  26. data/ext/libev/ev.h +146 -118
  27. data/ext/libev/ev_epoll.c +71 -20
  28. data/ext/libev/ev_kqueue.c +36 -16
  29. data/ext/libev/ev_poll.c +14 -11
  30. data/ext/libev/ev_port.c +43 -18
  31. data/ext/libev/ev_select.c +82 -25
  32. data/ext/libev/ev_vars.h +28 -21
  33. data/ext/libev/ev_win32.c +19 -10
  34. data/ext/libev/ev_wrap.h +166 -152
  35. data/ext/libev/test_libev_win32.c +1 -1
  36. data/gems.rb +9 -0
  37. data/lib/cool.io/async_watcher.rb +1 -1
  38. data/lib/cool.io/custom_require.rb +9 -0
  39. data/lib/cool.io/dns_resolver.rb +30 -22
  40. data/lib/cool.io/dsl.rb +32 -28
  41. data/lib/cool.io/io.rb +55 -35
  42. data/lib/cool.io/iowatcher.rb +1 -1
  43. data/lib/cool.io/listener.rb +35 -17
  44. data/lib/cool.io/loop.rb +17 -25
  45. data/lib/cool.io/meta.rb +6 -5
  46. data/lib/cool.io/server.rb +5 -4
  47. data/lib/cool.io/socket.rb +41 -30
  48. data/lib/cool.io/timer_watcher.rb +1 -1
  49. data/lib/cool.io/version.rb +7 -0
  50. data/lib/cool.io.rb +11 -10
  51. data/lib/coolio.rb +1 -1
  52. data/libev_ruby_gil.diff +175 -0
  53. data/libev_win_select.diff +130 -0
  54. data/spec/async_watcher_spec.rb +5 -5
  55. data/spec/dns_spec.rb +27 -8
  56. data/spec/iobuffer_spec.rb +147 -0
  57. data/spec/spec_helper.rb +15 -1
  58. data/spec/stat_watcher_spec.rb +81 -0
  59. data/spec/tcp_server_spec.rb +225 -0
  60. data/spec/tcp_socket_spec.rb +185 -0
  61. data/spec/timer_watcher_spec.rb +23 -19
  62. data/spec/udp_socket_spec.rb +58 -0
  63. data/spec/unix_listener_spec.rb +8 -8
  64. data/spec/unix_server_spec.rb +10 -8
  65. metadata +109 -112
  66. data/VERSION +0 -1
  67. data/examples/httpclient.rb +0 -38
  68. data/ext/http11_client/.gitignore +0 -5
  69. data/ext/http11_client/LICENSE +0 -31
  70. data/ext/http11_client/ext_help.h +0 -14
  71. data/ext/http11_client/extconf.rb +0 -6
  72. data/ext/http11_client/http11_client.c +0 -300
  73. data/ext/http11_client/http11_parser.c +0 -403
  74. data/ext/http11_client/http11_parser.h +0 -48
  75. data/ext/http11_client/http11_parser.rl +0 -173
  76. data/lib/cool.io/eventmachine.rb +0 -234
  77. data/lib/cool.io/http_client.rb +0 -419
  78. data/lib/rev.rb +0 -4
  79. data/spec/possible_tests/schedules_other_threads.rb +0 -48
  80. data/spec/possible_tests/test_on_resolve_failed.rb +0 -9
  81. data/spec/possible_tests/test_resolves.rb +0 -27
  82. data/spec/possible_tests/test_write_during_resolve.rb +0 -27
  83. data/spec/possible_tests/works_straight.rb +0 -71
data/ext/libev/ev_wrap.h CHANGED
@@ -1,186 +1,200 @@
1
1
  /* DO NOT EDIT, automatically generated by update_ev_wrap */
2
2
  #ifndef EV_WRAP_H
3
3
  #define EV_WRAP_H
4
- #define now_floor ((loop)->now_floor)
5
- #define mn_now ((loop)->mn_now)
6
- #define rtmn_diff ((loop)->rtmn_diff)
7
- #define io_blocktime ((loop)->io_blocktime)
8
- #define timeout_blocktime ((loop)->timeout_blocktime)
9
- #define backend ((loop)->backend)
4
+ #define acquire_cb ((loop)->acquire_cb)
10
5
  #define activecnt ((loop)->activecnt)
11
- #define loop_done ((loop)->loop_done)
6
+ #define anfdmax ((loop)->anfdmax)
7
+ #define anfds ((loop)->anfds)
8
+ #define async_pending ((loop)->async_pending)
9
+ #define asynccnt ((loop)->asynccnt)
10
+ #define asyncmax ((loop)->asyncmax)
11
+ #define asyncs ((loop)->asyncs)
12
+ #define backend ((loop)->backend)
12
13
  #define backend_fd ((loop)->backend_fd)
13
- #define backend_fudge ((loop)->backend_fudge)
14
+ #define backend_mintime ((loop)->backend_mintime)
14
15
  #define backend_modify ((loop)->backend_modify)
15
16
  #define backend_poll ((loop)->backend_poll)
16
- #define anfds ((loop)->anfds)
17
- #define anfdmax ((loop)->anfdmax)
18
- #define pendings ((loop)->pendings)
19
- #define pendingmax ((loop)->pendingmax)
20
- #define pendingcnt ((loop)->pendingcnt)
21
- #define pending_w ((loop)->pending_w)
22
- #define rfeeds ((loop)->rfeeds)
23
- #define rfeedmax ((loop)->rfeedmax)
24
- #define rfeedcnt ((loop)->rfeedcnt)
25
- #define evfd ((loop)->evfd)
26
- #define evpipe ((loop)->evpipe)
27
- #define pipe_w ((loop)->pipe_w)
17
+ #define checkcnt ((loop)->checkcnt)
18
+ #define checkmax ((loop)->checkmax)
19
+ #define checks ((loop)->checks)
20
+ #define cleanupcnt ((loop)->cleanupcnt)
21
+ #define cleanupmax ((loop)->cleanupmax)
22
+ #define cleanups ((loop)->cleanups)
28
23
  #define curpid ((loop)->curpid)
29
- #define postfork ((loop)->postfork)
30
- #define vec_ri ((loop)->vec_ri)
31
- #define vec_ro ((loop)->vec_ro)
32
- #define vec_wi ((loop)->vec_wi)
33
- #define vec_wo ((loop)->vec_wo)
34
- #define vec_eo ((loop)->vec_eo)
35
- #define vec_max ((loop)->vec_max)
36
- #define polls ((loop)->polls)
37
- #define pollmax ((loop)->pollmax)
38
- #define pollcnt ((loop)->pollcnt)
39
- #define pollidxs ((loop)->pollidxs)
40
- #define pollidxmax ((loop)->pollidxmax)
41
- #define epoll_events ((loop)->epoll_events)
24
+ #define epoll_epermcnt ((loop)->epoll_epermcnt)
25
+ #define epoll_epermmax ((loop)->epoll_epermmax)
26
+ #define epoll_eperms ((loop)->epoll_eperms)
42
27
  #define epoll_eventmax ((loop)->epoll_eventmax)
43
- #define kqueue_changes ((loop)->kqueue_changes)
44
- #define kqueue_changemax ((loop)->kqueue_changemax)
45
- #define kqueue_changecnt ((loop)->kqueue_changecnt)
46
- #define kqueue_events ((loop)->kqueue_events)
47
- #define kqueue_eventmax ((loop)->kqueue_eventmax)
48
- #define port_events ((loop)->port_events)
49
- #define port_eventmax ((loop)->port_eventmax)
50
- #define iocp ((loop)->iocp)
51
- #define fdchanges ((loop)->fdchanges)
52
- #define fdchangemax ((loop)->fdchangemax)
28
+ #define epoll_events ((loop)->epoll_events)
29
+ #define evpipe ((loop)->evpipe)
53
30
  #define fdchangecnt ((loop)->fdchangecnt)
54
- #define timers ((loop)->timers)
55
- #define timermax ((loop)->timermax)
56
- #define timercnt ((loop)->timercnt)
57
- #define periodics ((loop)->periodics)
58
- #define periodicmax ((loop)->periodicmax)
59
- #define periodiccnt ((loop)->periodiccnt)
60
- #define idles ((loop)->idles)
61
- #define idlemax ((loop)->idlemax)
62
- #define idlecnt ((loop)->idlecnt)
63
- #define idleall ((loop)->idleall)
64
- #define prepares ((loop)->prepares)
65
- #define preparemax ((loop)->preparemax)
66
- #define preparecnt ((loop)->preparecnt)
67
- #define checks ((loop)->checks)
68
- #define checkmax ((loop)->checkmax)
69
- #define checkcnt ((loop)->checkcnt)
70
- #define forks ((loop)->forks)
71
- #define forkmax ((loop)->forkmax)
31
+ #define fdchangemax ((loop)->fdchangemax)
32
+ #define fdchanges ((loop)->fdchanges)
72
33
  #define forkcnt ((loop)->forkcnt)
73
- #define cleanups ((loop)->cleanups)
74
- #define cleanupmax ((loop)->cleanupmax)
75
- #define cleanupcnt ((loop)->cleanupcnt)
76
- #define async_pending ((loop)->async_pending)
77
- #define asyncs ((loop)->asyncs)
78
- #define asyncmax ((loop)->asyncmax)
79
- #define asynccnt ((loop)->asynccnt)
80
- #define fs_fd ((loop)->fs_fd)
81
- #define fs_w ((loop)->fs_w)
34
+ #define forkmax ((loop)->forkmax)
35
+ #define forks ((loop)->forks)
82
36
  #define fs_2625 ((loop)->fs_2625)
37
+ #define fs_fd ((loop)->fs_fd)
83
38
  #define fs_hash ((loop)->fs_hash)
39
+ #define fs_w ((loop)->fs_w)
40
+ #define idleall ((loop)->idleall)
41
+ #define idlecnt ((loop)->idlecnt)
42
+ #define idlemax ((loop)->idlemax)
43
+ #define idles ((loop)->idles)
44
+ #define invoke_cb ((loop)->invoke_cb)
45
+ #define io_blocktime ((loop)->io_blocktime)
46
+ #define iocp ((loop)->iocp)
47
+ #define kqueue_changecnt ((loop)->kqueue_changecnt)
48
+ #define kqueue_changemax ((loop)->kqueue_changemax)
49
+ #define kqueue_changes ((loop)->kqueue_changes)
50
+ #define kqueue_eventmax ((loop)->kqueue_eventmax)
51
+ #define kqueue_events ((loop)->kqueue_events)
52
+ #define kqueue_fd_pid ((loop)->kqueue_fd_pid)
53
+ #define loop_count ((loop)->loop_count)
54
+ #define loop_depth ((loop)->loop_depth)
55
+ #define loop_done ((loop)->loop_done)
56
+ #define mn_now ((loop)->mn_now)
57
+ #define now_floor ((loop)->now_floor)
58
+ #define origflags ((loop)->origflags)
59
+ #define pending_w ((loop)->pending_w)
60
+ #define pendingcnt ((loop)->pendingcnt)
61
+ #define pendingmax ((loop)->pendingmax)
62
+ #define pendingpri ((loop)->pendingpri)
63
+ #define pendings ((loop)->pendings)
64
+ #define periodiccnt ((loop)->periodiccnt)
65
+ #define periodicmax ((loop)->periodicmax)
66
+ #define periodics ((loop)->periodics)
67
+ #define pipe_w ((loop)->pipe_w)
68
+ #define pipe_write_skipped ((loop)->pipe_write_skipped)
69
+ #define pipe_write_wanted ((loop)->pipe_write_wanted)
70
+ #define pollcnt ((loop)->pollcnt)
71
+ #define pollidxmax ((loop)->pollidxmax)
72
+ #define pollidxs ((loop)->pollidxs)
73
+ #define pollmax ((loop)->pollmax)
74
+ #define polls ((loop)->polls)
75
+ #define port_eventmax ((loop)->port_eventmax)
76
+ #define port_events ((loop)->port_events)
77
+ #define postfork ((loop)->postfork)
78
+ #define preparecnt ((loop)->preparecnt)
79
+ #define preparemax ((loop)->preparemax)
80
+ #define prepares ((loop)->prepares)
81
+ #define release_cb ((loop)->release_cb)
82
+ #define rfeedcnt ((loop)->rfeedcnt)
83
+ #define rfeedmax ((loop)->rfeedmax)
84
+ #define rfeeds ((loop)->rfeeds)
85
+ #define rtmn_diff ((loop)->rtmn_diff)
84
86
  #define sig_pending ((loop)->sig_pending)
85
87
  #define sigfd ((loop)->sigfd)
86
- #define sigfd_w ((loop)->sigfd_w)
87
88
  #define sigfd_set ((loop)->sigfd_set)
88
- #define loop_count ((loop)->loop_count)
89
- #define loop_depth ((loop)->loop_depth)
89
+ #define sigfd_w ((loop)->sigfd_w)
90
+ #define timeout_blocktime ((loop)->timeout_blocktime)
91
+ #define timercnt ((loop)->timercnt)
92
+ #define timermax ((loop)->timermax)
93
+ #define timers ((loop)->timers)
90
94
  #define userdata ((loop)->userdata)
91
- #define release_cb ((loop)->release_cb)
92
- #define acquire_cb ((loop)->acquire_cb)
93
- #define invoke_cb ((loop)->invoke_cb)
95
+ #define vec_eo ((loop)->vec_eo)
96
+ #define vec_max ((loop)->vec_max)
97
+ #define vec_ri ((loop)->vec_ri)
98
+ #define vec_ro ((loop)->vec_ro)
99
+ #define vec_wi ((loop)->vec_wi)
100
+ #define vec_wo ((loop)->vec_wo)
94
101
  #else
95
102
  #undef EV_WRAP_H
96
- #undef now_floor
97
- #undef mn_now
98
- #undef rtmn_diff
99
- #undef io_blocktime
100
- #undef timeout_blocktime
101
- #undef backend
103
+ #undef acquire_cb
102
104
  #undef activecnt
103
- #undef loop_done
105
+ #undef anfdmax
106
+ #undef anfds
107
+ #undef async_pending
108
+ #undef asynccnt
109
+ #undef asyncmax
110
+ #undef asyncs
111
+ #undef backend
104
112
  #undef backend_fd
105
- #undef backend_fudge
113
+ #undef backend_mintime
106
114
  #undef backend_modify
107
115
  #undef backend_poll
108
- #undef anfds
109
- #undef anfdmax
110
- #undef pendings
111
- #undef pendingmax
112
- #undef pendingcnt
113
- #undef pending_w
114
- #undef rfeeds
115
- #undef rfeedmax
116
- #undef rfeedcnt
117
- #undef evfd
118
- #undef evpipe
119
- #undef pipe_w
116
+ #undef checkcnt
117
+ #undef checkmax
118
+ #undef checks
119
+ #undef cleanupcnt
120
+ #undef cleanupmax
121
+ #undef cleanups
120
122
  #undef curpid
121
- #undef postfork
122
- #undef vec_ri
123
- #undef vec_ro
124
- #undef vec_wi
125
- #undef vec_wo
126
- #undef vec_eo
127
- #undef vec_max
128
- #undef polls
129
- #undef pollmax
130
- #undef pollcnt
131
- #undef pollidxs
132
- #undef pollidxmax
133
- #undef epoll_events
123
+ #undef epoll_epermcnt
124
+ #undef epoll_epermmax
125
+ #undef epoll_eperms
134
126
  #undef epoll_eventmax
135
- #undef kqueue_changes
136
- #undef kqueue_changemax
137
- #undef kqueue_changecnt
138
- #undef kqueue_events
139
- #undef kqueue_eventmax
140
- #undef port_events
141
- #undef port_eventmax
142
- #undef iocp
143
- #undef fdchanges
144
- #undef fdchangemax
127
+ #undef epoll_events
128
+ #undef evpipe
145
129
  #undef fdchangecnt
146
- #undef timers
147
- #undef timermax
148
- #undef timercnt
149
- #undef periodics
150
- #undef periodicmax
151
- #undef periodiccnt
152
- #undef idles
153
- #undef idlemax
154
- #undef idlecnt
155
- #undef idleall
156
- #undef prepares
157
- #undef preparemax
158
- #undef preparecnt
159
- #undef checks
160
- #undef checkmax
161
- #undef checkcnt
162
- #undef forks
163
- #undef forkmax
130
+ #undef fdchangemax
131
+ #undef fdchanges
164
132
  #undef forkcnt
165
- #undef cleanups
166
- #undef cleanupmax
167
- #undef cleanupcnt
168
- #undef async_pending
169
- #undef asyncs
170
- #undef asyncmax
171
- #undef asynccnt
172
- #undef fs_fd
173
- #undef fs_w
133
+ #undef forkmax
134
+ #undef forks
174
135
  #undef fs_2625
136
+ #undef fs_fd
175
137
  #undef fs_hash
138
+ #undef fs_w
139
+ #undef idleall
140
+ #undef idlecnt
141
+ #undef idlemax
142
+ #undef idles
143
+ #undef invoke_cb
144
+ #undef io_blocktime
145
+ #undef iocp
146
+ #undef kqueue_changecnt
147
+ #undef kqueue_changemax
148
+ #undef kqueue_changes
149
+ #undef kqueue_eventmax
150
+ #undef kqueue_events
151
+ #undef kqueue_fd_pid
152
+ #undef loop_count
153
+ #undef loop_depth
154
+ #undef loop_done
155
+ #undef mn_now
156
+ #undef now_floor
157
+ #undef origflags
158
+ #undef pending_w
159
+ #undef pendingcnt
160
+ #undef pendingmax
161
+ #undef pendingpri
162
+ #undef pendings
163
+ #undef periodiccnt
164
+ #undef periodicmax
165
+ #undef periodics
166
+ #undef pipe_w
167
+ #undef pipe_write_skipped
168
+ #undef pipe_write_wanted
169
+ #undef pollcnt
170
+ #undef pollidxmax
171
+ #undef pollidxs
172
+ #undef pollmax
173
+ #undef polls
174
+ #undef port_eventmax
175
+ #undef port_events
176
+ #undef postfork
177
+ #undef preparecnt
178
+ #undef preparemax
179
+ #undef prepares
180
+ #undef release_cb
181
+ #undef rfeedcnt
182
+ #undef rfeedmax
183
+ #undef rfeeds
184
+ #undef rtmn_diff
176
185
  #undef sig_pending
177
186
  #undef sigfd
178
- #undef sigfd_w
179
187
  #undef sigfd_set
180
- #undef loop_count
181
- #undef loop_depth
188
+ #undef sigfd_w
189
+ #undef timeout_blocktime
190
+ #undef timercnt
191
+ #undef timermax
192
+ #undef timers
182
193
  #undef userdata
183
- #undef release_cb
184
- #undef acquire_cb
185
- #undef invoke_cb
194
+ #undef vec_eo
195
+ #undef vec_max
196
+ #undef vec_ri
197
+ #undef vec_ro
198
+ #undef vec_wi
199
+ #undef vec_wo
186
200
  #endif
@@ -32,7 +32,7 @@
32
32
  }
33
33
 
34
34
 
35
-
35
+ #define FD_SETSIZE 1024
36
36
  #include <winsock.h>
37
37
 
38
38
  #include <stdlib.h>
data/gems.rb ADDED
@@ -0,0 +1,9 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in cool.io.gemspec
4
+ gemspec
5
+
6
+ group :maintenance, optional: true do
7
+ gem "bake-gem"
8
+ gem "bake-modernize"
9
+ end
@@ -19,7 +19,7 @@ module Coolio
19
19
  # merely signals an event has occurred for each byte written.
20
20
  @writer.write "\0"
21
21
  end
22
-
22
+
23
23
  # Called whenever a signal is received
24
24
  def on_signal; end
25
25
  event_callback :on_signal
@@ -0,0 +1,9 @@
1
+ def cool_require(gem)
2
+ begin
3
+ m = /(\d+.\d+)/.match(RUBY_VERSION)
4
+ ver = m[1]
5
+ require "#{ver}/#{gem}.so"
6
+ rescue LoadError
7
+ require gem
8
+ end
9
+ end
@@ -9,7 +9,7 @@
9
9
  # as best I could with extremely limited knowledge of the DNS format. There's
10
10
  # obviously a ton of stuff it doesn't support (like IPv6 and TCP).
11
11
  #
12
- # If you do know what you're doing with DNS, feel free to improve this!
12
+ # If you do know what you're doing with DNS, feel free to improve this!
13
13
  # A good starting point my be this EventMachine Net::DNS-based asynchronous
14
14
  # resolver:
15
15
  #
@@ -17,6 +17,8 @@
17
17
  #
18
18
  #++
19
19
 
20
+ require 'resolv'
21
+
20
22
  module Coolio
21
23
  # A non-blocking DNS resolver. It provides interfaces for querying both
22
24
  # /etc/hosts and nameserves listed in /etc/resolv.conf, or nameservers of
@@ -31,23 +33,30 @@ module Coolio
31
33
  # again.
32
34
  class DNSResolver < IOWatcher
33
35
  #--
34
- # TODO check if it's caching right
35
- RESOLV_CONF = '/etc/resolv.conf'
36
- HOSTS = '/etc/hosts'
37
36
  DNS_PORT = 53
38
37
  DATAGRAM_SIZE = 512
39
38
  TIMEOUT = 3 # Retry timeout for each datagram sent
40
39
  RETRIES = 4 # Number of retries to attempt
41
40
  # so currently total is 12s before it will err due to timeouts
42
41
  # if it errs due to inability to reach the DNS server [Errno::EHOSTUNREACH], same
43
-
44
42
  # Query /etc/hosts (or the specified hostfile) for the given host
45
- def self.hosts(host, hostfile = HOSTS)
43
+ def self.hosts(host, hostfile = Resolv::Hosts::DefaultFileName)
46
44
  hosts = {}
47
- File.open(hostfile).each_line do |host_entry|
48
- entries = host_entry.gsub(/#.*$/, '').gsub(/\s+/, ' ').split(' ')
49
- addr = entries.shift
50
- entries.each { |e| hosts[e] ||= addr }
45
+ File.open(hostfile) do |f|
46
+ f.each_line do |host_entry|
47
+ entries = host_entry.gsub(/#.*$/, '').gsub(/\s+/, ' ').split(' ')
48
+ addr = entries.shift
49
+ entries.each { |e| hosts[e] ||= addr }
50
+ end
51
+ end
52
+ unless hosts.key?("localhost")
53
+ # On Windows, there is a case that hosts file doesn't have entry by default
54
+ # and preferred IPv4/IPv6 behavior may be changed by registry key [1], so
55
+ # "localhost" should be resolved by getaddrinfo.
56
+ # (first[3] means preferred resolved IP address ::1 or 127.0.0.1)
57
+ # [1] https://docs.microsoft.com/en-us/troubleshoot/windows-server/networking/configure-ipv6-in-windows
58
+ require "socket"
59
+ hosts["localhost"] = ::Socket.getaddrinfo("localhost", nil).first[3]
51
60
  end
52
61
 
53
62
  hosts[host]
@@ -59,16 +68,16 @@ module Coolio
59
68
  # use nameservers listed in /etc/resolv.conf
60
69
  def initialize(hostname, *nameservers)
61
70
  if nameservers.empty?
62
- nameservers = File.read(RESOLV_CONF).scan(/^\s*nameserver\s+([0-9.:]+)/).flatten # TODO could optimize this to just read once
63
- raise RuntimeError, "no nameservers found in #{RESOLV_CONF}" if nameservers.empty? # TODO just call resolve_failed, not raise [also handle Errno::ENOENT)]
71
+ nameservers = Resolv::DNS::Config.default_config_hash[:nameserver]
72
+ raise RuntimeError, "no nameservers found" if nameservers.empty? # TODO just call resolve_failed, not raise [also handle Errno::ENOENT)]
64
73
  end
65
74
 
66
75
  @nameservers = nameservers
67
76
  @question = request_question hostname
68
-
77
+
69
78
  @socket = UDPSocket.new
70
79
  @timer = Timeout.new(self)
71
-
80
+
72
81
  super(@socket)
73
82
  end
74
83
 
@@ -106,11 +115,10 @@ module Coolio
106
115
  def send_request
107
116
  nameserver = @nameservers.shift
108
117
  @nameservers << nameserver # rotate them
109
- @socket.connect @nameservers.first, DNS_PORT
110
118
  begin
111
- @socket.send request_message, 0
119
+ @socket.send request_message, 0, @nameservers.first, DNS_PORT
112
120
  rescue Errno::EHOSTUNREACH # TODO figure out why it has to be wrapper here, when the other wrapper should be wrapping this one!
113
- end
121
+ end
114
122
  end
115
123
 
116
124
  # Called by the subclass when the DNS response is available
@@ -120,7 +128,7 @@ module Coolio
120
128
  datagram = @socket.recvfrom_nonblock(DATAGRAM_SIZE).first
121
129
  rescue Errno::ECONNREFUSED
122
130
  end
123
-
131
+
124
132
  address = response_address datagram rescue nil
125
133
  address ? on_success(address) : on_failure
126
134
  detach
@@ -128,7 +136,7 @@ module Coolio
128
136
 
129
137
  def request_question(hostname)
130
138
  raise ArgumentError, "hostname cannot be nil" if hostname.nil?
131
-
139
+
132
140
  # Query name
133
141
  message = hostname.split('.').map { |s| [s.size].pack('C') << s }.join + "\0"
134
142
 
@@ -149,7 +157,7 @@ module Coolio
149
157
  qdcount = 1
150
158
 
151
159
  # No answer, authority, or additional records
152
- ancount = nscount = arcount = 0
160
+ ancount = nscount = arcount = 0
153
161
 
154
162
  message << [qdcount, ancount, nscount, arcount].pack('nnnn')
155
163
  message << @question
@@ -169,7 +177,7 @@ module Coolio
169
177
  return unless rcode == 0
170
178
 
171
179
  # Extract the question and answer counts
172
- qdcount, ancount = message[4..7].unpack('nn').map { |n| n.to_i }
180
+ qdcount, _ancount = message[4..7].unpack('nn').map { |n| n.to_i }
173
181
 
174
182
  # We only asked one question
175
183
  return unless qdcount == 1
@@ -210,7 +218,7 @@ module Coolio
210
218
  return @resolver.__send__(:send_request)
211
219
  rescue Errno::EHOSTUNREACH # if the DNS is toast try again after the timeout occurs again
212
220
  return nil
213
- end
221
+ end
214
222
  end
215
223
  @resolver.__send__(:on_timeout)
216
224
  @resolver.detach
data/lib/cool.io/dsl.rb CHANGED
@@ -7,112 +7,112 @@
7
7
  module Coolio
8
8
  # A module we stash all the connections defined by the DSL under
9
9
  module Connections; end
10
-
10
+
11
11
  # A DSL for defining Cool.io connection types and servers
12
12
  module DSL
13
13
  # Define all methods on the metaclass
14
14
  module_function
15
-
15
+
16
16
  # Run the default Cool.io event loop
17
17
  def run
18
18
  Cool.io::Loop.default.run
19
19
  end
20
-
20
+
21
21
  # Connect to the given host and port using the given connection class
22
22
  def connect(host, port, connection_name = nil, *initializer_args, &block)
23
23
  if block_given?
24
24
  initializer_args.unshift connection_name if connection_name
25
-
25
+
26
26
  klass = Class.new Cool.io::TCPSocket
27
27
  connection_builder = ConnectionBuilder.new klass
28
- connection_builder.instance_eval &block
28
+ connection_builder.instance_eval(&block)
29
29
  else
30
30
  raise ArgumentError, "no connection name or block given" unless connection_name
31
31
  klass = self[connection_name]
32
32
  end
33
-
33
+
34
34
  client = klass.connect host, port, *initializer_args
35
35
  client.attach Cool.io::Loop.default
36
36
  client
37
37
  end
38
-
38
+
39
39
  # Create a new Cool.io::TCPServer
40
40
  def server(host, port, connection_name = nil, *initializer_args, &block)
41
41
  if block_given?
42
42
  initializer_args.unshift connection_name if connection_name
43
-
43
+
44
44
  klass = Class.new Cool.io::TCPSocket
45
45
  connection_builder = ConnectionBuilder.new klass
46
- connection_builder.instance_eval &block
46
+ connection_builder.instance_eval(&block)
47
47
  else
48
48
  raise ArgumentError, "no connection name or block given" unless connection_name
49
49
  klass = self[connection_name]
50
50
  end
51
-
51
+
52
52
  server = Cool.io::TCPServer.new host, port, klass, *initializer_args
53
53
  server.attach Cool.io::Loop.default
54
54
  server
55
55
  end
56
-
56
+
57
57
  # Create a new Cool.io::TCPSocket class
58
58
  def connection(name, &block)
59
59
  # Camelize class name
60
60
  class_name = name.to_s.split('_').map { |s| s.capitalize }.join
61
-
61
+
62
62
  connection = Class.new Cool.io::TCPSocket
63
63
  connection_builder = ConnectionBuilder.new connection
64
- connection_builder.instance_eval &block
65
-
64
+ connection_builder.instance_eval(&block)
65
+
66
66
  Coolio::Connections.const_set class_name, connection
67
67
  end
68
-
68
+
69
69
  # Look up a connection class by its name
70
70
  def [](connection_name)
71
71
  class_name = connection_name.to_s.split('_').map { |s| s.capitalize }.join
72
-
72
+
73
73
  begin
74
74
  Coolio::Connections.const_get class_name
75
75
  rescue NameError
76
76
  raise NameError, "No connection type registered for #{connection_name.inspect}"
77
77
  end
78
78
  end
79
-
79
+
80
80
  # Builder for Cool.io::TCPSocket classes
81
81
  class ConnectionBuilder
82
82
  def initialize(klass)
83
83
  @klass = klass
84
84
  end
85
-
85
+
86
86
  # Declare an initialize function
87
87
  def initializer(&action)
88
88
  @klass.send :define_method, :initialize, &action
89
89
  end
90
-
90
+
91
91
  # Declare the on_connect callback
92
92
  def on_connect(&action)
93
93
  @klass.send :define_method, :on_connect, &action
94
94
  end
95
-
95
+
96
96
  # Declare a callback fired if we failed to connect
97
97
  def on_connect_failed(&action)
98
98
  @klass.send :define_method, :on_connect_failed, &action
99
99
  end
100
-
100
+
101
101
  # Declare a callback fired if DNS resolution failed
102
102
  def on_resolve_failed(&action)
103
103
  @klass.send :define_method, :on_resolve_failed, &action
104
104
  end
105
-
105
+
106
106
  # Declare the on_close callback
107
107
  def on_close(&action)
108
108
  @klass.send :define_method, :on_close, &action
109
109
  end
110
-
110
+
111
111
  # Declare the on_read callback
112
112
  def on_read(&action)
113
113
  @klass.send :define_method, :on_read, &action
114
114
  end
115
-
115
+
116
116
  # Declare the on_write_complete callback
117
117
  def on_write_complete(&action)
118
118
  @klass.send :define_method, :on_write_complete, &action
@@ -124,12 +124,16 @@ end
124
124
  # The Cool module containing all our coolness
125
125
  module Cool
126
126
  module Coolness
127
- def cool; Cool::IOThunk; end
127
+ def cool
128
+ Cool::IOThunk
129
+ end
128
130
  end
129
-
131
+
130
132
  module IOThunk
131
- def self.io; Coolio::DSL; end
133
+ def self.io
134
+ Coolio::DSL
135
+ end
132
136
  end
133
137
  end
134
138
 
135
- extend Cool::Coolness
139
+ extend Cool::Coolness