[
https://issues.apache.org/jira/browse/AVRO-4256?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Maciej Mensfeld updated AVRO-4256:
----------------------------------
Description:
The {{avro}} Ruby gem (1.12.x) cannot be used inside
[Ractors|https://docs.ruby-lang.org/en/master/Ractor.html] on Ruby 4.0. Every
common operation - parsing schemas, serializing records, even reading constants
- fails with {{Ractor::IsolationError}} or {{{}RuntimeError{}}}.
This blocks any use of Ractors for parallel Avro serialization/deserialization.
h3. Root causes
*1. Non-shareable Set constants ({{{}lib/avro/schema.rb:24-31{}}})*
{{{}PRIMITIVE_TYPES{}}}, {{{}NAMED_TYPES{}}}, {{VALID_TYPES}} and their
{{_SYM}} variants are plain {{Set}} objects - not frozen, not Ractor-shareable.
*2. Un-shareable Proc/closure in method definitions
({{{}lib/avro/schema.rb:239{}}})*
{{Schema#to_s}} and other methods are defined with closures that capture
non-shareable state.
*3. Mutable module-level instance variables ({{{}lib/avro.rb:38-55{}}})*
{{{}@disable_enum_symbol_validation{}}},
{{{}@disable_field_default_validation{}}}, {{@disable_schema_name_validation}}
are mutable class-level state that non-main Ractors cannot access.
h3. Test output
{code:java}
Ruby version: 4.0.3
Avro version: 1.12.1
## 1. Access Avro::Schema::PRIMITIVE_TYPES constant in a Ractor
FAILED: Ractor::IsolationError: can not access non-shareable objects in
constant Avro::Schema::PRIMITIVE_TYPES by non-main Ractor.
## 2. Access Avro::Schema::VALID_TYPES constant in a Ractor
FAILED: Ractor::IsolationError: can not access non-shareable objects in
constant Avro::Schema::VALID_TYPES by non-main Ractor.
## 3. Parse an Avro schema inside a Ractor
FAILED: RuntimeError: defined with an un-shareable Proc in a different Ractor
## 4. Pass a pre-parsed Schema object into a Ractor
FAILED: RuntimeError: defined with an un-shareable Proc in a different Ractor
## 5. Encode a record using DatumWriter inside a Ractor
FAILED: Ractor::IsolationError: can not access non-shareable objects in
constant Avro::Schema::VALID_TYPES_SYM by non-main Ractor.
## 6. Read Avro.disable_enum_symbol_validation inside a Ractor
FAILED: Ractor::IsolationError: can not set instance variables of
classes/modules by non-main Ractors
{code}
h3. Suggested fixes
# Freeze all {{{}Set{}}}/{{{}Hash{}}}/{{{}Array{}}} constants with
{{Ractor.make_shareable}} or {{.freeze}}
# Replace closures with regular {{def}} method definitions instead of
{{define_method}} with blocks
# Replace mutable module-level {{@ivars}} with Ractor-local storage or frozen
configuration
h3. Reproduction script
Self-contained script using bundler/inline - save as {{avro_ractor_poc.rb}} and
run with {{{}ruby avro_ractor_poc.rb{}}}.
was:
```
h3. Description
The {{avro}} Ruby gem (1.12.x) cannot be used inside
[Ractors|https://docs.ruby-lang.org/en/master/Ractor.html] on Ruby 4.0. Every
common operation - parsing schemas, serializing records, even reading constants
- fails with {{Ractor::IsolationError}} or {{{}RuntimeError{}}}.
This blocks any use of Ractors for parallel Avro serialization/deserialization.
h3. Root causes
*1. Non-shareable Set constants ({{{}lib/avro/schema.rb:24-31{}}})*
{{{}PRIMITIVE_TYPES{}}}, {{{}NAMED_TYPES{}}}, {{VALID_TYPES}} and their
{{_SYM}} variants are plain {{Set}} objects - not frozen, not Ractor-shareable.
*2. Un-shareable Proc/closure in method definitions
({{{}lib/avro/schema.rb:239{}}})*
{{Schema#to_s}} and other methods are defined with closures that capture
non-shareable state.
*3. Mutable module-level instance variables ({{{}lib/avro.rb:38-55{}}})*
{{{}@disable_enum_symbol_validation{}}},
{{{}@disable_field_default_validation{}}}, {{@disable_schema_name_validation}}
are mutable class-level state that non-main Ractors cannot access.
h3. Test output
{code:java}
Ruby version: 4.0.3
Avro version: 1.12.1
## 1. Access Avro::Schema::PRIMITIVE_TYPES constant in a Ractor
FAILED: Ractor::IsolationError: can not access non-shareable objects in
constant Avro::Schema::PRIMITIVE_TYPES by non-main Ractor.
## 2. Access Avro::Schema::VALID_TYPES constant in a Ractor
FAILED: Ractor::IsolationError: can not access non-shareable objects in
constant Avro::Schema::VALID_TYPES by non-main Ractor.
## 3. Parse an Avro schema inside a Ractor
FAILED: RuntimeError: defined with an un-shareable Proc in a different Ractor
## 4. Pass a pre-parsed Schema object into a Ractor
FAILED: RuntimeError: defined with an un-shareable Proc in a different Ractor
## 5. Encode a record using DatumWriter inside a Ractor
FAILED: Ractor::IsolationError: can not access non-shareable objects in
constant Avro::Schema::VALID_TYPES_SYM by non-main Ractor.
## 6. Read Avro.disable_enum_symbol_validation inside a Ractor
FAILED: Ractor::IsolationError: can not set instance variables of
classes/modules by non-main Ractors
{code}
h3. Suggested fixes
# Freeze all {{{}Set{}}}/{{{}Hash{}}}/{{{}Array{}}} constants with
{{Ractor.make_shareable}} or {{.freeze}}
# Replace closures with regular {{def}} method definitions instead of
{{define_method}} with blocks
# Replace mutable module-level {{@ivars}} with Ractor-local storage or frozen
configuration
h3. Reproduction script
Self-contained script using bundler/inline - save as {{avro_ractor_poc.rb}} and
run with {{{}ruby avro_ractor_poc.rb{}}}.
> Ruby gem incompatible with Ruby 4.0 Ractors: non-shareable constants,
> closures, and mutable class-level state
> -------------------------------------------------------------------------------------------------------------
>
> Key: AVRO-4256
> URL: https://issues.apache.org/jira/browse/AVRO-4256
> Project: Apache Avro
> Issue Type: Bug
> Components: ruby
> Affects Versions: 1.12.1
> Environment: Ruby 4.0.3 (2026-04-21), Linux x86_64, avro gem 1.12.1
> Reporter: Maciej Mensfeld
> Priority: Minor
> Labels: ruby
> Attachments: avro_ractor_poc.rb
>
> Original Estimate: 48h
> Remaining Estimate: 48h
>
> The {{avro}} Ruby gem (1.12.x) cannot be used inside
> [Ractors|https://docs.ruby-lang.org/en/master/Ractor.html] on Ruby 4.0. Every
> common operation - parsing schemas, serializing records, even reading
> constants - fails with {{Ractor::IsolationError}} or {{{}RuntimeError{}}}.
> This blocks any use of Ractors for parallel Avro
> serialization/deserialization.
> h3. Root causes
> *1. Non-shareable Set constants ({{{}lib/avro/schema.rb:24-31{}}})*
> {{{}PRIMITIVE_TYPES{}}}, {{{}NAMED_TYPES{}}}, {{VALID_TYPES}} and their
> {{_SYM}} variants are plain {{Set}} objects - not frozen, not
> Ractor-shareable.
> *2. Un-shareable Proc/closure in method definitions
> ({{{}lib/avro/schema.rb:239{}}})*
> {{Schema#to_s}} and other methods are defined with closures that capture
> non-shareable state.
> *3. Mutable module-level instance variables ({{{}lib/avro.rb:38-55{}}})*
> {{{}@disable_enum_symbol_validation{}}},
> {{{}@disable_field_default_validation{}}},
> {{@disable_schema_name_validation}} are mutable class-level state that
> non-main Ractors cannot access.
> h3. Test output
> {code:java}
> Ruby version: 4.0.3
> Avro version: 1.12.1
> ## 1. Access Avro::Schema::PRIMITIVE_TYPES constant in a Ractor
> FAILED: Ractor::IsolationError: can not access non-shareable objects in
> constant Avro::Schema::PRIMITIVE_TYPES by non-main Ractor.
> ## 2. Access Avro::Schema::VALID_TYPES constant in a Ractor
> FAILED: Ractor::IsolationError: can not access non-shareable objects in
> constant Avro::Schema::VALID_TYPES by non-main Ractor.
> ## 3. Parse an Avro schema inside a Ractor
> FAILED: RuntimeError: defined with an un-shareable Proc in a different
> Ractor
> ## 4. Pass a pre-parsed Schema object into a Ractor
> FAILED: RuntimeError: defined with an un-shareable Proc in a different
> Ractor
> ## 5. Encode a record using DatumWriter inside a Ractor
> FAILED: Ractor::IsolationError: can not access non-shareable objects in
> constant Avro::Schema::VALID_TYPES_SYM by non-main Ractor.
> ## 6. Read Avro.disable_enum_symbol_validation inside a Ractor
> FAILED: Ractor::IsolationError: can not set instance variables of
> classes/modules by non-main Ractors
> {code}
> h3. Suggested fixes
> # Freeze all {{{}Set{}}}/{{{}Hash{}}}/{{{}Array{}}} constants with
> {{Ractor.make_shareable}} or {{.freeze}}
> # Replace closures with regular {{def}} method definitions instead of
> {{define_method}} with blocks
> # Replace mutable module-level {{@ivars}} with Ractor-local storage or
> frozen configuration
> h3. Reproduction script
> Self-contained script using bundler/inline - save as {{avro_ractor_poc.rb}}
> and run with {{{}ruby avro_ractor_poc.rb{}}}.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)