ractorize 0.0.10 → 0.0.11

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: f7827fd6bd911724e81479f2966f75aafb825c1320fb870531b08db1079b5b9c
4
- data.tar.gz: bf7da9b30088e3554637b646ef4bb5ceab085d076f3e0097c68f236d647b3baf
3
+ metadata.gz: 4600c739ac97a907068b19020d82d72c695df5dba8e47c56620cada3418de052
4
+ data.tar.gz: ea91548851760e76582f06e9dc6e49bc4626a648442ce7503b59b40df6c47ccf
5
5
  SHA512:
6
- metadata.gz: e7858c116a76c408a6c341ee8007a91a50e4caae089978564d2704535845248e14272c18909bd8f4e5458e6dbe97262afb2acc088fd79412f5231ff1f56d3de1
7
- data.tar.gz: 0e3b0165b66489c83b3dc7ebe37873ad6600e4fb9239eeaa326440d700112bf13255a67532f84fdfd15c3d37afcb93285742a4a50e5eef0993231bab1c5976ff
6
+ metadata.gz: 198181e33f7fdab8ca7a98713d39b0dadffe240273353e6d9f28de6fbda3be139d9cd4f92df99e678231a05bcb41a276547f16d2553bb6e1a09d56e632cb615f
7
+ data.tar.gz: adfd5a6ab472f0d1b3479ed51cc401b0112bc563798594863067c7f6c4cd3284210a1e7a148e2ffc9645607dd3bbab5e977ffcc60201ae62dea0edc71f40b30f
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## [0.0.11] - 2026-07-31
2
+
3
+ - Log if a RactorizedRactor is taken down via ClosedError
4
+
1
5
  ## [0.0.10] - 2026-06-30
2
6
 
3
7
  - Handle thunks being cloned
data/README.md CHANGED
@@ -274,6 +274,15 @@ Note that if you call either `#__close__` or `#__join__` on the object, then the
274
274
 
275
275
  An easy way to avoid the deadlock is just don't make any use of such an object after closing it.
276
276
 
277
+ ### Objects returned from a method called on a ractorized object might be cloned!
278
+
279
+ You might have a "void" method where you don't care about the return value but it also doesn't
280
+ return `nil` instead it just returns the last expression arbitrarily.
281
+
282
+ This return value (or parts of it) will be cloned by CRuby/Ractor if it's not shareable!
283
+
284
+ Confusing stuff can happen with certain types of objects when cloned, such as open files.
285
+
277
286
  ## Fine print
278
287
 
279
288
  Ractors are still experimental and so this gem is also still experimental.
@@ -10,22 +10,7 @@ module Ractorize
10
10
  tracker = Tracker.new
11
11
 
12
12
  loop do
13
- # SimpleCov branch coverage doesn't like that we aren't testing not matching anything
14
- # but this does result in an error unlike case/when so no point in checking that.
15
- # :nocov:
16
- case receive
17
- # :nocov:
18
- in :track_ractorized_object, ractorized_object
19
- tracker.track_ractorized_object(ractorized_object)
20
- in :cleanup_after_ractorized_object, ractorized_object_id
21
- tracker.cleanup_after_ractorized_object(ractorized_object_id)
22
- in :track_thunk, thunk_id, thunk_ractor
23
- tracker.track_thunk(thunk_id, thunk_ractor)
24
- in :thunk_cloned, old_thunk_id, new_thunk_id, thunk_ractor
25
- tracker.thunk_cloned(old_thunk_id, new_thunk_id, thunk_ractor)
26
- in :cleanup_after_thunk, thunk_id
27
- tracker.cleanup_after_thunk(thunk_id)
28
- end
13
+ tracker.send(*receive)
29
14
  rescue TrackingRactor::ClosedError
30
15
  # do nothing
31
16
  end
@@ -3,6 +3,8 @@ require_relative "../base_ractor"
3
3
  module Ractorize
4
4
  class RactorizedObject < BasicObject
5
5
  class RactorizedRactor < ::BaseRactor
