[Bug] Some common uses of ActiveModel fail in workflows due to sync construct use
I maintainer di solito rispondono entro 1 giorno
Valutazione
- Difficoltà
- 5/5
- Tempo stimato
- Più di una settimana
- Idoneità per principianti
- 30/100
- Tipo di issue
- Bug
- Chiarezza
- Da chiarire
- Stato di attività
- Ferma
- Stack tecnologico
- ruby
- Ambito
- backend, distributed-systems
Direzione di ricerca
Inizia riproducendo l’esempio mostrato di ActiveModel::Model e ActiveModel::Attributes all’interno di un workflow e ispeziona i frame attribute_methods.rb e illegal_call_tracer.rb nel trace. Determina quali operazioni di ActiveModel invocano ConcurrentMap o Thread::Mutex, quindi definisci e verifica un comportamento sicuro per i workflow con una copertura di regressione; il lavoro è completato quando l’uso comune di ActiveModel non attiva più l’errore di non determinismo del workflow.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Describe the bug
Many common uses of ActiveModel use ConcurrentMap under the hood which uses Thread::Mutex which is forbidden in workflows.
We believe this can be replicated simply by accessing an attribute that doesn't exist. We also believe this can be replicated using a model set like:
module MyCompany
module Messages
class Foo
include Message
attribute :some_field_1, :string
attribute :some_field_2, :string
attribute :some_field_3, ObjectType.for(Array), :default => []
attribute :some_field_4, :boolean, :default => false
attribute :some_field_5, :boolean, :default => false
end
end
module Message
extend ActiveSupport::Concern
include ActiveModel::Model
include ActiveModel::Attributes
include ActiveModel::Serializers::JSON
included do
def as_json(options = {})
super(options).merge(::JSON.create_id => self.class.name)
end
end
class_methods do
def json_create(data)
new(**data.except(JSON.create_id))
end
end
end
end
This can give stack traces like:
W, [2025-10-24T12:22:16.291089 #70269] WARN -- : Cannot access Thread::Mutex synchronize from inside a workflow, reason: disallowed. If this is known to be safe, the code can be run in a Temporalio::Workflow::Unsafe.illegal_call_tracing_disabled block. {:attempt=>1, :namespace=>"default", :run_id=>"019a1773-c113-74ff-924d-7c51d86cd682", :task_queue=>"deliverable-orchestration", :workflow_id=>"59824eb54dc4fa489c15c372", :workflow_type=>"OrchestrationWorkflowV2"} (Temporalio::Workflow::NondeterminismError)
/path/to/gems/temporalio-0.6.0-arm64-darwin/lib/temporalio/internal/worker/workflow_instance/illegal_call_tracer.rb:112:in `block in initialize'
/path/to/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/collection/map/mri_map_backend.rb:25:in `compute_if_absent'
/path/to/gems/activemodel-6.1.7.10/lib/active_model/attribute_methods.rb:400:in `attribute_method_matchers_matching'
/path/to/gems/activemodel-6.1.7.10/lib/active_model/attribute_methods.rb:506:in `matched_attribute_method'
/path/to/gems/activemodel-6.1.7.10/lib/active_model/attribute_methods.rb:494:in `respond_to?'
/path/to/gems/activemodel-6.1.7.10/lib/active_model/attribute_assignment.rb:48:in `_assign_attribute'
/path/to/gems/activemodel-6.1.7.10/lib/active_model/attribute_assignment.rb:42:in `block in _assign_attributes'
/path/to/gems/activemodel-6.1.7.10/lib/active_model/attribute_assignment.rb:41:in `each'
/path/to/gems/activemodel-6.1.7.10/lib/active_model/attribute_assignment.rb:41:in `_assign_attributes'
/path/to/gems/activemodel-6.1.7.10/lib/active_model/attribute_assignment.rb:34:in `assign_attributes'
/path/to/gems/activemodel-6.1.7.10/lib/active_model/model.rb:81:in `initialize'
/path/to/gems/activemodel-6.1.7.10/lib/active_model/attributes.rb:77:in `initialize'
/path/to/models/my_models.rb:99:in `new'
And for cases where it's an invalid attribute access via method_missing, it can give traces like:
/path/to/gems/temporalio-1.0.0-arm64-darwin/lib/temporalio/internal/worker/workflow_instance/illegal_call_tracer.rb:112:in `block in initialize'
/path/to/gems/concurrent-ruby-1.3.4/lib/concurrent-ruby/concurrent/collection/map/mri_map_backend.rb:25:in `compute_if_absent'
/path/to/gems/activemodel-6.1.7.3/lib/active_model/attribute_methods.rb:400:in `attribute_method_matchers_matching'
/path/to/gems/activemodel-6.1.7.3/lib/active_model/attribute_methods.rb:506:in `matched_attribute_method'
/path/to/gems/activemodel-6.1.7.3/lib/active_model/attribute_methods.rb:468:in `method_missing'
my_workflow_class.rb:52:in `block in execute'
my_workflow_class.rb:39:in `loop'
ConcurrentMap use is so pervasive in ActiveModel, it is unreasonable for us to ask users not to use anything relying on it. Also, it may be unreasonable to just alter our illegal trace detector to check backtrace for the active model because the use of mutexes can cause an issue like we hit with loggers (see https://temporal.io/blog/temporal-ruby-crash-proof-fibers#implicitly-used-sync-constructs).
The best solution may be a WorkflowSafeObject type of mixin that surrounds every call with Workflow::Unsafe::durable_scheduler_disabled.
- Lingua principale
- Ruby
- Stelle
- 207
- Fork
- 44
- Merge medio
- 1g 6h
- PR unite (30g)
- 19
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Nessun modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di temporalio/sdk-ruby
-
[Bug] JSON payload decoding raises ArgumentError with json 3.x (JSON.parse options are keyword-only)Forse già presa @chris-olszewski l’ha presa 7 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 88/100
temporalio/sdk-ruby#595 · 3 commenti · 1 assegnatario ·
I maintainer di solito rispondono entro 1 giorno
-
External Payload Storage Foundation - RubyForse già presa @jmaeagle99 l’ha presa 4 giorni fa. Aperta
temporalio/sdk-ruby#614 · 1 assegnatario ·
I maintainer di solito rispondono entro 1 giorno
-
bug
Difficoltà 3/5 Mezza giornata Idoneità per principianti 40/100
temporalio/sdk-ruby#613 ·
I maintainer di solito rispondono entro 1 giorno
-
Proposal: handle SIGTERM by default to initiate graceful worker shutdownForse già presa @eamsden l’ha presa 5 giorni fa. Aperta
temporalio/sdk-ruby#611 · 1 assegnatario ·
I maintainer di solito rispondono entro 1 giorno
-
[Feature Request] Add thread lifecycle hook to `Worker::ThreadPool`Forse già presa @GregoryTravis l’ha presa 49 giorni fa. Apertaenhancement
temporalio/sdk-ruby#563 · 1 assegnatario ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di temporalio/sdk-ruby
Issue simili
-
feature
Difficoltà 2/5 1-3 ore Idoneità per principianti 60/100
manyfold3d/manyfold#7346 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
🐞 bug pending triage
Difficoltà 2/5 1-3 ore Idoneità per principianti 65/100
CircuitVerse/CircuitVerse#8025 · 2 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
we-promise/sure#4199 ·
I maintainer di solito rispondono entro 1 giorno
-
Zibi version number updateAperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 62/100
riscv/riscv-unified-db#2738 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 62/100
scanaislop/aislop#482 ·
I maintainer di solito rispondono entro 1 giorno