cztop 1.2.5 → 1.2.6

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: f69946c755652d803136712eb37943759d0266b68c6cf7be08d87a70c3fa84c9
4
- data.tar.gz: 7019a58ab3cfd1ad5670b7ae7a2af5eb27a50b19186e2a7c727de98121cab529
3
+ metadata.gz: ca8b5fa8bb96e24ab3c500b704891677ab4431b66f027cfd68dd15d7be79a380
4
+ data.tar.gz: c6360aaef9640bf4f7f75bf3f7f2229d48c93b9e5929bdb28c5012fb9a014806
5
5
  SHA512:
6
- metadata.gz: 74c495a413b86d3dbefcea43701aca13f4f6c13640b206da210d0b9f3c132e29f93750908e73dc8b7929b37dca199fb99f4bd6dfd78083e155d84cfb12c1343d
7
- data.tar.gz: fa73f38fc6923d6eb92272a55e00b3ac7bbad5d9031a101b93cdd83618cb3e2e301b0a68a029658800692bb1c35c905220b4af089c42db1dc65ff89c270b91fb
6
+ metadata.gz: b099c61bbfde6095eaf621b09f13501e2529f87fd91850863b4bdb30d4856584908fc06712371db6f767bf2061f9752cb26991b185e9dd8ab212d686911747fd
7
+ data.tar.gz: 0731e75df8e20bbfb12546ef2145811104dc117eb381b65edbe1733cf147b4785bcc96679a372f3029351da338872c915f7d801f7031f5302ad52196fec056a7
data/CHANGES.md CHANGED
@@ -1,3 +1,14 @@
1
+ 1.2.6 (7/12/2024)
2
+ -----
3
+ * add missing `require 'io/wait'` to get `IO#wait_readable`
4
+ * CZTop::Socket#wait_readable
5
+ - drop broken support for Ruby < 3.2
6
+ - work around quirks of edge-triggered ZMQ FD
7
+ * CZTop::Socket#wait_writable
8
+ - drop broken support for Ruby < 3.2
9
+ - work around quirks of edge-triggered ZMQ FD
10
+ - fix waiting for readiness on ZMQ FD
11
+
1
12
  1.2.5 (7/11/2024)
2
13
  -----
3
14
  * CZTop::Socket::ROUTER#wait_writable: don't raise SocketError if no peer is connected
