io-event 1.6.5 → 1.7.5

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.
@@ -3,14 +3,19 @@
3
3
  # Released under the MIT License.
4
4
  # Copyright, 2021-2024, by Samuel Williams.
5
5
 
6
- require_relative 'selector/select'
7
- require_relative 'debug/selector'
8
- require_relative 'support'
6
+ require_relative "selector/select"
7
+ require_relative "debug/selector"
8
+ require_relative "support"
9
9
 
10
10
  module IO::Event
11
+ # @namespace
11
12
  module Selector
13
+ # The default selector implementation, which is chosen based on the environment and available implementations.
14
+ #
15
+ # @parameter env [Hash] The environment to read configuration from.
16
+ # @returns [Class] The default selector implementation.
12
17
  def self.default(env = ENV)
13
- if name = env['IO_EVENT_SELECTOR']&.to_sym
18
+ if name = env["IO_EVENT_SELECTOR"]&.to_sym
14
19
  return const_get(name)
15
20
  end
16
21
 
@@ -25,10 +30,15 @@ module IO::Event
25
30
  end
26
31
  end
27
32
 
33
+ # Create a new selector instance, according to the best available implementation.
34
+ #
35
+ # @parameter loop [Fiber] The event loop fiber.
36
+ # @parameter env [Hash] The environment to read configuration from.
37
+ # @returns [Selector] The new selector instance.
28
38
  def self.new(loop, env = ENV)
29
39
  selector = default(env).new(loop)
30
40
 
31
- if debug = env['IO_EVENT_DEBUG_SELECTOR']
41
+ if debug = env["IO_EVENT_DEBUG_SELECTOR"]
32
42
  selector = Debug::Selector.wrap(selector, env)
33
43
  end
34
44
 
@@ -1,23 +1,44 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2022-2023, by Samuel Williams.
4
+ # Copyright, 2022-2024, by Samuel Williams.
5
5
 
6
6
  class IO
7
7
  module Event
8
+ # Helper methods for detecting support for various features.
8
9
  module Support
10
+ # Some features are only availble if the IO::Buffer class is available.
11
+ #
12
+ # @returns [Boolean] Whether the IO::Buffer class is available.
9
13
  def self.buffer?
10
14
  IO.const_defined?(:Buffer)
11
15
  end
12
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.
13
22
  def self.fiber_scheduler_v1?
14
- IO.const_defined?(:Buffer) and !Fiber.respond_to?(:blocking)
23
+ IO.const_defined?(:Buffer)
15
24
  end
16
25
 
26
+ # More advanced read/write methods and blocking controls were introduced in Ruby 3.2.
27
+ #
28
+ # To be removed on 31 Mar 2026.
17
29
  def self.fiber_scheduler_v2?
30
+ # Some interface changes were back-ported incorrectly:
31
+ # https://github.com/ruby/ruby/pull/10778
32
+ # Specifically "Improvements to IO::Buffer read/write/pread/pwrite."
33
+ # Missing correct size calculation.
34
+ return false if RUBY_VERSION >= "3.2.5"
35
+
18
36
  IO.const_defined?(:Buffer) and Fiber.respond_to?(:blocking) and IO::Buffer.instance_method(:read).arity == -1
19
37
  end
20
38
 
39
+ # Updated inferfaces for read/write and IO::Buffer were introduced in Ruby 3.3, including pread/pwrite.
40
+ #
41
+ # To become the default 31 Mar 2026.
21
42
  def self.fiber_scheduler_v3?
22
43
  if fiber_scheduler_v2?
23
44
  return true if RUBY_VERSION >= "3.3"
@@ -3,46 +3,68 @@
3
3
  # Released under the MIT License.
4
4
  # Copyright, 2024, by Samuel Williams.
5
5
 
6
- require_relative 'priority_heap'
6
+ require_relative "priority_heap"
7
7
 
8
8
  class IO
9
9
  module Event
10
+ # An efficient sorted set of timers.
10
11
  class Timers
12
+ # A handle to a scheduled timer.
11
13
  class Handle
14
+ # Initialize the handle with the given time and block.
15
+ #
16
+ # @parameter time [Float] The time at which the block should be called.
17
+ # @parameter block [Proc] The block to call.
12
18
  def initialize(time, block)
13
19
  @time = time
14
20
  @block = block
15
21
  end
16
22
 
