@@ -571,9 +571,7 @@ Some things to note about the above code:
571
571
572
572
* A timer is represented by ` Temporalio::Workflow.sleep ` .
573
573
* Timers are also started on ` Temporalio::Workflow.timeout ` .
574
- * _ Technically_ ` Kernel.sleep ` and ` Timeout.timeout ` also delegate to the above calls, but the more explicit workflow
575
- forms are encouraged because they accept more options and are not subject to Ruby standard library implementation
576
- changes.
574
+ * ` Kernel.sleep ` and ` Timeout.timeout ` are considered illegal by default.
577
575
* Each timer accepts a ` Cancellation ` , but if none is given, it defaults to ` Temporalio::Workflow.cancellation ` .
578
576
* ` Temporalio::Workflow.wait_condition ` accepts a block that waits until the evaluated block result is truthy, then
579
577
returns the value.
@@ -586,7 +584,10 @@ Some things to note about the above code:
586
584
#### Workflow Fiber Scheduling and Cancellation
587
585
588
586
Workflows are backed by a custom, deterministic ` Fiber::Scheduler ` . All fiber calls inside a workflow use this scheduler
589
- to ensure coroutines run deterministically.
587
+ to ensure coroutines run deterministically. Although this means that ` Kernel.sleep ` and ` Mutex ` and such should work and
588
+ since they are Fiber-aware, Temporal intentionally disables their use by default to prevent accidental use. See
589
+ "Workflow Logic Constraints" and "Advanced Workflow Safety and Escaping" for more details, and see "Workflow Utilities"
590
+ for alternatives.
590
591
591
592
Every workflow contains a ` Temporalio::Cancellation ` at ` Temporalio::Workflow.cancellation ` . This is canceled when the
592
593
workflow is canceled. For all workflow calls that accept a cancellation token, this is the default. So if a workflow is
@@ -678,6 +679,9 @@ from workflows including:
678
679
nil key for dynamic). ` []= ` or ` store ` can be called on these to update the handlers, though defined handlers are
679
680
encouraged over runtime-set ones.
680
681
682
+ There are also classes for ` Temporalio::Workflow::Mutex ` , ` Temporalio::Workflow::Queue ` , and
683
+ ` Temporalio::Workflow::SizedQueue ` that are workflow-safe wrappers around the standard library forms.
684
+
681
685
` Temporalio::Workflow::ContinueAsNewError ` can be raised to continue-as-new the workflow. It accepts positional args and
682
686
defaults the workflow to the same as the current, though it can be changed with the ` workflow ` kwarg. See API
683
687
documentation for other details.
@@ -714,15 +718,15 @@ Ruby workflows. This means there are several things workflows cannot do such as:
714
718
715
719
* Perform IO (network, disk, stdio, etc)
716
720
* Access/alter external mutable state
717
- * Do any threading
721
+ * Do any threading or blocking calls
718
722
* Do anything using the system clock (e.g. ` Time.Now ` )
719
723
* Make any random calls
720
724
* Make any not-guaranteed-deterministic calls
721
725
722
- This means you can't even call ` puts ` or logger calls outside of ` Temporalio::Workflow.logger ` because they use mutexes
723
- which may be hit during periods of high-contention, but they are not completely disabled since users may do quick
724
- debugging with them. See the [ Advanced Workflow Safety and Escaping] ( #advanced-workflow-safety-and-escaping ) section if
725
- needing to work around this.
726
+ This means you can't even use logger calls outside of ` Temporalio::Workflow.logger ` because they use mutexes which may
727
+ be hit during periods of high-contention, but they are not completely disabled since users may do quick debugging with
728
+ them. See the [ Advanced Workflow Safety and Escaping] ( #advanced-workflow-safety-and-escaping ) section if needing to work
729
+ around this.
726
730
727
731
#### Workflow Testing
728
732
@@ -928,24 +932,22 @@ See the `WorkflowReplayer` API documentation for more details.
928
932
929
933
#### Advanced Workflow Safety and Escaping
930
934
931
- Workflows use a custom fiber scheduler to make things like certain blocking calls and timeouts durable. There is also
932
- call tracing to prevent accidentally making illegal workflow calls. But sometimes in advanced situations, workarounds
933
- may be needed. This section describes advanced situations working with the workflow Fiber scheduler and illegal call
934
- tracer.
935
+ Workflows use a custom fiber scheduler to make fibers durable. There is also call tracing to prevent accidentally making
936
+ illegal workflow calls. But sometimes in advanced situations, workarounds may be needed. This section describes advanced
937
+ situations working with the workflow Fiber scheduler and illegal call tracer.
935
938
936
939
##### Durable Fiber Scheduler
937
940
938
- The custom fiber scheduler that powers workflows makes otherwise-local, blocking things durable. This is why ` sleep ` and
939
- ` Timeout.timeout ` and ` Queue ` and other things work durably. However, there are cases where it may be desired for these
940
- to work locally inside a workflow such as for logging or ` puts ` or other side-effecting, known-non-deterministic
941
- aspects.
941
+ By default, Temporal considers ` Logger ` , ` sleep ` , ` Timeout.timeout ` , ` Queue ` , etc illegal. However, there are cases
942
+ where it may be desired for these to work locally inside a workflow such as for logging or other side-effecting,
943
+ known-non-deterministic aspects.
942
944
943
945
Users can pass a block to ` Temporalio::Workflow::Unsafe.durable_scheduler_disabled ` to not use the durable scheduler.
944
946
This should be used any time the scheduler needs to be bypassed, e.g. for local stdout. Not doing this can cause
945
- workflows to get hung in high contention situations. For instance, if there is a ` puts ` or a logger (that isn't the
946
- safe-to-use ` Temporalio::Workflow.logger ` ) in a workflow, _ technically_ Ruby surrounds the IO writes with a mutex and
947
- in extreme high contention that mutex may durably block and then the workflow task may complete causing hung workflows
948
- because no event comes to wake the mutex.
947
+ workflows to get hung in high contention situations. For instance, if there is a logger (that isn't the safe-to-use
948
+ ` Temporalio::Workflow.logger ` ) in a workflow, _ technically_ Ruby surrounds the IO writes with a mutex and in extreme
949
+ high contention that mutex may durably block and then the workflow task may complete causing hung workflows because no
950
+ event comes to wake the mutex.
949
951
950
952
Also, by default anything that relies on IO wait that is not inside ` durable_scheduler_disabled ` will fail. It is
951
953
recommended to put things that need this in ` durable_scheduler_disabled ` , but if the durable scheduler is still needed
@@ -957,9 +959,9 @@ Note `durable_scheduler_disabled` implies `illegal_call_tracing_disabled` (see n
957
959
958
960
##### Illegal Call Tracing
959
961
960
- Ruby workflow threads employ a ` TracePoint ` to catch illegal calls such as ` Time.now ` or ` Thread.new ` . The set of
961
- illegal calls can be configured via the ` illegal_workflow_calls ` parameter when creating a worker. The default set is at
962
- ` Temporalio::Worker.default_illegal_workflow_calls ` .
962
+ Ruby workflow threads employ a ` TracePoint ` to catch illegal calls such as ` sleep ` or ` Time.now ` or ` Thread.new ` . The
963
+ set of illegal calls can be configured via the ` illegal_workflow_calls ` parameter when creating a worker. The default
964
+ set is at ` Temporalio::Worker.default_illegal_workflow_calls ` .
963
965
964
966
When an illegal call is encountered, an exception is thrown. In advanced cases there may be a need to allow an illegal
965
967
call that is known to be used deterministically. This code can be in a block passed to
0 commit comments