cztop 1.0.0 → 1.1.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/coverage.yml +20 -0
  3. data/.github/workflows/draft_api.yml +27 -0
  4. data/.github/workflows/{main.yml → stable_api.yml} +6 -6
  5. data/.rubocop.yml +175 -0
  6. data/CHANGES.md +8 -1
  7. data/Gemfile +5 -0
  8. data/README.md +3 -1
  9. data/ci/install-libczmq +22 -0
  10. data/ci/install-libzmq +22 -0
  11. data/cztop.gemspec +3 -2
  12. data/lib/cztop/actor.rb +55 -26
  13. data/lib/cztop/authenticator.rb +18 -9
  14. data/lib/cztop/beacon.rb +22 -10
  15. data/lib/cztop/cert_store.rb +8 -2
  16. data/lib/cztop/certificate.rb +47 -18
  17. data/lib/cztop/config/comments.rb +14 -3
  18. data/lib/cztop/config/serialization.rb +25 -5
  19. data/lib/cztop/config/traversing.rb +44 -13
  20. data/lib/cztop/config.rb +23 -9
  21. data/lib/cztop/frame.rb +23 -10
  22. data/lib/cztop/has_ffi_delegate.rb +11 -1
  23. data/lib/cztop/message/frames.rb +16 -2
  24. data/lib/cztop/message.rb +36 -22
  25. data/lib/cztop/metadata.rb +35 -24
  26. data/lib/cztop/monitor.rb +14 -5
  27. data/lib/cztop/poller/aggregated.rb +31 -15
  28. data/lib/cztop/poller/zmq.rb +25 -22
  29. data/lib/cztop/poller/zpoller.rb +18 -6
  30. data/lib/cztop/poller.rb +43 -18
  31. data/lib/cztop/polymorphic_zsock_methods.rb +6 -1
  32. data/lib/cztop/proxy.rb +34 -19
  33. data/lib/cztop/send_receive_methods.rb +5 -1
  34. data/lib/cztop/socket/types.rb +128 -22
  35. data/lib/cztop/socket.rb +23 -18
  36. data/lib/cztop/version.rb +5 -1
  37. data/lib/cztop/z85/padded.rb +12 -3
  38. data/lib/cztop/z85/pipe.rb +40 -17
  39. data/lib/cztop/z85.rb +17 -6
  40. data/lib/cztop/zap.rb +57 -32
  41. data/lib/cztop/zsock_options.rb +155 -122
  42. data/lib/cztop.rb +2 -1
  43. metadata +28 -10
  44. data/.ruby-version +0 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '0099b49a3147e57b4e29b8ca7288370f56e06694230c2f390e36308ac1f0cb1e'
4
- data.tar.gz: d4431ae33cc4c35f9911d755d4377913f502156c26317b04a720c598f1f3eb3b
3
+ metadata.gz: 149778ca201f323611fe23b4b1107c4cb4bde8ea7364bbe7370cea39daf5ab02
4
+ data.tar.gz: 195be179654f5b1c286f4859a012a093bed587f644306ee63642a7e300b261f6
5
5
  SHA512:
6
- metadata.gz: 48f93f12b32aaed87a7cdbdf3f83ff064e69f1fef3e27e4dfaee21a7d721698bd8e7e1675d6fa1110b7597ae7651d971d4502b631a5505345cbb0dbf8ecc19e8
7
- data.tar.gz: 90540f6ccab41b27361fc1372feb5198351a725b20a69509285ed459073f438a149a7e5e11043a1936b978610c664a0f7096bbb27c6801054cb85ff6fcd6a0b4
6
+ metadata.gz: c2a65ca5f02e39cfc9ca2695fefd6b02c0e898878041a662d0af1361235fa1ec091c4024d0a9d68b793173f191ce81350e21cc98b0a2320d3d6c9d9617f35d50
7
+ data.tar.gz: bae808f502e3f8b3ced7872d76a6377578bd37d332bf12ba96aaa126ea7571abbbfe363426c9578c30ecd6abbc126198e470d3d378de0bd0b1960384ab9d17b7
@@ -0,0 +1,20 @@
1
+ name: Coverage
2
+
3
+ on: [push,pull_request]
4
+
5
+ jobs:
6
+ build:
7
+ runs-on: ubuntu-20.04
8
+ steps:
9
+ - uses: actions/checkout@v2
10
+ - name: Set up Ruby
11
+ uses: ruby/setup-ruby@v1
12
+ with:
13
+ ruby-version: 3.1
14
+ - name: Install CZMQ
15
+ run: sudo apt-get install libczmq-dev
16
+ - name: Run the default task
17
+ run: |
18
+ gem install bundler
19
+ bundle install
20
+ env REPORT_COVERAGE=true bundle exec rake
@@ -0,0 +1,27 @@
1
+ name: DRAFT API
2
+
3
+ on: [push,pull_request]
4
+
5
+ jobs:
6
+ build:
7
+ runs-on: ubuntu-20.04
8
+ timeout-minutes: 15
9
+ steps:
10
+ - uses: actions/checkout@v2
11
+ - name: Set up Ruby
12
+ uses: ruby/setup-ruby@v1
13
+ with:
14
+ ruby-version: 3.1
15
+ - name: Install ZMQ and CZMQ
16
+ run: |
17
+ export PKG_CONFIG_PATH=$HOME/lib/pkgconfig # custom libs (for linking)
18
+ env
19
+ env ZMQ_VERSION=HEAD ci/install-libzmq
20
+ env CZMQ_VERSION=HEAD ci/install-libczmq
21
+ - name: Run the default task
22
+ run: |
23
+ export LD_LIBRARY_PATH=$HOME/lib # custom libs (for execution)
24
+ env
25
+ gem install bundler
26
+ bundle install
27
+ bundle exec rake
@@ -1,4 +1,4 @@
1
- name: Specs
1
+ name: STABLE API
2
2
 
3
3
  on: [push,pull_request]
4
4
 
@@ -8,9 +8,9 @@ jobs:
8
8
  strategy:
9
9
  matrix:
10
10
  ruby:
11
- - "2.6"
12
- - "2.7"
13
- - "3.0"
11
+ - 2.7
12
+ - 3.0
13
+ - 3.1
14
14
  steps:
15
15
  - uses: actions/checkout@v2
16
16
  - name: Set up Ruby ${{ matrix.ruby }}
@@ -18,9 +18,9 @@ jobs:
18
18
  with:
19
19
  ruby-version: ${{ matrix.ruby }}
20
20
  - name: Install CZMQ
21
- run: sudo apt install libczmq-dev
21
+ run: sudo apt-get install libczmq-dev
22
22
  - name: Run the default task
23
23
  run: |
24
- gem install bundler -v 2.2.3
24
+ gem install bundler
25
25
  bundle install
26
26
  bundle exec rake