6
+ class UnexpectedClosedError < StandardError; end
7
+
6
8
  class << self
7
9
  def new(name: nil)
8
10
  super do
@@ -25,15 +27,13 @@ module Ractorize
25
27
 
26
28
  klass.new(*args.freeze, **opts.freeze, &block)
27
29
  else
28
- # :nocov:
30
+ # simplecov:disable
29
31
  raise "Invalid mode #{mode}"
30
- # :nocov:
32
+ # simplecov:enable
31
33
  end
32
34
 
33
35
  loop do
34
- # rubocop:disable Lint/UselessAssignment
35
36
  value = method_name = method_args = opts = return_port = thunk_ractor = block_given = nil
36
- # rubocop:enable Lint/UselessAssignment
37
37
  method_name, method_args, opts, return_port, thunk_ractor, block_given = receive
38
38
 
39
39
  case method_name
@@ -80,9 +80,9 @@ module Ractorize
80
80
  # TODO: handle error situation
81
81
  break
82
82
  else
83
- # :nocov:
83
+ # simplecov:disable
84
84
  raise "Not sure how to handle outcome_type #{outcome_type}"
85
- # :nocov:
85
+ # simplecov:enable
86
86
  end
87
87
  end
88
88
 
@@ -100,10 +100,10 @@ module Ractorize
100
100
  rescue IOError => e
101
101
  # Unclear why this sometimes manifests as this error instead of ClosedError but
102
102
  # need to handle them both.
103
- # :nocov:
103
+ # simplecov:disable
104
104
  raise unless e.message == "closed stream"
105
- # :nocov:
106
- rescue Ractor::ClosedError
105
+ # simplecov:enable
106
+ rescue RactorizedRactor::ClosedError
107
107
  # Whoa... this error inherits from StopIteration and will kill the loop!!!
108
108
  # Nothing really to do here but keep the loop going and handle other
109
109
  # method calls to the ractorized object from other ractors.
@@ -112,19 +112,28 @@ module Ractorize
112
112
  end
113
113
 
114
114
  nil
115
+ rescue RactorizedRactor::ClosedError => e
116
+ # simplecov:disable
117
+ puts "unexpected closed error!"
118
+ puts e.backtrace
119
+ error = UnexpectedClosedError.new
120
+ error.set_backtrace(e.backtrace)
121
+
122
+ raise error
123
+ # simplecov:enable
115
124
  end
116
125
 
117
126
  nil
118
127
  # object
119
128
  rescue => e
120
- # :nocov:
129
+ # simplecov:disable
121
130
  puts
122
131
  puts "an unhandled error!!! #{e.class} #{e.message} #{e}"
123
132
  puts e.backtrace
124
133
  puts
125
134
 
126
135
  raise
127
- # :nocov:
136
+ # simplecov:enable
128
137
  end
129
138
  end
130
139
  end
@@ -67,9 +67,9 @@ module Ractorize
67
67
  @__ractor__ << [:__target_object_id__, return_port].freeze
68
68
  @__target_object_id__ = return_port.receive
69
69
  else
70
- # :nocov:
70
+ # simplecov:disable
71
71
  ::Kernel.raise "Invalid mode #{mode}"
72
- # :nocov:
72
+ # simplecov:enable
73
73
  end
74
74
 
75
75
  @__object_id__ = ::Object.instance_method(:object_id).bind_call(self)
@@ -131,9 +131,9 @@ module Ractorize
131
131
  # Seems SimpleCov branch coverage doesn't like that we don't test the non-exhaustive
132
132
  # pattern path, but since that's purely defensive I have no interest in testing it.
133
133
 
134
- # :nocov:
134
+ # simplecov:disable
135
135
  case data
136
- # :nocov:
136
+ # simplecov:enable
137
137
  in :return, value
138
138
  stop = true
139
139
  in :yield, [yielded_args, yielded_opts, yielded_block], block_result_port
@@ -167,19 +167,19 @@ module Ractorize
167
167
  value = return_port.receive
168
168
  return_port.close
169
169
 
