Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

Timer timing issue

オープン
#201 コメント 1 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

評価

難易度
5/5
見積もり時間
1週間以上
初心者へのやさしさ
25/100
issue の種類
バグ
明瞭さ
説明が足りない
活発さ
停滞
技術スタック
ruby

調査の方向性

state_manager.rb と、issue で説明されている history_window のイベント処理ループから始めます。sleep の完了とタイマーの発火が 1 つの履歴バッチで到着するワークフローシナリオを再現し、現在の動作を、引用されている Java SDK および Rust SDK の動作と比較します。この issue には、まだ合意された実装も Definition of Done もありません。

索引モデルが issue の本文から書いたものです。

説明

temporal-ruby Timer timing issue

Scenario:

  • Timer started (30 minutes)
  • Sleep started by workflow code (15 minute)
  • Worker goes down
  • Sleep ends
  • Timer fires.
  • Worker comes back up
  • Worker receives a history containing the sleep finishing followed by timer firing.

The workflow thus receives two TIMER_FIRED events in its history at once. Now what should happen?

What’s happening in temporal-ruby today

It processes the timers in order. Sleep first, then the other timer. The workflow completes first, and it’s not allowed to do anything after the workflow has completed. Thus, if the timer issues a command, the task will fail with Temporal::WorkflowAlreadyCompletingError.

Attempted solution

My first attempt was to early-out in state_manager.rb

        history_window.events.each do |event|
          apply_event(event)
          break if if workflow_finished?
        end

This fixed my problem and is logical; the workflow will execute the same as it would have if the worker had never gone down. But, it will silently drop events.
I asked Maxim what other SDKs do…

Other SDKs’ behaviors

According to Maxim:

Temporal processes new events in batches. One batch per workflow task. It applies all the events before running workflow code. So in case of Java or Go, for example the Futures that correspond to timer will be set to ready before running any workflow threads. This way workflow can check if any of these Futures are ready to decide what to do next.

Signals have similar properties, but they use callbacks in Java and some other SDKs. Temporal SDK schedules callback threads before running workflow threads. This way workflow cannot complete before the callback threads were called.

Then in case of Java SDK it is going to make the main workflow thread eligible to run. But it still will run only after all other threads executed and all other Futures resolved.
Without this functionality you guaranteed to lose signals if they are delivered as callbacks.

Rust core does the same

Java implementation - we can a see that callbacks (timer in this case) have a higher priority than the main thread (which is awoken by the sleep in this case).

What now?

Changing temporal-ruby's behavior is obviously somewhat tricky and would cause version changes if not done in a version-safe way. We might take this fix on but want to work with the community.

  • Should we fix this?
  • Implementation suggestions for the fix itself?
  • Version safety. I'm guessing we should add a configuration that changes this behavior that folks can opt into.
主要言語
Ruby
スター
288
フォーク
113
平均マージ
10日 15時間
マージ済み PR(30日)
2

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

coinbase/temporal-ruby のほかの issue

coinbase/temporal-ruby の issue をすべて見る

似ている issue

Ruby の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。