io-event 1.11.2 → 1.12.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
- checksums.yaml.gz.sig +0 -0
- data/agent.md +47 -0
- data/ext/io/event/selector/selector.c +1 -6
- data/ext/io/event/worker_pool.c +17 -4
- data/lib/io/event/priority_heap.rb +1 -1
- data/lib/io/event/selector/select.rb +13 -91
- data/lib/io/event/support.rb +11 -18
- data/lib/io/event/version.rb +1 -1
- data/license.md +1 -1
- data.tar.gz.sig +0 -0
- metadata +4 -3
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 80ad33ec3e92cfe141ff91e691370fbb9349f627997f59e130ad1bb016b68ac2
|
4
|
+
data.tar.gz: b2d5c4d46dead9a1b08bcb0ae6afc7a4f75972168501d7bb2bea04b58bf4bdf2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e97d58a391676389971aefb44228a74949ca68a2552810b1b67f0ee2737344fdc0d303068050aa22c7a8def39733fde20d1ceeab6772dd125c9d74bca534a436
|
7
|
+
data.tar.gz: 55fa3477e391ac2775dfe9f999f7545bbe3240b2811143ad665a785beb7ff38df6f813c2fa20f93c1901d039d4ffcd60c23576393f79ffdd792d3a830f4e06e9
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/agent.md
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
# Agent
|
2
|
+
|
3
|
+
## Context
|
4
|
+
|
5
|
+
This section provides links to documentation from installed packages. It is automatically generated and may be updated by running `bake agent:context:install`.
|
6
|
+
|
7
|
+
**Important:** Before performing any code, documentation, or analysis tasks, always read and apply the full content of any relevant documentation referenced in the following sections. These context files contain authoritative standards and best practices for documentation, code style, and project-specific workflows. **Do not proceed with any actions until you have read and incorporated the guidance from relevant context files.**
|
8
|
+
|
9
|
+
### agent-context
|
10
|
+
|
11
|
+
Install and manage context files from Ruby gems.
|
12
|
+
|
13
|
+
#### [Usage Guide](.context/agent-context/usage.md)
|
14
|
+
|
15
|
+
`agent-context` is a tool that helps you discover and install contextual information from Ruby gems for AI agents. Gems can provide additional documentation, examples, and guidance in a `context/` ...
|
16
|
+
|
17
|
+
### decode
|
18
|
+
|
19
|
+
Code analysis for documentation generation.
|
20
|
+
|
21
|
+
#### [Getting Started with Decode](.context/decode/getting-started.md)
|
22
|
+
|
23
|
+
The Decode gem provides programmatic access to Ruby code structure and metadata. It can parse Ruby files and extract definitions, comments, and documentation pragmas, enabling code analysis, docume...
|
24
|
+
|
25
|
+
#### [Documentation Coverage](.context/decode/coverage.md)
|
26
|
+
|
27
|
+
This guide explains how to test and monitor documentation coverage in your Ruby projects using the Decode gem's built-in bake tasks.
|
28
|
+
|
29
|
+
#### [Ruby Documentation](.context/decode/ruby-documentation.md)
|
30
|
+
|
31
|
+
This guide covers documentation practices and pragmas supported by the Decode gem for documenting Ruby code. These pragmas provide structured documentation that can be parsed and used to generate A...
|
32
|
+
|
33
|
+
### sus
|
34
|
+
|
35
|
+
A fast and scalable test runner.
|
36
|
+
|
37
|
+
#### [Using Sus Testing Framework](.context/sus/usage.md)
|
38
|
+
|
39
|
+
Sus is a modern Ruby testing framework that provides a clean, BDD-style syntax for writing tests. It's designed to be fast, simple, and expressive.
|
40
|
+
|
41
|
+
#### [Mocking](.context/sus/mocking.md)
|
42
|
+
|
43
|
+
There are two types of mocking in sus: `receive` and `mock`. The `receive` matcher is a subset of full mocking and is used to set expectations on method calls, while `mock` can be used to replace m...
|
44
|
+
|
45
|
+
#### [Shared Test Behaviors and Fixtures](.context/sus/shared.md)
|
46
|
+
|
47
|
+
Sus provides shared test contexts which can be used to define common behaviours or tests that can be reused across one or more test files.
|
@@ -29,10 +29,7 @@ VALUE IO_Event_Selector_process_status_wait(rb_pid_t pid, int flags)
|
|
29
29
|
int IO_Event_Selector_nonblock_set(int file_descriptor)
|
30
30
|
{
|
31
31
|
#ifdef _WIN32
|
32
|
-
|
33
|
-
ioctlsocket(file_descriptor, FIONBIO, &nonblock);
|
34
|
-
// Windows does not provide any way to know this, so we always restore it back to unset:
|
35
|
-
return 0;
|
32
|
+
rb_w32_set_nonblock(file_descriptor);
|
36
33
|
#else
|
37
34
|
// Get the current mode:
|
38
35
|
int flags = fcntl(file_descriptor, F_GETFL, 0);
|
@@ -50,8 +47,6 @@ void IO_Event_Selector_nonblock_restore(int file_descriptor, int flags)
|
|
50
47
|
{
|
51
48
|
#ifdef _WIN32
|
52
49
|
// Yolo...
|
53
|
-
u_long nonblock = flags;
|
54
|
-
ioctlsocket(file_descriptor, FIONBIO, &nonblock);
|
55
50
|
#else
|
56
51
|
// The flags didn't have O_NONBLOCK set, so it would have been set, so we need to restore it:
|
57
52
|
if (!(flags & O_NONBLOCK)) {
|
data/ext/io/event/worker_pool.c
CHANGED
@@ -336,19 +336,32 @@ static VALUE worker_pool_call(VALUE self, VALUE _blocking_operation) {
|
|
336
336
|
pthread_mutex_unlock(&pool->mutex);
|
337
337
|
|
338
338
|
// Block the current fiber until work is completed:
|
339
|
-
int state;
|
339
|
+
int state = 0;
|
340
340
|
while (true) {
|
341
|
-
|
342
|
-
|
341
|
+
int current_state = 0;
|
342
|
+
rb_protect(worker_pool_work_begin, (VALUE)&work, ¤t_state);
|
343
|
+
if (DEBUG) fprintf(stderr, "-- worker_pool_call:work completed=%d, current_state=%d, state=%d\n", work.completed, current_state, state);
|
344
|
+
|
345
|
+
// Store the first exception state:
|
346
|
+
if (!state) {
|
347
|
+
state = current_state;
|
348
|
+
}
|
349
|
+
|
350
|
+
// If the work is still in the queue, we must wait for a worker to complete it (even if cancelled):
|
343
351
|
if (work.completed) {
|
352
|
+
// The work was completed, we can exit the loop:
|
344
353
|
break;
|
345
354
|
} else {
|
346
355
|
if (DEBUG) fprintf(stderr, "worker_pool_call:rb_fiber_scheduler_blocking_operation_cancel\n");
|
356
|
+
// Ensure the blocking operation is cancelled:
|
347
357
|
rb_fiber_scheduler_blocking_operation_cancel(blocking_operation);
|
348
|
-
|
358
|
+
|
359
|
+
// The work was not completed, we need to wait for it to be completed, so we go around the loop again.
|
349
360
|
}
|
350
361
|
}
|
351
362
|
|
363
|
+
if (DEBUG) fprintf(stderr, "<- worker_pool_call:work completed=%d, state=%d\n", work.completed, state);
|
364
|
+
|
352
365
|
if (state) {
|
353
366
|
rb_jump_tag(state);
|
354
367
|
} else {
|
@@ -82,7 +82,7 @@ class IO
|
|
82
82
|
# Validate the heap invariant. Every element except the root must not be smaller than its parent element. Note that it MAY be equal.
|
83
83
|
def valid?
|
84
84
|
# Notice we skip index 0 on purpose, because it has no parent
|
85
|
-
(1..(@contents.size - 1)).all? {
|
85
|
+
(1..(@contents.size - 1)).all? {|index| @contents[index] >= @contents[(index - 1) / 2]}
|
86
86
|
end
|
87
87
|
|
88
88
|
private
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# Released under the MIT License.
|
4
|
-
# Copyright, 2021-
|
4
|
+
# Copyright, 2021-2025, by Samuel Williams.
|
5
5
|
# Copyright, 2023, by Math Ieu.
|
6
6
|
|
7
7
|
require_relative "../interrupt"
|
@@ -199,7 +199,7 @@ module IO::Event
|
|
199
199
|
result = Fiber.blocking{buffer.read(io, 0, offset)}
|
200
200
|
|
201
201
|
if result < 0
|
202
|
-
if again?(result)
|
202
|
+
if length > 0 and again?(result)
|
203
203
|
self.io_wait(fiber, io, IO::READABLE)
|
204
204
|
else
|
205
205
|
return result
|
@@ -229,7 +229,7 @@ module IO::Event
|
|
229
229
|
result = Fiber.blocking{buffer.write(io, 0, offset)}
|
230
230
|
|
231
231
|
if result < 0
|
232
|
-
if again?(result)
|
232
|
+
if length > 0 and again?(result)
|
233
233
|
self.io_wait(fiber, io, IO::READABLE)
|
234
234
|
else
|
235
235
|
return result
|
@@ -305,96 +305,14 @@ module IO::Event
|
|
305
305
|
|
306
306
|
return total
|
307
307
|
end
|
308
|
-
elsif Support.fiber_scheduler_v1?
|
309
|
-
# Ruby <= 3.1, limited IO::Buffer support.
|
310
|
-
def io_read(fiber, _io, buffer, length, offset = 0)
|
311
|
-
# We need to avoid any internal buffering, so we use a duplicated IO object:
|
312
|
-
io = IO.for_fd(_io.fileno, autoclose: false)
|
313
|
-
|
314
|
-
total = 0
|
315
|
-
|
316
|
-
maximum_size = buffer.size - offset
|
317
|
-
while maximum_size > 0
|
318
|
-
case result = blocking{io.read_nonblock(maximum_size, exception: false)}
|
319
|
-
when :wait_readable
|
320
|
-
if length > 0
|
321
|
-
self.io_wait(fiber, io, IO::READABLE)
|
322
|
-
else
|
323
|
-
return EWOULDBLOCK
|
324
|
-
end
|
325
|
-
when :wait_writable
|
326
|
-
if length > 0
|
327
|
-
self.io_wait(fiber, io, IO::WRITABLE)
|
328
|
-
else
|
329
|
-
return EWOULDBLOCK
|
330
|
-
end
|
331
|
-
when nil
|
332
|
-
break
|
333
|
-
else
|
334
|
-
buffer.set_string(result, offset)
|
335
|
-
|
336
|
-
size = result.bytesize
|
337
|
-
total += size
|
338
|
-
offset += size
|
339
|
-
break if size >= length
|
340
|
-
length -= size
|
341
|
-
end
|
342
|
-
|
343
|
-
maximum_size = buffer.size - offset
|
344
|
-
end
|
345
|
-
|
346
|
-
return total
|
347
|
-
rescue IOError => error
|
348
|
-
return -Errno::EBADF::Errno
|
349
|
-
rescue SystemCallError => error
|
350
|
-
return -error.errno
|
351
|
-
end
|
352
|
-
|
353
|
-
def io_write(fiber, _io, buffer, length, offset = 0)
|
354
|
-
# We need to avoid any internal buffering, so we use a duplicated IO object:
|
355
|
-
io = IO.for_fd(_io.fileno, autoclose: false)
|
356
|
-
|
357
|
-
total = 0
|
358
|
-
|
359
|
-
maximum_size = buffer.size - offset
|
360
|
-
while maximum_size > 0
|
361
|
-
chunk = buffer.get_string(offset, maximum_size)
|
362
|
-
case result = blocking{io.write_nonblock(chunk, exception: false)}
|
363
|
-
when :wait_readable
|
364
|
-
if length > 0
|
365
|
-
self.io_wait(fiber, io, IO::READABLE)
|
366
|
-
else
|
367
|
-
return EWOULDBLOCK
|
368
|
-
end
|
369
|
-
when :wait_writable
|
370
|
-
if length > 0
|
371
|
-
self.io_wait(fiber, io, IO::WRITABLE)
|
372
|
-
else
|
373
|
-
return EWOULDBLOCK
|
374
|
-
end
|
375
|
-
else
|
376
|
-
total += result
|
377
|
-
offset += result
|
378
|
-
break if result >= length
|
379
|
-
length -= result
|
380
|
-
end
|
381
|
-
|
382
|
-
maximum_size = buffer.size - offset
|
383
|
-
end
|
384
|
-
|
385
|
-
return total
|
386
|
-
rescue IOError => error
|
387
|
-
return -Errno::EBADF::Errno
|
388
|
-
rescue SystemCallError => error
|
389
|
-
return -error.errno
|
390
|
-
end
|
391
|
-
|
392
|
-
def blocking(&block)
|
393
|
-
fiber = Fiber.new(blocking: true, &block)
|
394
|
-
return fiber.resume(fiber)
|
395
|
-
end
|
396
308
|
end
|
397
309
|
|
310
|
+
# Wait for a process to change state.
|
311
|
+
#
|
312
|
+
# @parameter fiber [Fiber] The fiber to resume after waiting.
|
313
|
+
# @parameter pid [Integer] The process ID to wait for.
|
314
|
+
# @parameter flags [Integer] Flags to pass to Process::Status.wait.
|
315
|
+
# @returns [Process::Status] The status of the waited process.
|
398
316
|
def process_wait(fiber, pid, flags)
|
399
317
|
Thread.new do
|
400
318
|
Process::Status.wait(pid, flags)
|
@@ -414,6 +332,10 @@ module IO::Event
|
|
414
332
|
end
|
415
333
|
end
|
416
334
|
|
335
|
+
# Wait for IO events or a timeout.
|
336
|
+
#
|
337
|
+
# @parameter duration [Numeric | Nil] The maximum time to wait, or nil for no timeout.
|
338
|
+
# @returns [Integer] The number of ready IO objects.
|
417
339
|
def select(duration = nil)
|
418
340
|
if pop_ready
|
419
341
|
# If we have popped items from the ready list, they may influence the duration calculation, so we don't delay the event loop:
|
data/lib/io/event/support.rb
CHANGED
@@ -14,35 +14,28 @@ class IO
|
|
14
14
|
IO.const_defined?(:Buffer)
|
15
15
|
end
|
16
16
|
|
17
|
-
# The basic fiber scheduler was introduced along side the IO::Buffer class.
|
18
|
-
#
|
19
|
-
# @returns [Boolean] Whether the IO::Buffer class is available.
|
20
|
-
#
|
21
|
-
# To be removed on 31 Mar 2025.
|
22
|
-
def self.fiber_scheduler_v1?
|
23
|
-
IO.const_defined?(:Buffer)
|
24
|
-
end
|
25
|
-
|
26
17
|
# More advanced read/write methods and blocking controls were introduced in Ruby 3.2.
|
27
18
|
#
|
28
19
|
# To be removed on 31 Mar 2026.
|
29
20
|
def self.fiber_scheduler_v2?
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
21
|
+
if RUBY_VERSION >= "3.2"
|
22
|
+
return true if RUBY_VERSION >= "3.2.6"
|
23
|
+
|
24
|
+
# Some interface changes were back-ported incorrectly and released in 3.2.5 <https://github.com/ruby/ruby/pull/10778> - Specifically "Improvements to IO::Buffer read/write/pread/pwrite." is missing correct size calculation.
|
25
|
+
return false if RUBY_VERSION >= "3.2.5"
|
26
|
+
|
27
|
+
# Feature detection:
|
28
|
+
IO.const_defined?(:Buffer) and Fiber.respond_to?(:blocking) and IO::Buffer.instance_method(:read).arity == -1
|
29
|
+
end
|
37
30
|
end
|
38
31
|
|
39
32
|
# Updated inferfaces for read/write and IO::Buffer were introduced in Ruby 3.3, including pread/pwrite.
|
40
33
|
#
|
41
34
|
# To become the default 31 Mar 2026.
|
42
35
|
def self.fiber_scheduler_v3?
|
36
|
+
return true if RUBY_VERSION >= "3.3"
|
37
|
+
|
43
38
|
if fiber_scheduler_v2?
|
44
|
-
return true if RUBY_VERSION >= "3.3"
|
45
|
-
|
46
39
|
# Feature detection if required:
|
47
40
|
begin
|
48
41
|
IO::Buffer.new.slice(0, 0).write(STDOUT)
|
data/lib/io/event/version.rb
CHANGED
data/license.md
CHANGED
@@ -9,7 +9,7 @@ Copyright, 2022, by Bruno Sutic.
|
|
9
9
|
Copyright, 2023, by Math Ieu.
|
10
10
|
Copyright, 2024, by Pavel Rosický.
|
11
11
|
Copyright, 2024, by Anthony Ross.
|
12
|
-
Copyright, 2024, by Shizuo Fujita.
|
12
|
+
Copyright, 2024-2025, by Shizuo Fujita.
|
13
13
|
Copyright, 2024, by Jean Boussier.
|
14
14
|
Copyright, 2025, by Stanislav (Stas) Katkov.
|
15
15
|
|
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: io-event
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Williams
|
@@ -10,11 +10,11 @@ authors:
|
|
10
10
|
- Jean Boussier
|
11
11
|
- Benoit Daloze
|
12
12
|
- Bruno Sutic
|
13
|
+
- Shizuo Fujita
|
13
14
|
- Alex Matchneer
|
14
15
|
- Anthony Ross
|
15
16
|
- Delton Ding
|
16
17
|
- Pavel Rosický
|
17
|
-
- Shizuo Fujita
|
18
18
|
- Stanislav (Stas) Katkov
|
19
19
|
bindir: bin
|
20
20
|
cert_chain:
|
@@ -54,6 +54,7 @@ extensions:
|
|
54
54
|
- ext/extconf.rb
|
55
55
|
extra_rdoc_files: []
|
56
56
|
files:
|
57
|
+
- agent.md
|
57
58
|
- design.md
|
58
59
|
- ext/extconf.rb
|
59
60
|
- ext/io/event/array.h
|
@@ -106,7 +107,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
106
107
|
requirements:
|
107
108
|
- - ">="
|
108
109
|
- !ruby/object:Gem::Version
|
109
|
-
version:
|
110
|
+
version: 3.2.6
|
110
111
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
111
112
|
requirements:
|
112
113
|
- - ">="
|
metadata.gz.sig
CHANGED
Binary file
|