cztop 1.2.5 → 1.2.6

Sign up to get free protection for your applications and to get access to all the features.
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