data/.rubocop.yml ADDED
@@ -0,0 +1,175 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.7
3
+ NewCops: enable
4
+ Layout/EmptyLineAfterMagicComment:
5
+ Enabled: true
6
+ Layout/ExtraSpacing:
7
+ AllowForAlignment: true
8
+ Layout/EmptyLines:
9
+ Enabled: false
10
+ Layout/EmptyLineBetweenDefs:
11
+ NumberOfEmptyLines: 2
12
+ Layout/MultilineOperationIndentation:
13
+ Enabled: true
14
+ Gemspec/DeprecatedAttributeAssignment: # new in 1.30
15
+ Enabled: true
16
+ Gemspec/RequireMFA: # new in 1.23
17
+ Enabled: true
18
+ Layout/LineContinuationLeadingSpace: # new in 1.31
19
+ Enabled: true
20
+ Layout/LineContinuationSpacing: # new in 1.31
21
+ Enabled: true
22
+ Layout/LineEndStringConcatenationIndentation: # new in 1.18
23
+ Enabled: true
24
+ Layout/SpaceBeforeBrackets: # new in 1.7
25
+ Enabled: true
26
+ Lint/AmbiguousAssignment: # new in 1.7
27
+ Enabled: true
28
+ Lint/AmbiguousOperatorPrecedence: # new in 1.21
29
+ Enabled: false
30
+ Lint/AmbiguousRange: # new in 1.19
31
+ Enabled: true
32
+ Lint/ConstantOverwrittenInRescue: # new in 1.31
33
+ Enabled: true
34
+ Lint/DeprecatedConstants: # new in 1.8
35
+ Enabled: true
36
+ Lint/DuplicateBranch: # new in 1.3
37
+ Enabled: true
38
+ Lint/DuplicateRegexpCharacterClassElement: # new in 1.1
39
+ Enabled: true
40
+ Lint/EmptyBlock: # new in 1.1
41
+ Enabled: true
42
+ Lint/EmptyClass: # new in 1.3
43
+ Enabled: true
44
+ Lint/EmptyInPattern: # new in 1.16
45
+ Enabled: true
46
+ Lint/IncompatibleIoSelectWithFiberScheduler: # new in 1.21
47
+ Enabled: true
48
+ Lint/LambdaWithoutLiteralBlock: # new in 1.8
49
+ Enabled: true
50
+ Lint/NoReturnInBeginEndBlocks: # new in 1.2
51
+ Enabled: true
52
+ Lint/NonAtomicFileOperation: # new in 1.31
53
+ Enabled: true
54
+ Lint/NumberedParameterAssignment: # new in 1.9
55
+ Enabled: true
56
+ Lint/OrAssignmentToConstant: # new in 1.9
57
+ Enabled: true
58
+ Lint/RedundantDirGlobSort: # new in 1.8
59
+ Enabled: true
60
+ Lint/RefinementImportMethods: # new in 1.27
61
+ Enabled: true
62
+ Lint/RequireRangeParentheses: # new in 1.32
63
+ Enabled: true
64
+ Lint/RequireRelativeSelfPath: # new in 1.22
65
+ Enabled: true
66
+ Lint/SymbolConversion: # new in 1.9
67
+ Enabled: true
68
+ Lint/ToEnumArguments: # new in 1.1
69
+ Enabled: true
70
+ Lint/TripleQuotes: # new in 1.9
71
+ Enabled: true
72
+ Lint/UnexpectedBlockArity: # new in 1.5
73
+ Enabled: true
74
+ Lint/UnmodifiedReduceAccumulator: # new in 1.1
75
+ Enabled: true
76
+ Lint/UselessRuby2Keywords: # new in 1.23
77
+ Enabled: true
78
+ Naming/BlockForwarding: # new in 1.24
79
+ Enabled: true
80
+ Security/CompoundHash: # new in 1.28
81
+ Enabled: true
82
+ Security/IoMethods: # new in 1.22
83
+ Enabled: true
84
+ Style/AndOr:
85
+ EnforcedStyle: conditionals
86
+ Style/InfiniteLoop:
87
+ Enabled: false
88
+ Style/ArgumentsForwarding: # new in 1.1
89
+ Enabled: true
90
+ Style/CollectionCompact: # new in 1.2
91
+ Enabled: true
92
+ Style/DocumentDynamicEvalDefinition: # new in 1.1
93
+ Enabled: true
94
+ Style/EmptyHeredoc: # new in 1.32
95
+ Enabled: true
96
+ Style/EndlessMethod: # new in 1.8
97
+ Enabled: true
98
+ Style/EnvHome: # new in 1.29
99
+ Enabled: true
100
+ Style/FetchEnvVar: # new in 1.28
101
+ Enabled: true
102
+ Style/FileRead: # new in 1.24
103
+ Enabled: true
104
+ Style/FileWrite: # new in 1.24
105
+ Enabled: true
106
+ Style/FrozenStringLiteralComment:
107
+ EnforcedStyle: always_true
108
+ Style/HashConversion: # new in 1.10
109
+ Enabled: true
110
+ Style/HashExcept: # new in 1.7
111
+ Enabled: true
112
+ Style/IfWithBooleanLiteralBranches: # new in 1.9
113
+ Enabled: true
114
+ Style/InPatternThen: # new in 1.16
115
+ Enabled: true
116
+ Style/MagicCommentFormat: # new in 1.35
117
+ Enabled: true
118
+ Style/MapCompactWithConditionalBlock: # new in 1.30
119
+ Enabled: true
120
+ Style/MapToHash: # new in 1.24
121
+ Enabled: true
122
+ Style/MultilineInPatternThen: # new in 1.16
123
+ Enabled: true
124
+ Style/NegatedIfElseCondition: # new in 1.2
125
+ Enabled: true
126
+ Style/NestedFileDirname: # new in 1.26
127
+ Enabled: true
128
+ Style/NilLambda: # new in 1.3
129
+ Enabled: true
130
+ Style/NumberedParameters: # new in 1.22
131
+ Enabled: true
132
+ Style/NumberedParametersLimit: # new in 1.22
133
+ Enabled: true
134
+ Style/ObjectThen: # new in 1.28
135
+ Enabled: true
136
+ Style/OpenStructUse: # new in 1.23
137
+ Enabled: true
138
+ Style/QuotedSymbols: # new in 1.16
139
+ Enabled: true
140
+ Style/RedundantArgument: # new in 1.4
141
+ Enabled: true
142
+ Style/RedundantInitialize: # new in 1.27
143
+ Enabled: true
144
+ Style/RedundantSelfAssignmentBranch: # new in 1.19
145
+ Enabled: true
146
+ Style/SelectByRegexp: # new in 1.22
147
+ Enabled: true
148
+ Style/StringChars: # new in 1.12
149
+ Enabled: true
150
+ Style/SwapValues: # new in 1.1
151
+ Enabled: true
152
+ Style/ClassAndModuleChildren:
153
+ Enabled: false
154
+ Style/StringConcatenation:
155
+ Enabled: false
156
+ Style/RescueModifier:
157
+ Enabled: false
158
+ Style/YodaCondition:
159
+ Enabled: false
160
+ Lint/AmbiguousRegexpLiteral:
161
+ Enabled: false
162
+ Style/WordArray:
163
+ Enabled: false
164
+ Style/Semicolon:
165
+ Enabled: false
166
+ Naming/MethodName:
167
+ Enabled: false
168
+ Style/EmptyMethod:
169
+ Enabled: false
170
+ Layout/EmptyLinesAroundClassBody:
171
+ Enabled: true
172
+ EnforcedStyle: empty_lines_except_namespace
173
+ Layout/EmptyLinesAroundModuleBody:
174
+ Enabled: true
175
+ EnforcedStyle: empty_lines_except_namespace
data/CHANGES.md CHANGED
@@ -1,5 +1,12 @@
1
+ 1.1.0.pre1 (10/17/2022)
2
+ -----
3
+ * modernize syntax using Rubocop
4
+ * use czmq-ffi-gen 1.1.0.pre1
5
+ * require Ruby >= 2.7.x
6
+
1
7
  1.0.0 (01/08/2021)
