@@ -946,19 +946,21 @@ workflow will not progress until fixed.
946
946
The sandbox is not foolproof and non-determinism can still occur. It is simply a best-effort way to catch bad code
947
947
early. Users are encouraged to define their workflows in files with no other side effects.
948
948
949
- The sandbox offers a mechanism to pass through modules from outside the sandbox. By default this already includes all
949
+ The sandbox offers a mechanism to " pass through" modules from outside the sandbox. By default this already includes all
950
950
standard library modules and Temporal modules. ** For performance and behavior reasons, users are encouraged to pass
951
- through all third party modules whose calls will be deterministic.** This includes modules containing the activities to
952
- be referenced in workflows. See "Passthrough Modules" below on how to do this.
951
+ through all modules whose calls will be deterministic.** In particular, this advice extends to modules containing the
952
+ activities to be referenced in workflows, and modules containing dataclasses and Pydantic models, which can be
953
+ particularly expensive to import. See "Passthrough Modules" below on how to do this.
953
954
954
955
If you are getting an error like:
955
956
956
957
> temporalio.worker.workflow_sandbox._ restrictions.RestrictedWorkflowAccessError: Cannot access
957
958
> http.client.IncompleteRead.\_\_ mro_entries\_\_ from inside a workflow. If this is code from a module not used in a
958
959
> workflow or known to only be used deterministically from a workflow, mark the import as pass through.
959
960
960
- Then you are either using an invalid construct from the workflow, this is a known limitation of the sandbox, or most
961
- commonly this is from a module that is safe to pass through (see "Passthrough Modules" section below).
961
+ Then either:
962
+ - [ Most commonly] This is from a module that is safe to pass through (see "Passthrough Modules" section below).
963
+ - You're using an invalid construct from the workflow, this is a known limitation of the sandbox, or
962
964
963
965
##### How the Sandbox Works
964
966
@@ -967,12 +969,13 @@ The sandbox is made up of two components that work closely together:
967
969
* Global state isolation
968
970
* Restrictions preventing known non-deterministic library calls
969
971
970
- Global state isolation is performed by using ` exec ` . Upon workflow start, the file that the workflow is defined in is
971
- imported into a new sandbox created for that workflow run. In order to keep the sandbox performant a known set of
972
- "passthrough modules" are passed through from outside of the sandbox when they are imported. These are expected to be
973
- side-effect free on import and have their non-deterministic aspects restricted. By default the entire Python standard
974
- library, ` temporalio ` , and a couple of other modules are passed through from outside of the sandbox. To update this
975
- list, see "Customizing the Sandbox".
972
+ Global state isolation is performed by using ` exec ` . Upon workflow start, and every time that the workflow is replayed,
973
+ the file that the workflow is defined in is re-imported into a new sandbox created for that workflow run. In order to
974
+ keep the sandbox performant, not all modules are re-imported in this way: instead, a known set of "passthrough modules"
975
+ are obtained as references to the already-imported module _ outside_ the sandbox. These modules should be side-effect
976
+ free on import and if they have any non-deterministic functions then these should be restricted by sandbox restriction
977
+ rules. By default the entire Python standard library, ` temporalio ` , and a couple of other modules are "passed through"
978
+ in this way from outside of the sandbox. To update this list, see "Customizing the Sandbox".
976
979
977
980
Restrictions preventing known non-deterministic library calls are achieved using proxy objects on modules wrapped around
978
981
the custom importer set in the sandbox. Many restrictions apply at workflow import time and workflow run time, while
@@ -984,7 +987,7 @@ and isn't restricted, see "Customizing the Sandbox".
984
987
##### Avoiding the Sandbox
985
988
986
989
There are three increasingly-scoped ways to avoid the sandbox. Users are discouraged from avoiding the sandbox if
987
- possible.
990
+ possible, except for passing through safe modules, which is recommended .
988
991
989
992
To remove restrictions around a particular block of code, use ` with temporalio.workflow.unsafe.sandbox_unrestricted(): ` .
990
993
The workflow will still be running in the sandbox, but no restrictions for invalid library calls will be applied.
@@ -1011,11 +1014,12 @@ is immutable and contains three fields that can be customized, but only two have
1011
1014
###### Passthrough Modules
1012
1015
1013
1016
By default the sandbox completely reloads non-standard-library and non-Temporal modules for every workflow run. To make
1014
- the sandbox quicker and use less memory when importing known-side-effect-free third party modules, they can be marked
1017
+ the sandbox quicker and use less memory when importing known-side-effect-free modules, they can be marked
1015
1018
as passthrough modules.
1016
1019
1017
1020
** For performance and behavior reasons, users are encouraged to pass through all third party modules whose calls will be
1018
- deterministic.**
1021
+ deterministic.** In particular, this advice extends to modules containing the activities to be referenced in workflows,
1022
+ and modules containing dataclasses and Pydantic models, which can be particularly expensive to import.
1019
1023
1020
1024
One way to pass through a module is at import time in the workflow file using the ` imports_passed_through ` context
1021
1025
manager like so:
0 commit comments