170
- # :nocov:
170
+ # simplecov:disable
171
171
  ::Kernel.raise ::Ractorize::Thunk::EscapingRactorError if ::Ractorize::Thunk === value
172
- # :nocov:
172
+ # simplecov:enable
173
173
 
174
174
  value
175
175
  end
176
176
  end
177
177
 
178
178
  def respond_to?(method_name, include_all = false)
179
- # :nocov:
179
+ # simplecov:disable
180
180
  # This line is only here for when commenting out < BasicObject when debugging stuff
181
181
  return super if ::Object === self
182
- # :nocov:
182
+ # simplecov:enable
183
183
 
184
184
  respond_to_missing?(method_name, include_all)
185
185
  end
@@ -7,9 +7,9 @@ module Ractorize
7
7
  def new
8
8
  super do
9
9
  # SimpleCov seems to want us to handle the case where nothing matches but that would be an error
10
- # :nocov:
10
+ # simplecov:disable
11
11
  case receive
12
- # :nocov:
12
+ # simplecov:enable
13
13
  in :__close__
14
14
  # do nothing
15
15
  in :success, value
data/src/ractorize.rb CHANGED
@@ -25,16 +25,16 @@ module Ractorize
25
25
  @auto_freeze = @auto_freeze ? @auto_freeze.dup : []
26
26
 
27
27
  unless Ractor.shareable?(target)
28
- # :nocov:
28
+ # simplecov:disable
29
29
  raise "#{target} isn't shareable so can't use it to auto-freeze"
30
- # :nocov:
30
+ # simplecov:enable
31
31
  end
32
32
 
33
33
  @auto_freeze << if class_or_proc
34
34
  unless Ractor.shareable?(class_or_proc)
35
- # :nocov:
35
+ # simplecov:disable
36
36
  raise "#{class_or_proc} isn't shareable so can't use it to auto-freeze"
37
- # :nocov:
37
+ # simplecov:enable
38
38
  end
39
39
 
40
40
  [target, class_or_proc]
@@ -49,16 +49,16 @@ module Ractorize
49
49
  @move_arg = @move_arg ? @move_arg.dup : []
50
50
 
51
51
  unless Ractor.shareable?(target)
52
- # :nocov:
52
+ # simplecov:disable
53
53
  raise "#{target} isn't shareable so can't use it to auto-freeze"
54
- # :nocov:
54
+ # simplecov:enable
55
55
  end
56
56
 
57
57
  @move_arg << if class_or_proc
58
58
  unless Ractor.shareable?(class_or_proc)
59
- # :nocov:
59
+ # simplecov:disable
60
60
  raise "#{class_or_proc} isn't shareable so can't use it to auto-freeze"
61
- # :nocov:
61
+ # simplecov:enable
62
62
  end
63
63
 
64
64
  [target, class_or_proc]
@@ -189,9 +189,9 @@ module Ractorize
189
189
  when :done
190
190
  break
191
191
  else
192
- # :nocov:
192
+ # simplecov:disable
193
193
  ::Kernel.raise "Unknown class_by_arg arg type #{arg_type}"
194
- # :nocov:
194
+ # simplecov:enable
195
195
  end
196
196
  end
197
197
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ractorize
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.10
4
+ version: 0.0.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Miles Georgi
@@ -46,13 +46,16 @@ required_ruby_version: !ruby/object:Gem::Requirement
46
46
  - - ">="
47
47
  - !ruby/object:Gem::Version
48
48
  version: 4.0.0
49
+ - - "<"
50
+ - !ruby/object:Gem::Version
51
+ version: '4.1'
49
52
  required_rubygems_version: !ruby/object:Gem::Requirement
50
53
  requirements:
51
54
  - - ">="
52
55
  - !ruby/object:Gem::Version
53
56
  version: '0'
54
57
  requirements: []
55
- rubygems_version: 4.0.10
58
+ rubygems_version: 4.0.16
56
59
  specification_version: 4
57
60
  summary: Turn objects into ractors with ease!
58
61
  test_files: []