2
8
  -----
9
+ * use czmq-ffi-gen 1.0.x
3
10
  * modernized project
4
11
 
5
12
  0.13.1 (03/04/2018)
@@ -132,7 +139,7 @@
132
139
 
133
140
  0.3.0 (04/13/2016)
134
141
  -----
135
- * port CZTop::Poller to zmq_poller_*() functions so it supports thread-safe
142
+ * port CZTop::Poller to `zmq_poller_*()` functions so it supports thread-safe
136
143
  sockets as well
137
144
  * extract niche features to CZTop::Poller::Aggregated
138
145
  * fix taxi system example
data/Gemfile CHANGED
@@ -3,3 +3,8 @@ gemspec
3
3
 
4
4
  # useful when working on czmq-ffi-gen in parallel
5
5
  # gem "czmq-ffi-gen", path: "../czmq-ffi-gen"
6
+
7
+ group :development do
8
+ gem 'codecov', require: false
9
+ gem 'simplecov', require: false
10
+ end
data/README.md CHANGED
@@ -1,4 +1,6 @@
1
- ![Specs status](https://github.com/paddor/cztop/workflows/Specs/badge.svg)
1
+ ![Specs status](https://github.com/paddor/cztop/workflows/STABLE%20API/badge.svg)
2
+ ![Specs status](https://github.com/paddor/cztop/workflows/DRAFT%20API/badge.svg)
3
+ [![codecov](https://codecov.io/gh/paddor/cztop/branch/master/graph/badge.svg?token=TnjOba97R7)](https://codecov.io/gh/paddor/cztop)
2
4
 
3
5
  # CZTop
4
6
 
@@ -0,0 +1,22 @@
1
+ #!/bin/sh -x
2
+ # vim: ft=sh
3
+ set -e
4
+ mkdir -p ~/src
5
+ cd ~/src
6
+
7
+ case "$CZMQ_VERSION" in
8
+ HEAD)
9
+ echo "Using HEAD and compiling with --enable-drafts ..."
10
+ git clone https://github.com/zeromq/czmq czmq
11
+ CONFIGURE_OPTS="--enable-drafts=yes"
12
+ ;;
13
+ *)
14
+ echo '$CZMQ_VERSION not set.'
15
+ exit 1
16
+ esac
17
+
18
+ cd czmq
19
+ ./autogen.sh
20
+ ./configure --prefix=$HOME $CONFIGURE_OPTS
21
+ make
22
+ make install
data/ci/install-libzmq ADDED
@@ -0,0 +1,22 @@
1
+ #!/bin/sh -x
2
+ # vim: ft=sh
3
+ set -e
4
+ mkdir -p ~/src
5
+ cd ~/src
6
+
7
+ case "$ZMQ_VERSION" in
8
+ HEAD)
9
+ echo "Using HEAD and compiling with --enable-drafts ..."
10
+ git clone https://github.com/zeromq/libzmq libzmq
11
+ CONFIGURE_OPTS="--enable-drafts=yes"
12
+ ;;
13
+ *)
14
+ echo '$ZMQ_VERSION not set.'
15
+ exit 1
16
+ esac
17
+
18
+ cd libzmq
19
+ ./autogen.sh
20
+ ./configure --prefix=$HOME $CONFIGURE_OPTS
21
+ make
22
+ make install
data/cztop.gemspec CHANGED
@@ -11,7 +11,7 @@ Gem::Specification.new do |spec|
11
11
  spec.summary = %q{CZMQ Ruby binding based on the generated low-level FFI bindings of CZMQ}
12
12
  spec.homepage = "https://rubygems.org/gems/cztop"
13
13
  spec.license = "ISC"
14
- spec.required_ruby_version = Gem::Requirement.new(">= 2.5.0")
14
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.7.0")
15
15
 
16
16
  spec.metadata["homepage_uri"] = spec.homepage
17
17
  spec.metadata["source_code_uri"] = "https://github.com/paddor/cztop"
@@ -22,7 +22,7 @@ Gem::Specification.new do |spec|
22
22
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
23
  spec.require_paths = ["lib"]
24
24
 
25
- spec.add_runtime_dependency "czmq-ffi-gen", "~> 1.0"
25
+ spec.add_runtime_dependency "czmq-ffi-gen", "~> 1.1.0.pre1"
26
26
 
27
27
  spec.add_development_dependency "bundler"
28
28
  spec.add_development_dependency "rake"
@@ -31,4 +31,5 @@ Gem::Specification.new do |spec|
31
31
  spec.add_development_dependency "rspec-given", "~> 3.8.0"
32
32
  spec.add_development_dependency "pry"
33
33
  spec.add_development_dependency "yard"
34
+ spec.add_development_dependency "rubocop", "~> 1.36.0"
34
35
  end
data/lib/cztop/actor.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module CZTop
2
4
  # Represents a CZMQ::FFI::Zactor.
3
5
  #
@@ -33,6 +35,7 @@ module CZTop
33
35
  #
34
36
  # @see http://api.zeromq.org/czmq3-0:zactor
35
37
  class Actor
38
+
36
39
  include HasFFIDelegate
37
40
  extend CZTop::HasFFIDelegate::ClassMethods
38
41
  include ZsockOptions
@@ -40,12 +43,15 @@ module CZTop
40
43
  include PolymorphicZsockMethods
41
44
  include ::CZMQ::FFI
42
45
 
46
+
43
47
  # Raised when trying to interact with a terminated actor.
44
48
  class DeadActorError < RuntimeError; end
45
49
 
50
+
46
51
  # @return [Exception] the exception that crashed this actor, if any
47
52
  attr_reader :exception
48
53
 
54
+
49
55
  # Creates a new actor. Either pass a callback directly or a block. The
50
56
  # block will be called for every received message.
51
57
  #
@@ -60,15 +66,16 @@ module CZTop
60
66
  # @yieldparam pipe [Socket::PAIR]
61
67
  # @see #process_messages
62
68
  def initialize(callback = nil, c_args = nil, &handler)
63
- @running = true
64
- @mtx = Mutex.new
65
- @callback = callback || handler
66
- @callback = shim(@callback) unless @callback.is_a? ::FFI::Pointer
67
- ffi_delegate = Zactor.new(@callback, c_args)
69
+ @running = true
70
+ @mtx = Mutex.new
71
+ @callback = callback || handler
72
+ @callback = shim(@callback) unless @callback.is_a? ::FFI::Pointer
73
+ ffi_delegate = Zactor.new(@callback, c_args)
68
74
  attach_ffi_delegate(ffi_delegate)
69
- options.sndtimeo = 20#ms # see #<<
75
+ options.sndtimeo = 20 # ms # see #<<
70
76
  end
71
77
 
78
+
72
79
  # Send a message to the actor.
73
80
  # @param message [Object] message to send to the actor, see {Message.coerce}
74
81
  # @return [self] so it's chainable
@@ -88,7 +95,8 @@ module CZTop
88
95
  else
89
96
  begin
90
97
  @mtx.synchronize do
91
- raise DeadActorError if not @running
98
+ raise DeadActorError unless @running
99
+
92
100
  message.send_to(self)
93
101
  end
94
102
  rescue IO::EAGAINWaitWritable
@@ -109,19 +117,23 @@ module CZTop
109
117
  retry
110
118
  end
111
119
  end
120
+
112
121
  self
113
122
  end
114
123
 
124
+
115
125
  # Receive a message from the actor.
116
126
  # @return [Message]
117
127
  # @raise [DeadActorError] if actor is terminated
118
128
  def receive
119
129
  @mtx.synchronize do
120
- raise DeadActorError if not @running
130
+ raise DeadActorError unless @running
131
+
121
132
  super
122
133
  end
123
134
  end
124
135
 
136
+
125
137
  # Same as {#<<}, but also waits for a response from the actor and returns
126
138
  # it.
127
139
  # @param message [Message] the request to the actor
@@ -129,9 +141,11 @@ module CZTop
129
141
  # @raise [ArgumentError] if the message is "$TERM" (use {#terminate})
130
142
  def request(message)
131
143
  @mtx.synchronize do
132
- raise DeadActorError if not @running
144
+ raise DeadActorError unless @running
145
+
133
146
  message = Message.coerce(message)
134
- raise ArgumentError, "use #terminate" if TERM == message[0]
147
+ raise ArgumentError, 'use #terminate' if TERM == message[0]
148
+
135
149
  message.send_to(self)
136
150
  Message.receive_from(self)
137
151
  end
@@ -140,6 +154,7 @@ module CZTop
140
154
  retry
141
155
  end
142
156
 
157
+
143
158
  # Sends a message according to a "picture".
144
159
  # @see zsock_send() on http://api.zeromq.org/czmq3-0:zsock
145
160
  # @note Mainly added for {Beacon}. If implemented there, it wouldn't be
@@ -151,11 +166,13 @@ module CZTop
151
166
  # @return [void]
152
167
  def send_picture(picture, *args)
153
168
  @mtx.synchronize do
154
- raise DeadActorError if not @running
169
+ raise DeadActorError unless @running
170
+
155
171
  Zsock.send(ffi_delegate, picture, *args)
156
172
  end
157
173
  end
158
174
 
175
+
159
176
  # Thread-safe {PolymorphicZsockMethods#wait}.
160
177
  # @return [Integer]
161
178
  def wait
@@ -164,12 +181,14 @@ module CZTop
164
181
  end
165
182
  end
166
183
 
184
+
167
185
  # Tells the actor to terminate and waits for it. Idempotent.
168
186
  # @return [Boolean] whether it died just now (+false+ if it was dead
169
187
  # already)
170
188
  def terminate
171
189
  @mtx.synchronize do
172
- return false if not @running
190
+ return false unless @running
191
+
173
192
  Message.new(TERM).send_to(self)
174
193
  await_handler_death
175
194
  true
@@ -179,19 +198,23 @@ module CZTop
179
198
  retry
180
199
  end
181
200
 
201
+
182
202
  # @return [Boolean] whether this actor is dead (terminated or crashed)
183
203
  def dead?
184
204
  !@running
185
205
  end
186
206
 
207
+
187
208
  # @return [Boolean] whether this actor has crashed
188
209
  # @see #exception
189
210
  def crashed?
190
211
  !!@exception # if set, it has crashed
191
212
  end
192
213
 
214
+
193
215
  private
194
216
 
217
+
195
218
  # Shims the given handler. The shim is used to do the handshake, to
196
219
  # {#process_messages}, and ensure we're notified when the handler has
197
220
  # terminated.
@@ -200,35 +223,37 @@ module CZTop
200
223
  # @return [FFI::Function] the callback function to be passed to the zactor
201
224
  # @raise [ArgumentError] if invalid handler given
202
225
  def shim(handler)
203
- raise ArgumentError, "invalid handler" if !handler.respond_to?(:call)
226
+ raise ArgumentError, 'invalid handler' unless handler.respond_to?(:call)
204
227
 
205
- @handler_thread = nil
228
+ @handler_thread = nil
206
229
  @handler_dead_signal = Queue.new # used for signaling
207
230
 
208
231
  Zactor.fn do |pipe_delegate, _args|
209
- begin
210
- @mtx.synchronize do
211
- @handler_thread = Thread.current
212
- @pipe = Socket::PAIR.from_ffi_delegate(pipe_delegate)
213
- @pipe.signal # handshake, so zactor_new() returns
214
- end
215
- process_messages(handler)
216
- rescue Exception
217
- @exception = $!
218
- ensure
219
- signal_shimmed_handler_death
232
+ @mtx.synchronize do
233
+ @handler_thread = Thread.current
234
+ @pipe = Socket::PAIR.from_ffi_delegate(pipe_delegate)
235
+ @pipe.signal # handshake, so zactor_new() returns
220
236
  end
237
+
238
+ process_messages(handler)
239
+ rescue Exception
240
+ @exception = $ERROR_INFO
241
+ ensure
242
+ signal_shimmed_handler_death
221
243
  end
222
244
  end
223
245
 
246
+
224
247
  # @return [Boolean] whether the handler is a Ruby object, like a simple
225
248
  # block (as opposed to a FFI::Pointer to a C function)
226
249
  def handler_shimmed?
227
250
  !!@handler_thread # if it exists, it's shimmed
228
251
  end
229
252
 
253
+
230
254
  # the command which causes an actor handler to terminate
231
- TERM = "$TERM"
255
+ TERM = '$TERM'
256
+
232
257
 
233
258
  # Successively receive messages that were sent to the actor and
234
259
  # yield them to the given handler to process them. The a pipe (a
@@ -256,12 +281,14 @@ module CZTop
256
281
  end
257
282
  end
258
283
 
284
+
259
285
  # Receives the next message even across any interrupts.
260
286
  # @return [Message] the next message
261
287
  def next_message
262
288
  @pipe.receive
263
289
  end
264
290
 
291
+
265
292
  # Creates a new thread that will signal the definitive termination of the
266
293
  # Ruby handler.
267
294
  #
@@ -286,6 +313,7 @@ module CZTop
286
313
  end
287
314
  end
288
315
 
316
+
289
317
  # Waits for the C or Ruby handler to die.
290
318
  # @return [void]
291
319
  def await_handler_death
@@ -303,5 +331,6 @@ module CZTop
303
331
  @running = false
304
332
  end
305
333
  end
334
+
306
335
  end
307
336
  end