23
+ # @attribute [Float] The time at which the block should be called.
24
+ attr :time
25
+
26
+ # @attribute [Proc | Nil] The block to call when the timer fires.
27
+ attr :block
28
+
29
+ # Compare the handle with another handle.
30
+ #
31
+ # @parameter other [Handle] The other handle to compare with.
32
+ # @returns [Boolean] Whether the handle is less than the other handle.
17
33
  def < other
18
34
  @time < other.time
19
35
  end
20
36
 
37
+ # Compare the handle with another handle.
38
+ #
39
+ # @parameter other [Handle] The other handle to compare with.
40
+ # @returns [Boolean] Whether the handle is greater than the other handle.
21
41
  def > other
22
42
  @time > other.time
23
43
  end
24
44
 
25
- attr :time
26
- attr :block
27
-
45
+ # Invoke the block.
28
46
  def call(...)
29
47
  @block.call(...)
30
48
  end
31
49
 
50
+ # Cancel the timer.
32
51
  def cancel!
33
52
  @block = nil
34
53
  end
35
54
 
55
+ # @returns [Boolean] Whether the timer has been cancelled.
36
56
  def cancelled?
37
57
  @block.nil?
38
58
  end
39
59
  end
40
60
 
61
+ # Initialize the timers.
41
62
  def initialize
42
63
  @heap = PriorityHeap.new
43
64
  @scheduled = []
44
65
  end
45
66
 
67
+ # @returns [Integer] The number of timers in the heap.
46
68
  def size
47
69
  flush!
48
70
 
@@ -50,7 +72,9 @@ class IO
50
72
  end
51
73
 
52
74
  # Schedule a block to be called at a specific time in the future.
75
+ #
53
76
  # @parameter time [Float] The time at which the block should be called, relative to {#now}.
77
+ # @parameter block [Proc] The block to call.
54
78
  def schedule(time, block)
55
79
  handle = Handle.new(time, block)
56
80
 
@@ -60,11 +84,18 @@ class IO
60
84
  end
61
85
 
62
86
  # Schedule a block to be called after a specific time offset, relative to the current time as returned by {#now}.
87
+ #
63
88
  # @parameter offset [#to_f] The time offset from the current time at which the block should be called.
89
+ # @yields {|now| ...} When the timer fires.
64
90
  def after(offset, &block)
65
91
  schedule(self.now + offset.to_f, block)
66
92
  end
67
93
 
94
+
95
+ # Compute the time interval until the next timer fires.
96
+ #
97
+ # @parameter now [Float] The current time.
98
+ # @returns [Float | Nil] The time interval until the next timer fires, if any.
68
99
  def wait_interval(now = self.now)
69
100
  flush!
70
101
 
@@ -77,10 +108,14 @@ class IO
77
108
  end
78
109
  end
79
110
 
111
+ # @returns [Float] The current time.
80
112
  def now
81
113
  ::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
82
114
  end
83
115
 
116
+ # Fire all timers that are ready to fire.
117
+ #
118
+ # @parameter now [Float] The current time.
84
119
  def fire(now = self.now)
85
120
  # Flush scheduled timers into the heap:
86
121
  flush!
@@ -101,6 +136,9 @@ class IO
101
136
  end
102
137
  end
103
138
 
139
+ # Flush all scheduled timers into the heap.
140
+ #
141
+ # This is a small optimization which assumes that most timers (timeouts) will be cancelled.
104
142
  protected def flush!
105
143
  while handle = @scheduled.pop
106
144
  @heap.push(handle) unless handle.cancelled?
@@ -3,8 +3,10 @@
3
3
  # Released under the MIT License.
4
4
  # Copyright, 2021-2024, by Samuel Williams.
5
5
 
6
+ # @namespace
6
7
  class IO
8
+ # @namespace
7
9
  module Event
8
- VERSION = "1.6.5"
10
+ VERSION = "1.7.5"
9
11
  end
10
12
  end
data/lib/io/event.rb CHANGED
@@ -3,13 +3,13 @@
3
3
  # Released under the MIT License.
4
4
  # Copyright, 2021-2024, by Samuel Williams.
5
5
 
6
- require_relative 'event/version'
7
- require_relative 'event/selector'
8
- require_relative 'event/timers'
6
+ require_relative "event/version"
7
+ require_relative "event/selector"
8
+ require_relative "event/timers"
9
9
 
10
10
  begin
11
- require 'IO_Event'
11
+ require "IO_Event"
12
12
  rescue LoadError => error
13
13
  warn "Could not load native event selector: #{error}"
