Skip to content

Commit 64c20ad

Browse files
committed
Evolve sandbox documentation
1 parent 53d9ace commit 64c20ad

File tree

1 file changed

+18
-14
lines changed

1 file changed

+18
-14
lines changed

README.md

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -946,19 +946,21 @@ workflow will not progress until fixed.
946946
The sandbox is not foolproof and non-determinism can still occur. It is simply a best-effort way to catch bad code
947947
early. Users are encouraged to define their workflows in files with no other side effects.
948948

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
950950
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.
953954

954955
If you are getting an error like:
955956

956957
> temporalio.worker.workflow_sandbox._restrictions.RestrictedWorkflowAccessError: Cannot access
957958
> http.client.IncompleteRead.\_\_mro_entries\_\_ from inside a workflow. If this is code from a module not used in a
958959
> workflow or known to only be used deterministically from a workflow, mark the import as pass through.
959960
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
962964

963965
##### How the Sandbox Works
964966

@@ -967,12 +969,13 @@ The sandbox is made up of two components that work closely together:
967969
* Global state isolation
968970
* Restrictions preventing known non-deterministic library calls
969971

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".
976979

977980
Restrictions preventing known non-deterministic library calls are achieved using proxy objects on modules wrapped around
978981
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".
984987
##### Avoiding the Sandbox
985988

986989
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.
988991

989992
To remove restrictions around a particular block of code, use `with temporalio.workflow.unsafe.sandbox_unrestricted():`.
990993
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
10111014
###### Passthrough Modules
10121015

10131016
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
10151018
as passthrough modules.
10161019

10171020
**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.
10191023

10201024
One way to pass through a module is at import time in the workflow file using the `imports_passed_through` context
10211025
manager like so:

0 commit comments

Comments
 (0)