While trying to speed up some object creation and utilizing ruby 3 ractors I unfortunately ran into “bug”.
To demonstrate it I created a little test app:
require 'dry-struct'
require 'json'
class Something < Dry::Struct
attribute :name, Dry::Types["string"]
attribute :type, Dry::Types["string"].optional.default('Dry::Struct'.freeze)
def to_json(opts={})
as_json(opts).to_json(opts)
end
def as_json(opts={})
to_hash
end
end
class SomethingElse
attr_accessor :name
def initialize(name:)
@name = name
end
def to_json(opts={})
as_json(opts).to_json(opts)
end
def as_json(opts={})
{
name: name,
type: "SimpleClass"
}
end
end
puts SomethingElse.new(name: "No Ractor").to_json
processor1 = Ractor.new do
SomethingElse.new(name: "With Ractor")
end
puts processor1.take.to_json
puts Something.new(name: "No Ractor").to_json
processor2 = Ractor.new do
Something.new(name: "With Ractor")
end
puts processor2.take.to_json
which creates the following output:
{"name":"No Ractor","type":"SimpleClass"}
<internal:ractor>:267: warning: Ractor is experimental, and the behavior may change in future versions of Ruby! Also there are many implementation issues.
{"name":"With Ractor","type":"SimpleClass"}
{"name":"No Ractor","type":"Dry::Struct"}
#<Thread:0x00005602eb4eec30 run> terminated with exception (report_on_exception is true):
.bundle/ruby/3.0.0/gems/dry-struct-1.4.0/lib/dry/struct/class_interface.rb:265:in `new': defined in a different Ractor (RuntimeError)
from test.rb:47:in `block in <main>'
<internal:ractor>:694:in `take': thrown by remote Ractor. (Ractor::RemoteError)
from test.rb:50:in `<main>'
.bundle/ruby/3.0.0/gems/dry-struct-1.4.0/lib/dry/struct/class_interface.rb:265:in `new': defined in a different Ractor (RuntimeError)
from test.rb:47:in `block in <main>'
I understand that the ractor feature is experimental but this seams to be a problem. After looking at the code it seams like I can probably recreate the error with dry-schema as it creates a closure that is not shareable with a ractor. Any Idea how this can be solved?
Thank you.