@@ -571,9 +571,7 @@ Some things to note about the above code:
571571
572572* A timer is represented by ` Temporalio::Workflow.sleep ` .
573573 * 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.
577575 * Each timer accepts a ` Cancellation ` , but if none is given, it defaults to ` Temporalio::Workflow.cancellation ` .
578576* ` Temporalio::Workflow.wait_condition ` accepts a block that waits until the evaluated block result is truthy, then
579577 returns the value.
@@ -586,7 +584,10 @@ Some things to note about the above code:
586584#### Workflow Fiber Scheduling and Cancellation
587585
588586Workflows 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.
590591
591592Every workflow contains a ` Temporalio::Cancellation ` at ` Temporalio::Workflow.cancellation ` . This is canceled when the
592593workflow 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:
678679 nil key for dynamic). ` []= ` or ` store ` can be called on these to update the handlers, though defined handlers are
679680 encouraged over runtime-set ones.
680681
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+
681685` Temporalio::Workflow::ContinueAsNewError ` can be raised to continue-as-new the workflow. It accepts positional args and
682686defaults the workflow to the same as the current, though it can be changed with the ` workflow ` kwarg. See API
683687documentation for other details.
@@ -714,15 +718,15 @@ Ruby workflows. This means there are several things workflows cannot do such as:
714718
715719* Perform IO (network, disk, stdio, etc)
716720* Access/alter external mutable state
717- * Do any threading
721+ * Do any threading or blocking calls
718722* Do anything using the system clock (e.g. ` Time.Now ` )
719723* Make any random calls
720724* Make any not-guaranteed-deterministic calls
721725
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.
726730
727731#### Workflow Testing
728732
@@ -928,24 +932,22 @@ See the `WorkflowReplayer` API documentation for more details.
928932
929933#### Advanced Workflow Safety and Escaping
930934
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.
935938
936939##### Durable Fiber Scheduler
937940
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.
942944
943945Users can pass a block to ` Temporalio::Workflow::Unsafe.durable_scheduler_disabled ` to not use the durable scheduler.
944946This 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.
949951
950952Also, by default anything that relies on IO wait that is not inside ` durable_scheduler_disabled ` will fail. It is
951953recommended 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
957959
958960##### Illegal Call Tracing
959961
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 ` .
963965
964966When an illegal call is encountered, an exception is thrown. In advanced cases there may be a need to allow an illegal
965967call that is known to be used deterministically. This code can be in a block passed to
0 commit comments