@@ -946,19 +946,12 @@ 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
- If you are getting an error like:
955
-
956
- > temporalio.worker.workflow_sandbox._ restrictions.RestrictedWorkflowAccessError: Cannot access
957
- > http.client.IncompleteRead.\_\_ mro_entries\_\_ from inside a workflow. If this is code from a module not used in a
958
- > workflow or known to only be used deterministically from a workflow, mark the import as pass through.
959
-
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).
962
955
963
956
##### How the Sandbox Works
964
957
@@ -967,12 +960,13 @@ The sandbox is made up of two components that work closely together:
967
960
* Global state isolation
968
961
* Restrictions preventing known non-deterministic library calls
969
962
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".
963
+ Global state isolation is performed by using ` exec ` . Upon workflow start, and every time that the workflow is replayed,
964
+ the file that the workflow is defined in is re-imported into a new sandbox created for that workflow run. In order to
965
+ keep the sandbox performant, not all modules are re-imported in this way: instead, a known set of "passthrough modules"
966
+ are obtained as references to the already-imported module _ outside_ the sandbox. These modules should be side-effect
967
+ free on import and, if they make any non-deterministic calls, then these should be restricted by sandbox restriction
968
+ rules. By default the entire Python standard library, ` temporalio ` , and a couple of other modules are "passed through"
969
+ in this way from outside of the sandbox. To update this list, see "Customizing the Sandbox".
976
970
977
971
Restrictions preventing known non-deterministic library calls are achieved using proxy objects on modules wrapped around
978
972
the custom importer set in the sandbox. Many restrictions apply at workflow import time and workflow run time, while
@@ -984,7 +978,7 @@ and isn't restricted, see "Customizing the Sandbox".
984
978
##### Avoiding the Sandbox
985
979
986
980
There are three increasingly-scoped ways to avoid the sandbox. Users are discouraged from avoiding the sandbox if
987
- possible.
981
+ possible, except for passing through safe modules, which is recommended .
988
982
989
983
To remove restrictions around a particular block of code, use ` with temporalio.workflow.unsafe.sandbox_unrestricted(): ` .
990
984
The workflow will still be running in the sandbox, but no restrictions for invalid library calls will be applied.
@@ -1011,11 +1005,12 @@ is immutable and contains three fields that can be customized, but only two have
1011
1005
###### Passthrough Modules
1012
1006
1013
1007
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
1008
+ the sandbox quicker and use less memory when importing known-side-effect-free modules, they can be marked
1015
1009
as passthrough modules.
1016
1010
1017
1011
** For performance and behavior reasons, users are encouraged to pass through all third party modules whose calls will be
1018
- deterministic.**
1012
+ deterministic.** In particular, this advice extends to modules containing the activities to be referenced in workflows,
1013
+ and modules containing dataclasses and Pydantic models, which can be particularly expensive to import.
1019
1014
1020
1015
One way to pass through a module is at import time in the workflow file using the ` imports_passed_through ` context
1021
1016
manager like so:
0 commit comments