data/README.md CHANGED
@@ -100,7 +100,7 @@ A slightly more complex version (more sockets) is [here](https://github.com/padd
100
100
  ### Features
101
101
 
102
102
  * Ruby idiomatic API
103
- * Fiber Scheduler aware
103
+ * compatible with Fiber Scheduler (only on Ruby >= 3.2)
104
104
  * errors as exceptions
105
105
  * CURVE security
106
106
  * supports CZMQ DRAFT API
@@ -1,7 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ begin
4
+ require 'io/wait'
5
+ rescue LoadError
6
+ end
7
+
3
8
  unless defined? IO::TimeoutError
4
- # Support Ruby < 3.2
9
+ # Define this to avoid NameError on Ruby < 3.2
5
10
  class IO::TimeoutError < IOError
6
11
  end
7
12
  end
@@ -42,6 +47,21 @@ module CZTop
42
47
  end
43
48
 
44
49
 
50
+ # Because ZMQ sockets are edge-triggered, there's a small chance that we miss an edge (race condition). To avoid
51
+ # blocking forever, all waiting on the ZMQ FD is done with this timeout.
52
+ FD_TIMEOUT = 0.5
53
+
54
+
55
+ # @note Only available on Ruby >= 3.2
56
+ #
57
+ def wait_for_fd_signal
58
+ @fd_io ||= to_io
59
+ @fd_io.wait_readable FD_TIMEOUT # NOTE: always wait for readability on ZMQ FD
60
+ end if IO.method_defined?(:wait_readable)
61
+
62
+
63
+ # Sometimes the ZMQ FD just insists on readiness. To avoid hogging the CPU, a sleep of this many seconds is
64
+ # included in the tight loop.
45
65
  JIFFY = 0.015 # 15 ms
46
66
 
47
67
 
@@ -49,72 +69,54 @@ module CZTop
49
69
  # @param timeout [Numeric, nil] timeout in seconds
50
70
  # @return [true] if readable within timeout
51
71
  # @raise [IO::EAGAINWaitReadable, IO::TimeoutError] if timeout has been reached
72
+ # @raise [CZMQ::FFI::Zsock::DestroyedError] if socket has already been destroyed
73
+ # @note Only available on Ruby >= 3.2
74
+ #
52
75
  def wait_readable(timeout = read_timeout)
53
76
  return true if readable?
54
77
 
55
- @fd_io ||= to_io
78
+ timeout_at = now + timeout if timeout
56
79
 
57
- if timeout
58
- timeout_at = now + timeout
80
+ while true
81
+ # p wait_readable: self, timeout: timeout
59
82
 
60
- while true
61
- # p wait_readable: self, timeout: timeout
62
- @fd_io.wait_readable(timeout)
63
- break if readable? # NOTE: ZMQ FD can't be trusted
64
- raise ::IO::TimeoutError if now >= timeout_at
83
+ wait_for_fd_signal
84
+ break if readable? # NOTE: ZMQ FD can't be trusted
85
+ raise ::IO::TimeoutError if timeout_at && now >= timeout_at
65
86
 
66
- # HACK for edge case: avoid hogging CPU if FD for socket type doesn't block and just insists
67
- sleep JIFFY
68
- end
69
- else
70
- while true
71
- # p wait_readable: self
72
- @fd_io.wait_readable
73
- break if readable? # NOTE: ZMQ FD can't be trusted
74
-
75
- # HACK for edge case: avoid hogging CPU if FD for socket type doesn't block and just insists
76
- sleep JIFFY
77
- end
87
+ sleep JIFFY # HACK
88
+ break if readable? # NOTE: ZMQ FD is edge-triggered. Check again before blocking.
78
89
  end
79
90
 
80
91
  true
81
- end
92
+ end if IO.method_defined?(:wait_readable)
82
93
 
83
94
 
84
95
  # Waits for socket to become writable.
85
96
  # @param timeout [Numeric, nil] timeout in seconds
86
97
  # @return [true] if writable within timeout
87
98
  # @raise [IO::EAGAINWaitReadable, IO::TimeoutError] if timeout has been reached
99
+ # @raise [CZMQ::FFI::Zsock::DestroyedError] if socket has already been destroyed
100
+ # @note Only available on Ruby >= 3.2
101
+ #
88
102
  def wait_writable(timeout = write_timeout)
89
103
  return true if writable?
90
104
 
91
- @fd_io ||= to_io
105
+ timeout_at = now + timeout if timeout
92
106
 
93
- if timeout
94
- timeout_at = now + timeout
107
+ while true
108
+ # p wait_writable: self, timeout: timeout
95
109
 
96
- while true
97
- # p wait_writable: self, timeout: timeout
98
- @fd_io.wait_writable(timeout)
99
- break if writable? # NOTE: ZMQ FD can't be trusted
100
- raise ::IO::TimeoutError if now >= timeout_at
110
+ wait_for_fd_signal
111
+ break if writable? # NOTE: ZMQ FD can't be trusted
112
+ raise ::IO::TimeoutError if timeout_at && now >= timeout_at
101
113
 
102
- # HACK for edge case: avoid hogging CPU if FD for socket type doesn't block and just insists
103
- sleep JIFFY
104
- end
105
- else
106
- while true
107
- # p wait_writable: self
108
- @fd_io.wait_writable
109
- break if writable? # NOTE: ZMQ FD can't be trusted
110
-
111
- # HACK for edge case: avoid hogging CPU if FD for socket type doesn't block and just insists
112
- sleep JIFFY
113
- end
114
+ sleep JIFFY # HACK
115
+ break if writable? # NOTE: ZMQ FD is edge-triggered. Check again before blocking.
114
116
  end
115
117
 
116
118
  true
117
- end
119
+ end if IO.method_defined?(:wait_readable)
118
120
 
119
121
 
120
122
  # @return [Float, nil] the timeout in seconds used by {IO#wait_readable}
data/lib/cztop/version.rb CHANGED
@@ -2,6 +2,6 @@
2
2
 
3
3
  module CZTop
4
4
 
5
- VERSION = '1.2.5'
5
+ VERSION = '1.2.6'
6
6
 
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cztop
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.5
4
+ version: 1.2.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Patrik Wenger
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-07-10 00:00:00.000000000 Z
11
+ date: 2024-07-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: czmq-ffi-gen