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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8ed51c0fcb16152e1701478f796fcfa8a02bfb17b913ec3398fad6845fdc405d
4
- data.tar.gz: 9ee69e4eaebc4ea779817a0212a1cc2de3ddaa455a7b881757e0a0df5574b0ab
3
+ metadata.gz: bc38746b7a17648d787378a1a186e213cc2b5470d0158a282d0a49653368557e
4
+ data.tar.gz: 192da5f1cbdf25ed7c242f5096ab9339287eafefc709226d625e78741bdd28b6
5
5
  SHA512:
6
- metadata.gz: a0c8c358607429e50d2f65e54792f31b60b81137b543e62fe6add5e02412d736bd2f38d6b17088e82de3efa6edb22965b67b7272de711089064632823aee6ce6
7
- data.tar.gz: '098896359667045cbee494f2efa0bb440b925df84c116143273f37cebd89049d053061fe9e9c76f07664c905c7ed7eed79cb9585f3147503c701b638c9064e87'
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
@@ -1,3 +1,8 @@
1
+ 1.7.1
2
+ -----
3
+
4
+ * Set fallback local loopback address by default for Windows environment
5
+
1
6
  1.7.0
2
7
  -----
3
8
 
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
- require 'cool.io'
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
- require 'cool.io'
95
- require 'cool.io/dsl'
93
+ ```ruby
94
+ require 'cool.io'
95
+ require 'cool.io/dsl'
96
96
 
97
- ADDR = '127.0.0.1'
98
- PORT = 4321
97
+ ADDR = '127.0.0.1'
98
+ PORT = 4321
99
99
 
100
- cool.io.connection :echo_server_connection do
101
- on_connect do
102
- puts "#{remote_addr}:#{remote_port} connected"
103
- end
100
+ cool.io.connection :echo_server_connection do
101
+ on_connect do
102
+ puts "#{remote_addr}:#{remote_port} connected"
103
+ end
104
104
 
105
- on_close do
106
- puts "#{remote_addr}:#{remote_port} disconnected"
107
- end
105
+ on_close do
106
+ puts "#{remote_addr}:#{remote_port} disconnected"
107
+ end
108
108
 
109
- on_read do |data|
110
- write data
111
- end
112
- end
109
+ on_read do |data|
110
+ write data
111
+ end
112
+ end
113
113
 
114
- puts "Echo server listening on #{ADDR}:#{PORT}"
115
- cool.io.server ADDR, PORT, :echo_server_connection
116
- cool.io.run
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
- require 'cool.io'
135
- HOST = 'localhost'
136
- PORT = 4321
135
+ ```ruby
136
+ require 'cool.io'
137
+ HOST = 'localhost'
138
+ PORT = 4321
137
139
 
138
- class EchoServerConnection < Cool.io::TCPSocket
139
- def on_connect
140
- puts "#{remote_addr}:#{remote_port} connected"
141
- end
140
+ class EchoServerConnection < Cool.io::TCPSocket
141
+ def on_connect
142
+ puts "#{remote_addr}:#{remote_port} connected"
143
+ end
142
144
 
143
- def on_close
144
- puts "#{remote_addr}:#{remote_port} disconnected"
145
- end
145
+ def on_close
146
+ puts "#{remote_addr}:#{remote_port} disconnected"
147
+ end
146
148
 
147
- def on_read(data)
148
- write data
149
- end
150
- end
149
+ def on_read(data)
150
+ write data
151
+ end
152
+ end
151
153
 
152
- server = Cool.io::TCPServer.new(HOST, PORT, EchoServerConnection)
153
- server.attach(Cool.io::Loop.default)
154
+ server = Cool.io::TCPServer.new(HOST, PORT, EchoServerConnection)
155
+ server.attach(Cool.io::Loop.default)
154
156
 
155
- puts "Echo server listening on #{HOST}:#{PORT}"
156
- Cool.io::Loop.default.run
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
@@ -4,6 +4,7 @@ libs = []
4
4
 
5
5
  $defs << "-DRUBY_VERSION_CODE=#{RUBY_VERSION.gsub(/\D/, '')}"
6
6
 
7
+ have_func('rb_io_descriptor')
7
8
  have_func('rb_thread_blocking_region')
8
9
  have_func('rb_thread_call_without_gvl')
9
10
  have_func('rb_thread_alone')
@@ -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
- GetOpenFile(rb_convert_type(io, T_FILE, "IO", "to_io"), fptr);
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;
@@ -1,6 +1,7 @@
1
1
  require 'mkmf'
2
2
 
3
3
  dir_config("iobuffer")
4
+ have_func("rb_io_descriptor")
4
5
  have_library("c", "main")
5
6
  if have_macro("HAVE_RB_IO_T", "ruby/io.h")
6
7
  have_struct_member("rb_io_t", "fd", "ruby/io.h")
@@ -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
- GetOpenFile(rb_convert_type(io, T_FILE, "IO", "to_io"), fptr);
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
- GetOpenFile(rb_convert_type(io, T_FILE, "IO", "to_io"), fptr);
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
@@ -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
@@ -1,5 +1,5 @@
1
1
  module Coolio
2
- VERSION = "1.7.0"
2
+ VERSION = "1.8.0"
3
3
 
4
4
  def self.version
5
5
  VERSION
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.7.0
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: 2020-09-26 00:00:00.000000000 Z
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.2.0.rc.1
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