cool.io 1.7.0 → 1.8.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.
- checksums.yaml +4 -4
- data/.github/workflows/test.yaml +51 -0
- data/CHANGES.md +5 -0
- data/README.md +43 -40
- data/Rakefile +1 -1
- data/ext/cool.io/extconf.rb +1 -0
- data/ext/cool.io/iowatcher.c +11 -6
- data/ext/iobuffer/extconf.rb +1 -0
- data/ext/iobuffer/iobuffer.c +14 -4
- data/ext/libev/ev.c +1 -1
- data/lib/cool.io/dns_resolver.rb +9 -0
- data/lib/cool.io/version.rb +1 -1
- data/spec/dns_spec.rb +15 -0
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bc38746b7a17648d787378a1a186e213cc2b5470d0158a282d0a49653368557e
|
4
|
+
data.tar.gz: 192da5f1cbdf25ed7c242f5096ab9339287eafefc709226d625e78741bdd28b6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cf443a3b3105db121df46f9066160f392a238d989a901a4eee2fcf2797a404784db51e97478188a191603d4869044b160ec287934cc5efc603ce822e56413aef
|
7
|
+
data.tar.gz: d8c4ebce45323df6b46cc36c20a16c30c041643021b2f75e9823f6df2d19b78793256cc084c49cb666c3cc9a6a8268f3cfe3bb0d10e8874d26d74cf86a966815
|
@@ -0,0 +1,51 @@
|
|
1
|
+
name: Test
|
2
|
+
|
3
|
+
on: [push, pull_request]
|
4
|
+
|
5
|
+
permissions:
|
6
|
+
contents: read
|
7
|
+
|
8
|
+
env:
|
9
|
+
CONSOLE_OUTPUT: XTerm
|
10
|
+
|
11
|
+
jobs:
|
12
|
+
test:
|
13
|
+
name: ${{matrix.ruby}} on ${{matrix.os}}
|
14
|
+
runs-on: ${{matrix.os}}-latest
|
15
|
+
continue-on-error: ${{matrix.experimental}}
|
16
|
+
|
17
|
+
strategy:
|
18
|
+
matrix:
|
19
|
+
os:
|
20
|
+
- ubuntu
|
21
|
+
- macos
|
22
|
+
|
23
|
+
ruby:
|
24
|
+
- "3.0"
|
25
|
+
- "3.1"
|
26
|
+
- "3.2"
|
27
|
+
- "head"
|
28
|
+
|
29
|
+
experimental: [false]
|
30
|
+
|
31
|
+
# include:
|
32
|
+
# - os: ubuntu
|
33
|
+
# ruby: truffleruby
|
34
|
+
# experimental: true
|
35
|
+
# - os: ubuntu
|
36
|
+
# ruby: jruby
|
37
|
+
# experimental: true
|
38
|
+
# - os: ubuntu
|
39
|
+
# ruby: head
|
40
|
+
# experimental: true
|
41
|
+
|
42
|
+
steps:
|
43
|
+
- uses: actions/checkout@v3
|
44
|
+
- uses: ruby/setup-ruby@v1
|
45
|
+
with:
|
46
|
+
ruby-version: ${{matrix.ruby}}
|
47
|
+
bundler-cache: true
|
48
|
+
|
49
|
+
- name: Run tests
|
50
|
+
timeout-minutes: 2
|
51
|
+
run: bundle exec rake
|
data/CHANGES.md
CHANGED
data/README.md
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
Cool.io
|
2
2
|
=======
|
3
3
|
|
4
|
-
### If you are interested in Celluloid based IO framework, please check out [Celluloid::IO](http://github.com/celluloid/celluloid-io)
|
5
|
-
|
6
4
|
Cool.io is an event library for Ruby, built on the libev event library which
|
7
5
|
provides a cross-platform interface to high performance system calls . This
|
8
6
|
includes the epoll system call for Linux, the kqueue system call for BSDs and
|
@@ -14,8 +12,9 @@ applications.
|
|
14
12
|
|
15
13
|
You can include Cool.io in your programs with:
|
16
14
|
|
17
|
-
|
18
|
-
|
15
|
+
```ruby
|
16
|
+
require 'cool.io'
|
17
|
+
```
|
19
18
|
|
20
19
|
Anatomy
|
21
20
|
-------
|
@@ -91,29 +90,31 @@ Example Program
|
|
91
90
|
|
92
91
|
Cool.io provides a Sinatra-like DSL for authoring event-driven programs:
|
93
92
|
|
94
|
-
|
95
|
-
|
93
|
+
```ruby
|
94
|
+
require 'cool.io'
|
95
|
+
require 'cool.io/dsl'
|
96
96
|
|
97
|
-
|
98
|
-
|
97
|
+
ADDR = '127.0.0.1'
|
98
|
+
PORT = 4321
|
99
99
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
100
|
+
cool.io.connection :echo_server_connection do
|
101
|
+
on_connect do
|
102
|
+
puts "#{remote_addr}:#{remote_port} connected"
|
103
|
+
end
|
104
104
|
|
105
|
-
|
106
|
-
|
107
|
-
|
105
|
+
on_close do
|
106
|
+
puts "#{remote_addr}:#{remote_port} disconnected"
|
107
|
+
end
|
108
108
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
109
|
+
on_read do |data|
|
110
|
+
write data
|
111
|
+
end
|
112
|
+
end
|
113
113
|
|
114
|
-
|
115
|
-
|
116
|
-
|
114
|
+
puts "Echo server listening on #{ADDR}:#{PORT}"
|
115
|
+
cool.io.server ADDR, PORT, :echo_server_connection
|
116
|
+
cool.io.run
|
117
|
+
```
|
117
118
|
|
118
119
|
This creates a new connection class called :echo_server_connection and defines
|
119
120
|
a set of callbacks for when various events occur.
|
@@ -131,29 +132,31 @@ Using Cool.io subclasses directly
|
|
131
132
|
Below is an example of how to write an echo server using a subclass instead of
|
132
133
|
the DSL:
|
133
134
|
|
134
|
-
|
135
|
-
|
136
|
-
|
135
|
+
```ruby
|
136
|
+
require 'cool.io'
|
137
|
+
HOST = 'localhost'
|
138
|
+
PORT = 4321
|
137
139
|
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
140
|
+
class EchoServerConnection < Cool.io::TCPSocket
|
141
|
+
def on_connect
|
142
|
+
puts "#{remote_addr}:#{remote_port} connected"
|
143
|
+
end
|
142
144
|
|
143
|
-
|
144
|
-
|
145
|
-
|
145
|
+
def on_close
|
146
|
+
puts "#{remote_addr}:#{remote_port} disconnected"
|
147
|
+
end
|
146
148
|
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
149
|
+
def on_read(data)
|
150
|
+
write data
|
151
|
+
end
|
152
|
+
end
|
151
153
|
|
152
|
-
|
153
|
-
|
154
|
+
server = Cool.io::TCPServer.new(HOST, PORT, EchoServerConnection)
|
155
|
+
server.attach(Cool.io::Loop.default)
|
154
156
|
|
155
|
-
|
156
|
-
|
157
|
+
puts "Echo server listening on #{HOST}:#{PORT}"
|
158
|
+
Cool.io::Loop.default.run
|
159
|
+
```
|
157
160
|
|
158
161
|
Here a new observer type (EchoServerConnection) is made by subclassing an
|
159
162
|
existing one and adding new implementations to existing event handlers.
|
data/Rakefile
CHANGED
@@ -48,7 +48,7 @@ namespace :build do
|
|
48
48
|
task :windows do
|
49
49
|
require 'rake_compiler_dock'
|
50
50
|
RakeCompilerDock.sh <<-CROSS
|
51
|
-
bundle && bundle exec rake cross native gem RUBY_CC_VERSION='2.7.0:2.6.0:2.5.0:2.4.0'
|
51
|
+
bundle && bundle exec rake cross native gem RUBY_CC_VERSION='3.0.0:2.7.0:2.6.0:2.5.0:2.4.0'
|
52
52
|
CROSS
|
53
53
|
end
|
54
54
|
end
|
data/ext/cool.io/extconf.rb
CHANGED
data/ext/cool.io/iowatcher.c
CHANGED
@@ -65,11 +65,6 @@ static VALUE Coolio_IOWatcher_initialize(int argc, VALUE *argv, VALUE self)
|
|
65
65
|
char *flags_str;
|
66
66
|
int events;
|
67
67
|
struct Coolio_Watcher *watcher_data;
|
68
|
-
#if HAVE_RB_IO_T
|
69
|
-
rb_io_t *fptr;
|
70
|
-
#else
|
71
|
-
OpenFile *fptr;
|
72
|
-
#endif
|
73
68
|
|
74
69
|
rb_scan_args(argc, argv, "11", &io, &flags);
|
75
70
|
|
@@ -88,10 +83,20 @@ static VALUE Coolio_IOWatcher_initialize(int argc, VALUE *argv, VALUE self)
|
|
88
83
|
rb_raise(rb_eArgError, "invalid event type: '%s' (must be 'r', 'w', or 'rw')", flags_str);
|
89
84
|
|
90
85
|
Data_Get_Struct(self, struct Coolio_Watcher, watcher_data);
|
91
|
-
|
86
|
+
io = rb_convert_type(io, T_FILE, "IO", "to_io");
|
92
87
|
|
93
88
|
watcher_data->dispatch_callback = Coolio_IOWatcher_dispatch_callback;
|
89
|
+
#ifdef HAVE_RB_IO_DESCRIPTOR
|
90
|
+
ev_io_init(&watcher_data->event_types.ev_io, Coolio_IOWatcher_libev_callback, rb_io_descriptor(io), events);
|
91
|
+
#else
|
92
|
+
#if defined(HAVE_RB_IO_T)
|
93
|
+
rb_io_t *fptr;
|
94
|
+
#else
|
95
|
+
OpenFile *fptr;
|
96
|
+
#endif
|
97
|
+
GetOpenFile(io, fptr);
|
94
98
|
ev_io_init(&watcher_data->event_types.ev_io, Coolio_IOWatcher_libev_callback, FPTR_TO_FD(fptr), events);
|
99
|
+
#endif
|
95
100
|
watcher_data->event_types.ev_io.data = (void *)self;
|
96
101
|
|
97
102
|
return Qnil;
|
data/ext/iobuffer/extconf.rb
CHANGED
data/ext/iobuffer/iobuffer.c
CHANGED
@@ -378,17 +378,22 @@ IO_Buffer_read_from(VALUE self, VALUE io)
|
|
378
378
|
{
|
379
379
|
struct buffer *buf;
|
380
380
|
int ret;
|
381
|
-
#if HAVE_RB_IO_T
|
381
|
+
#if defined(HAVE_RB_IO_T) || defined(HAVE_RB_IO_DESCRIPTOR)
|
382
382
|
rb_io_t *fptr;
|
383
383
|
#else
|
384
384
|
OpenFile *fptr;
|
385
385
|
#endif
|
386
386
|
|
387
387
|
Data_Get_Struct(self, struct buffer, buf);
|
388
|
-
|
388
|
+
io = rb_convert_type(io, T_FILE, "IO", "to_io");
|
389
|
+
GetOpenFile(io, fptr);
|
389
390
|
rb_io_set_nonblock(fptr);
|
390
391
|
|
392
|
+
#ifdef HAVE_RB_IO_DESCRIPTOR
|
393
|
+
ret = buffer_read_from(buf, rb_io_descriptor(io));
|
394
|
+
#else
|
391
395
|
ret = buffer_read_from(buf, FPTR_TO_FD(fptr));
|
396
|
+
#endif
|
392
397
|
return ret == -1 ? Qnil : INT2NUM(ret);
|
393
398
|
}
|
394
399
|
|
@@ -404,17 +409,22 @@ static VALUE
|
|
404
409
|
IO_Buffer_write_to(VALUE self, VALUE io)
|
405
410
|
{
|
406
411
|
struct buffer *buf;
|
407
|
-
#if HAVE_RB_IO_T
|
412
|
+
#if defined(HAVE_RB_IO_T) || defined(HAVE_RB_IO_DESCRIPTOR)
|
408
413
|
rb_io_t *fptr;
|
409
414
|
#else
|
410
415
|
OpenFile *fptr;
|
411
416
|
#endif
|
412
417
|
|
413
418
|
Data_Get_Struct(self, struct buffer, buf);
|
414
|
-
|
419
|
+
io = rb_convert_type(io, T_FILE, "IO", "to_io");
|
420
|
+
GetOpenFile(io, fptr);
|
415
421
|
rb_io_set_nonblock(fptr);
|
416
422
|
|
423
|
+
#ifdef HAVE_RB_IO_DESCRIPTOR
|
424
|
+
return INT2NUM(buffer_write_to(buf, rb_io_descriptor(io)));
|
425
|
+
#else
|
417
426
|
return INT2NUM(buffer_write_to(buf, FPTR_TO_FD(fptr)));
|
427
|
+
#endif
|
418
428
|
}
|
419
429
|
|
420
430
|
/*
|
data/ext/libev/ev.c
CHANGED
@@ -3768,7 +3768,7 @@ rb_thread_unsafe_dangerous_crazy_blocking_region_end(...);
|
|
3768
3768
|
#if defined(HAVE_RB_THREAD_BLOCKING_REGION) || defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
|
3769
3769
|
poll_args.loop = loop;
|
3770
3770
|
poll_args.waittime = waittime;
|
3771
|
-
rb_thread_call_without_gvl(ev_backend_poll, (void *)&poll_args, RUBY_UBF_IO, 0);
|
3771
|
+
rb_thread_call_without_gvl((void *)ev_backend_poll, (void *)&poll_args, RUBY_UBF_IO, 0);
|
3772
3772
|
#else
|
3773
3773
|
backend_poll (EV_A_ waittime);
|
3774
3774
|
#endif
|
data/lib/cool.io/dns_resolver.rb
CHANGED
@@ -49,6 +49,15 @@ module Coolio
|
|
49
49
|
entries.each { |e| hosts[e] ||= addr }
|
50
50
|
end
|
51
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]
|
60
|
+
end
|
52
61
|
|
53
62
|
hosts[host]
|
54
63
|
end
|
data/lib/cool.io/version.rb
CHANGED
data/spec/dns_spec.rb
CHANGED
@@ -19,6 +19,7 @@ end
|
|
19
19
|
describe "DNS" do
|
20
20
|
before :each do
|
21
21
|
@loop = Cool.io::Loop.new
|
22
|
+
@preferred_localhost_address = ::Socket.getaddrinfo("localhost", nil).first[3]
|
22
23
|
end
|
23
24
|
|
24
25
|
it "connects to valid domains" do
|
@@ -40,4 +41,18 @@ describe "DNS" do
|
|
40
41
|
@loop.run
|
41
42
|
end.to raise_error(WontResolve)
|
42
43
|
end
|
44
|
+
|
45
|
+
it "resolve localhost even though hosts is empty" do
|
46
|
+
Tempfile.open("empty") do |file|
|
47
|
+
expect( Coolio::DNSResolver.hosts("localhost", file.path)).to eq @preferred_localhost_address
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
it "resolve missing localhost even though hosts entries exist" do
|
52
|
+
Tempfile.open("empty") do |file|
|
53
|
+
file.puts("127.0.0.1 example.internal")
|
54
|
+
file.flush
|
55
|
+
expect( Coolio::DNSResolver.hosts("localhost", file.path)).to eq @preferred_localhost_address
|
56
|
+
end
|
57
|
+
end
|
43
58
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cool.io
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tony Arcieri
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2023-08-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake-compiler
|
@@ -78,6 +78,7 @@ extensions:
|
|
78
78
|
- ext/iobuffer/extconf.rb
|
79
79
|
extra_rdoc_files: []
|
80
80
|
files:
|
81
|
+
- ".github/workflows/test.yaml"
|
81
82
|
- ".gitignore"
|
82
83
|
- ".rspec"
|
83
84
|
- ".travis.yml"
|
@@ -172,7 +173,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
172
173
|
- !ruby/object:Gem::Version
|
173
174
|
version: '0'
|
174
175
|
requirements: []
|
175
|
-
rubygems_version: 3.
|
176
|
+
rubygems_version: 3.4.10
|
176
177
|
signing_key:
|
177
178
|
specification_version: 4
|
178
179
|
summary: A cool framework for doing high performance I/O in Ruby
|