14
- require_relative 'event/selector/nonblock'
14
+ require_relative "event/selector/nonblock"
15
15
  end
data/license.md CHANGED
@@ -8,6 +8,9 @@ Copyright, 2022, by Alex Matchneer.
8
8
  Copyright, 2022, by Bruno Sutic.
9
9
  Copyright, 2023, by Math Ieu.
10
10
  Copyright, 2024, by Pavel Rosický.
11
+ Copyright, 2024, by Anthony Ross.
12
+ Copyright, 2024, by Shizuo Fujita.
13
+ Copyright, 2024, by Jean Boussier.
11
14
 
12
15
  Permission is hereby granted, free of charge, to any person obtaining a copy
13
16
  of this software and associated documentation files (the "Software"), to deal
data/readme.md CHANGED
@@ -10,7 +10,17 @@ The initial proof-of-concept [Async](https://github.com/socketry/async) was buil
10
10
 
11
11
  ## Usage
12
12
 
13
- Please see the [project documentation](https://socketry.github.io/io-event/).
13
+ Please see the [project documentation](https://socketry.github.io/io-event/) for more details.
14
+
15
+ - [Getting Started](https://socketry.github.io/io-event/guides/getting-started/index) - This guide explains how to use `io-event` for non-blocking IO.
16
+
17
+ ## Releases
18
+
19
+ Please see the [project releases](https://socketry.github.io/io-event/releases/index) for all releases.
20
+
21
+ ### v1.7.5
22
+
23
+ - Fix `process_wait` race condition on EPoll that could cause a hang.
14
24
 
15
25
  ## Contributing
16
26
 
@@ -24,8 +34,8 @@ We welcome contributions to this project.
24
34
 
25
35
  ### Developer Certificate of Origin
26
36
 
27
- This project uses the [Developer Certificate of Origin](https://developercertificate.org/). All contributors to this project must agree to this document to have their contributions accepted.
37
+ In order to protect users of this project, we require all contributors to comply with the [Developer Certificate of Origin](https://developercertificate.org/). This ensures that all contributions are properly licensed and attributed.
28
38
 
29
- ### Contributor Covenant
39
+ ### Community Guidelines
30
40
 
31
- This project is governed by the [Contributor Covenant](https://www.contributor-covenant.org/). All contributors and participants agree to abide by its terms.
41
+ This project is best served by a collaborative and respectful environment. Treat each other professionally, respect differing viewpoints, and engage constructively. Harassment, discrimination, or harmful behavior is not tolerated. Communicate clearly, listen actively, and support one another. If any issues arise, please inform the project maintainers.
data/releases.md ADDED
@@ -0,0 +1,5 @@
1
+ # Releases
2
+
3
+ ## v1.7.5
4
+
5
+ - Fix `process_wait` race condition on EPoll that could cause a hang.
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.6.5
4
+ version: 1.7.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
@@ -10,6 +10,7 @@ authors:
10
10
  - Benoit Daloze
11
11
  - Bruno Sutic
12
12
  - Alex Matchneer
13
+ - Anthony Ross
13
14
  - Delton Ding
14
15
  - Pavel Rosický
15
16
  autorequire:
@@ -44,7 +45,7 @@ cert_chain:
44
45
  Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
45
46
  voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
46
47
  -----END CERTIFICATE-----
47
- date: 2024-06-23 00:00:00.000000000 Z
48
+ date: 2024-12-15 00:00:00.000000000 Z
48
49
  dependencies: []
49
50
  description:
50
51
  email:
@@ -82,10 +83,13 @@ files:
82
83
  - lib/io/event/version.rb
83
84
  - license.md
84
85
  - readme.md
86
+ - releases.md
85
87
  homepage: https://github.com/socketry/io-event
86
88
  licenses:
87
89
  - MIT
88
- metadata: {}
90
+ metadata:
91
+ documentation_uri: https://socketry.github.io/io-event/
92
+ source_code_uri: https://github.com/socketry/io-event.git
89
93
  post_install_message:
90
94
  rdoc_options: []
91
95
  require_paths:
@@ -101,7 +105,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
101
105
  - !ruby/object:Gem::Version
102
106
  version: '0'
103
107
  requirements: []
104
- rubygems_version: 3.5.11
108
+ rubygems_version: 3.5.22
105
109
  signing_key:
106
110
  specification_version: 4
107
111
  summary: An event loop.
metadata.gz.sig CHANGED
Binary file