Repository navigation
workflow: support using a shared sandbox for all workflow invocations - #310
Conversation
Importing everything on every workflow invocation is quite slow, especially when using pydantic or similar. I am planning to add automatic support for using pydantic to serialize/validate arguments, and regenerating the pydantic validators on every invocation will make it even more expensive. Using a shared sandbox eliminates that problem. Using a shared sandbox means that we still get all of the benefits of preventing nondeterminstic calls, but that modifications to global variables will stay visible. But I think a good workflow shouldn't really be using globals *anyway*, so... I think I'm planning to basically immediately make a PR that will switch the default to `share_sandboxes=True`, but for cleanliness I'm separating it. To do this, I: * Add a Sandbox class entered with enter() * Add a policy flag for it * Make `Workflows` responsible for producing a sandbox * Hold a sandbox-scoped lock while *importing* the module, to avoid weird cyclic init races. * A bunch of tweaks to serde's registries Questions: * Are we nervous about sharing a sandbox for genuinely concurrent runs? If so, we can maintain a pool of unused sandboxes and create a new one when necessary.
Each workflow run in the shared sandbox is sequential and serialized, right? Like workflow A starts an event loop, run to suspension, shutdown that loop, THEN workflow B can only start a new event loop after that, and do B things? I think I'm okay with shared sandboxes for this case. |
We will run multiple workflows in separate threads, so they can be genuinely concurrent. A and B in the same sandbox at the same time. If we are nervous about that, we can make it so that a sandbox is in use by one thread at a time, and can then get reused later. |
I feel like it's probably fine with the asyncio |
Yeah, the event loop isn't shared. |
vercel-internal-core -------------------- 0.1.3 - 2026-08-26 ------------------ Internal -------- - Support disabling HTTP timeouts for selected SDK operations while preserving the client default elsewhere. (#307) vercel-connect -------------- 0.1.1 - 2026-08-26 ------------------ - Update dependencies. vercel-queue ------------ 0.8.1 - 2026-08-26 ------------------ Documentation ------------- - Remove documentation and examples for `asgi_app` in preparation for its removal. (#309) vercel-sandbox -------------- 0.5.0 - 2026-08-26 ------------------ Features -------- - Add sync and async `fork_sandbox(...)` support for creating a sandbox from an existing named sandbox with optional configuration overrides. (#257) - Add `region` and `failover_regions` configuration for sandbox creation, forks, and updates, plus multi-region snapshot availability reporting. (#308) Bug Fixes --------- - Allow Sandbox process waits and log streams to remain idle longer than the session HTTP timeout. (#307) vercel-workflow --------------- 0.10.0 - 2026-08-26 ------------------- Breaking Changes ---------------- - Use type annotations on workflows and step to allow passing Pydantic models and dataclasses. (#317) - This is a breaking change, because type annotations will now be enforced. Passing a `dict` when the declaration expects a `list` will fail. (#317) - Pydantic models and dataclasses can no longer be passed to `@serializable` or `register_serializable()`. Annotate the workflow or step parameter or return value with their type instead. (#317) Features -------- - `get_workflow_metadata()` returns the current run's `WorkflowInfo` (run id, workflow name, start time, deployment URL, and feature flags), callable from a workflow body or a step body — mirroring the JS SDK's `getWorkflowMetadata()`. (#320) - One current limitation is that `started_at` is `None` from inside a step. (#320) - `BaseHook.wait()` accepts `metadata` to record on the hook, and `get_hook_by_token()` reads it back for a resumer. (#301) - A step can raise `RetryableError` to control when its next attempt runs. (#302) - Accept `specVersion` 7 sealed noop event logs. (#319) - A workflow or step can attach plaintext metadata to its run with `set_attributes()`. (#303) - Add a `share_sandboxes` parameter to `SandboxPolicy` to enable reusing already created sandboxes instead of creating a new one on each invocation. This speeds up workflows but means that modifications to global state may persist between invocations. (#310) - Expose unstable API to serve workflow HTTP endpoint from your own web framework. (#294) - Added semi-internal manifest API for TS tools and e2e test. (#296) Bug Fixes --------- - Fix failing or even crashing cipher calls inside the workflow sandbox. (#305) - Support resuming hooks with payload in the queue message. (#300) - Fixed nulls rejected by server, requiring Pydantic 2.12 or newer. (#321) - Fixed workflow and step calls with both positional-or-keyword parameters and `*args` failing during replay because their arguments were recorded in an unbindable shape. (#312) Internal -------- - Construct the protocol models by Python field name. (#322) vercel ------ 0.11.0 - 2026-08-26 ------------------- Features -------- - Expose `get_deadline()` for reading the current Function invocation deadline. (#306) - Answer workflow health checks for both queue-based transport and HTTP. (#292) - Add support to read the sealed (`encp`) workflow payloads (X25519 + AES-GCM) an outside writer addresses to a run, under the `encryption` extra. (#297) Bug Fixes --------- - Remove upper bounds on aggregate Sandbox and Workflow dependencies so sibling releases cannot make the `vercel` package un-installable. (#334) - Start a workflow run even when its queue message arrives before the `run_created` event has landed. (#284) Internal -------- - The Workflows implementation now ships in the separate `vercel-workflow` distribution, which `vercel` depends on, so `vercel.workflow` imports keep working without installing anything extra. (#299) vercel-apscheduler ------------------ 0.3.0 - 2026-08-26 ------------------ Breaking Changes ---------------- - The managed Redis backend was removed. The integration now always runs on its managed job store (Vercel Runtime Cache); a configured default `RedisJobStore` is rejected at import, `VERCEL_APSCHEDULER_BACKEND` accepts only `cache`, and the `redis` dependency is gone. The scheduler's durable identity now always derives from the builder-assigned subscriber id (previously the Redis `jobs_key`); the `scheduler_id` option still pins an identity explicitly. (#286) vercel-celery ------------- 0.7.5 - 2026-08-26 ------------------ - Update dependencies. vercel-django-tasks ------------------- 0.7.0 - 2026-08-26 ------------------ Features -------- - Add a Vercel Queues backend for Django Tasks and use it by default when no task backends are configured. (#291) vercel-dramatiq --------------- 0.7.4 - 2026-08-26 ------------------ - Update dependencies.
vercel-headers -------------- 0.7.2 - 2026-08-31 ------------------ Bug Fixes --------- - Accept request objects with concrete header implementations in the IP address and geolocation type annotations. (#337) vercel-internal-core -------------------- 0.1.3 - 2026-08-31 ------------------ Internal -------- - Support disabling HTTP timeouts for selected SDK operations while preserving the client default elsewhere. (#307) vercel-oidc ----------- 0.8.1 - 2026-08-31 ------------------ - Update dependencies. vercel-connect -------------- 0.1.1 - 2026-08-31 ------------------ - Update dependencies. vercel-internal-telemetry ------------------------- 0.7.3 - 2026-08-31 ------------------ - Update dependencies. vercel-queue ------------ 0.8.1 - 2026-08-31 ------------------ Bug Fixes --------- - Force embedded development servers to exit when graceful shutdown stalls. (#351) Documentation ------------- - Remove documentation and examples for `asgi_app` in preparation for its removal. (#309) vercel-sandbox -------------- 0.5.0 - 2026-08-31 ------------------ Features -------- - Add sync and async `fork_sandbox(...)` support for creating a sandbox from an existing named sandbox with optional configuration overrides. (#257) - Add `region` and `failover_regions` configuration for sandbox creation, forks, and updates, plus multi-region snapshot availability reporting. (#308) - Forward private ``__``-prefixed parameters to the Sandbox API. (#350) Bug Fixes --------- - Allow Sandbox process waits and log streams to remain idle longer than the session HTTP timeout. (#307) - Expose Linux process signals consistently on every SDK host platform. (#352) vercel-cache ------------ 0.7.3 - 2026-08-31 ------------------ - Update dependencies. vercel-workflow --------------- 0.10.0 - 2026-08-31 ------------------- Breaking Changes ---------------- - Make sleep() and retry delays treat numbers as seconds, not ms (#346) - This matches Python standard library APIs. (#346) - Use type annotations on workflows and step to allow passing Pydantic models and dataclasses. (#317) - This is a breaking change, because type annotations will now be enforced. Passing a `dict` when the declaration expects a `list` will fail. (#317) - Pydantic models and dataclasses can no longer be passed to `@serializable` or `register_serializable()`. Annotate the workflow or step parameter or return value with their type instead. (#317) Features -------- - Support `call_later`, `call_at`, and `now` in the event loop implementation. (#343) - This enables use of `asyncio.sleep()` as well as `asyncio.timeout` and the `timeout` parameter of `asyncio.wait_for`. (#343) - `get_workflow_metadata()` returns the current run's `WorkflowInfo` (run id, workflow name, start time, deployment URL, and feature flags), callable from a workflow body or a step body — mirroring the JS SDK's `getWorkflowMetadata()`. (#320) - One current limitation is that `started_at` is `None` from inside a step. (#320) - `BaseHook.wait()` accepts `metadata` to record on the hook, and `get_hook_by_token()` reads it back for a resumer. (#301) - A step can raise `RetryableError` to control when its next attempt runs. (#302) - Accept `specVersion` 7 sealed noop event logs. (#319) - Failed run and step events now preserve serialized error classes, messages, stacks, and causes. Failed runs also expose a plaintext `errorCode`. (#304) - A workflow or step can attach plaintext metadata to its run with `set_attributes()`. (#303) - Add a `share_sandboxes` parameter to `SandboxPolicy` to enable reusing already created sandboxes instead of creating a new one on each invocation. This speeds up workflows but means that modifications to global state may persist between invocations. (#310) - Support `timedelta` arguments for workflow `sleep()` and retry delays. (#342) - Expose unstable API to serve workflow HTTP endpoint from your own web framework. (#294) - Added semi-internal manifest API for TS tools and e2e test. (#296) Bug Fixes --------- - Fix failing or even crashing cipher calls inside the workflow sandbox. (#305) - Fail a workflow run with `HookConflictError` when another run already owns its hook token instead of leaving it running indefinitely. (#327) - Support resuming hooks with payload in the queue message. (#300) - Fix some bugs involving hooks arriving when the workflow was not yet blocked on them. (#339) - Fixed nulls rejected by server, requiring Pydantic 2.12 or newer. (#321) - Prevent workflows from having side effects while suspending. (#332) - `hook.dispose()` will now work properly in a `finally` block. (That is, the hook will be disposed only when the workflow is actually terminating, and not every time it gets replayed.) (#332) - More reliably fail runs whose replay diverges from the event log. (#347) - Runs will now fail even in the case where the main thread of execution is not directly blocked on the suspension that is erroring. (#347) - Fixed workflow and step calls with both positional-or-keyword parameters and `*args` failing during replay because their arguments were recorded in an unbindable shape. (#312) Internal -------- - Remove a just-added return from a finally block. (#344) - Correct internal workflow type annotations found by checking untyped function bodies. (#337) - Refactored event replay. (#341) - Construct the protocol models by Python field name. (#322) vercel ------ 0.11.0 - 2026-08-31 ------------------- Features -------- - Expose `get_deadline()` for reading the current Function invocation deadline. (#306) - Answer workflow health checks for both queue-based transport and HTTP. (#292) - Add support to read the sealed (`encp`) workflow payloads (X25519 + AES-GCM) an outside writer addresses to a run, under the `encryption` extra. (#297) Bug Fixes --------- - Remove upper bounds on aggregate Sandbox and Workflow dependencies so sibling releases cannot make the `vercel` package un-installable. (#334) - Start a workflow run even when its queue message arrives before the `run_created` event has landed. (#284) Internal -------- - The Workflows implementation now ships in the separate `vercel-workflow` distribution, which `vercel` depends on, so `vercel.workflow` imports keep working without installing anything extra. (#299) vercel-apscheduler ------------------ 0.3.0 - 2026-08-31 ------------------ Breaking Changes ---------------- - The managed Redis backend was removed. The integration now always runs on its managed job store (Vercel Runtime Cache); a configured default `RedisJobStore` is rejected at import, `VERCEL_APSCHEDULER_BACKEND` accepts only `cache`, and the `redis` dependency is gone. The scheduler's durable identity now always derives from the builder-assigned subscriber id (previously the Redis `jobs_key`); the `scheduler_id` option still pins an identity explicitly. (#286) vercel-celery ------------- 0.7.5 - 2026-08-31 ------------------ - Update dependencies. vercel-django-tasks ------------------- 0.7.0 - 2026-08-31 ------------------ Features -------- - Add a Vercel Queues backend for Django Tasks and use it by default when no task backends are configured. (#291) vercel-dramatiq --------------- 0.7.4 - 2026-08-31 ------------------ - Update dependencies.
vercel-headers -------------- 0.7.2 - 2026-08-31 ------------------ Bug Fixes --------- - Accept request objects with concrete header implementations in the IP address and geolocation type annotations. (#337) vercel-internal-core -------------------- 0.1.3 - 2026-08-31 ------------------ Internal -------- - Support disabling HTTP timeouts for selected SDK operations while preserving the client default elsewhere. (#307) vercel-oidc ----------- 0.8.1 - 2026-08-31 ------------------ - Update dependencies. vercel-connect -------------- 0.1.1 - 2026-08-31 ------------------ - Update dependencies. vercel-internal-telemetry ------------------------- 0.7.3 - 2026-08-31 ------------------ - Update dependencies. vercel-queue ------------ 0.8.1 - 2026-08-31 ------------------ Bug Fixes --------- - Force embedded development servers to exit when graceful shutdown stalls. (#351) Documentation ------------- - Remove documentation and examples for `asgi_app` in preparation for its removal. (#309) vercel-sandbox -------------- 0.5.0 - 2026-08-31 ------------------ Features -------- - Add sync and async `fork_sandbox(...)` support for creating a sandbox from an existing named sandbox with optional configuration overrides. (#257) - Add `region` and `failover_regions` configuration for sandbox creation, forks, and updates, plus multi-region snapshot availability reporting. (#308) - Forward private ``__``-prefixed parameters to the Sandbox API. (#350) Bug Fixes --------- - Allow Sandbox process waits and log streams to remain idle longer than the session HTTP timeout. (#307) - Expose Linux process signals consistently on every SDK host platform. (#352) vercel-cache ------------ 0.7.3 - 2026-08-31 ------------------ - Update dependencies. vercel-workflow --------------- 0.10.0 - 2026-08-31 ------------------- Breaking Changes ---------------- - Make `await hook` never return `None` - Raises a new `HookDisposedError` instead of returning `None` when the hook has been disposed. It is now typed to return `T` instead of `T | None`. `async for` over a hook will stop iterating on disposal, still. - Make sleep() and retry delays treat numbers as seconds, not ms (#346) - This matches Python standard library APIs. (#346) - Use type annotations on workflows and step to allow passing Pydantic models and dataclasses. (#317) - This is a breaking change, because type annotations will now be enforced. Passing a `dict` when the declaration expects a `list` will fail. (#317) - Pydantic models and dataclasses can no longer be passed to `@serializable` or `register_serializable()`. Annotate the workflow or step parameter or return value with their type instead. (#317) Features -------- - Support `call_later`, `call_at`, and `now` in the event loop implementation. (#343) - This enables use of `asyncio.sleep()` as well as `asyncio.timeout` and the `timeout` parameter of `asyncio.wait_for`. (#343) - `get_workflow_metadata()` returns the current run's `WorkflowInfo` (run id, workflow name, start time, deployment URL, and feature flags), callable from a workflow body or a step body — mirroring the JS SDK's `getWorkflowMetadata()`. (#320) - One current limitation is that `started_at` is `None` from inside a step. (#320) - Make `HookEvent` an async context manager - This matches TS, which supports `using`. ``` # disposes the hook on block exit async with SomeHook.wait(...) as hook: res = await hook ``` - `BaseHook.wait()` accepts `metadata` to record on the hook, and `get_hook_by_token()` reads it back for a resumer. (#301) - A step can raise `RetryableError` to control when its next attempt runs. (#302) - Accept `specVersion` 7 sealed noop event logs. (#319) - Failed run and step events now preserve serialized error classes, messages, stacks, and causes. Failed runs also expose a plaintext `errorCode`. (#304) - A workflow or step can attach plaintext metadata to its run with `set_attributes()`. (#303) - Add a `share_sandboxes` parameter to `SandboxPolicy` to enable reusing already created sandboxes instead of creating a new one on each invocation. This speeds up workflows but means that modifications to global state may persist between invocations. (#310) - Support `timedelta` arguments for workflow `sleep()` and retry delays. (#342) - Expose unstable API to serve workflow HTTP endpoint from your own web framework. (#294) - Added semi-internal manifest API for TS tools and e2e test. (#296) Bug Fixes --------- - Fix failing or even crashing cipher calls inside the workflow sandbox. (#305) - Fail a workflow run with `HookConflictError` when another run already owns its hook token instead of leaving it running indefinitely. (#327) - Support resuming hooks with payload in the queue message. (#300) - Fix some bugs involving hooks arriving when the workflow was not yet blocked on them. (#339) - Fixed nulls rejected by server, requiring Pydantic 2.12 or newer. (#321) - Prevent workflows from having side effects while suspending. (#332) - `hook.dispose()` will now work properly in a `finally` block. (That is, the hook will be disposed only when the workflow is actually terminating, and not every time it gets replayed.) (#332) - More reliably fail runs whose replay diverges from the event log. (#347) - Runs will now fail even in the case where the main thread of execution is not directly blocked on the suspension that is erroring. (#347) - Fixed workflow and step calls with both positional-or-keyword parameters and `*args` failing during replay because their arguments were recorded in an unbindable shape. (#312) Internal -------- - Remove a just-added return from a finally block. (#344) - Correct internal workflow type annotations found by checking untyped function bodies. (#337) - Refactored event replay. (#341) - Construct the protocol models by Python field name. (#322) vercel ------ 0.11.0 - 2026-08-31 ------------------- Features -------- - Expose `get_deadline()` for reading the current Function invocation deadline. (#306) - Answer workflow health checks for both queue-based transport and HTTP. (#292) - Add support to read the sealed (`encp`) workflow payloads (X25519 + AES-GCM) an outside writer addresses to a run, under the `encryption` extra. (#297) Bug Fixes --------- - Remove upper bounds on aggregate Sandbox and Workflow dependencies so sibling releases cannot make the `vercel` package un-installable. (#334) - Start a workflow run even when its queue message arrives before the `run_created` event has landed. (#284) Internal -------- - The Workflows implementation now ships in the separate `vercel-workflow` distribution, which `vercel` depends on, so `vercel.workflow` imports keep working without installing anything extra. (#299) vercel-apscheduler ------------------ 0.3.0 - 2026-08-31 ------------------ Breaking Changes ---------------- - The managed Redis backend was removed. The integration now always runs on its managed job store (Vercel Runtime Cache); a configured default `RedisJobStore` is rejected at import, `VERCEL_APSCHEDULER_BACKEND` accepts only `cache`, and the `redis` dependency is gone. The scheduler's durable identity now always derives from the builder-assigned subscriber id (previously the Redis `jobs_key`); the `scheduler_id` option still pins an identity explicitly. (#286) vercel-celery ------------- 0.7.5 - 2026-08-31 ------------------ - Update dependencies. vercel-django-tasks ------------------- 0.7.0 - 2026-08-31 ------------------ Features -------- - Add a Vercel Queues backend for Django Tasks and use it by default when no task backends are configured. (#291) vercel-dramatiq --------------- 0.7.4 - 2026-08-31 ------------------ - Update dependencies.
vercel-headers -------------- 0.7.2 - 2026-09-01 ------------------ Bug Fixes --------- - Accept request objects with concrete header implementations in the IP address and geolocation type annotations. (#337) vercel-internal-core -------------------- 0.1.3 - 2026-09-01 ------------------ Internal -------- - Support disabling HTTP timeouts for selected SDK operations while preserving the client default elsewhere. (#307) vercel-oidc ----------- 0.8.1 - 2026-09-01 ------------------ - Update dependencies. vercel-connect -------------- 0.1.1 - 2026-09-01 ------------------ - Update dependencies. vercel-internal-telemetry ------------------------- 0.7.3 - 2026-09-01 ------------------ - Update dependencies. vercel-queue ------------ 0.8.1 - 2026-09-01 ------------------ Bug Fixes --------- - Force embedded development servers to exit when graceful shutdown stalls. (#351) Documentation ------------- - Remove documentation and examples for `asgi_app` in preparation for its removal. (#309) vercel-sandbox -------------- 0.5.0 - 2026-09-01 ------------------ Features -------- - Add sync and async `fork_sandbox(...)` support for creating a sandbox from an existing named sandbox with optional configuration overrides. (#257) - Add `region` and `failover_regions` configuration for sandbox creation, forks, and updates, plus multi-region snapshot availability reporting. (#308) - Forward private ``__``-prefixed parameters to the Sandbox API. (#350) Bug Fixes --------- - Allow Sandbox process waits and log streams to remain idle longer than the session HTTP timeout. (#307) - Expose Linux process signals consistently on every SDK host platform. (#352) vercel-cache ------------ 0.7.3 - 2026-09-01 ------------------ - Update dependencies. vercel-workflow --------------- 0.10.0 - 2026-09-01 ------------------- Breaking Changes ---------------- - Make `await hook` never return `None` (#353) Raises a new `HookDisposedError` instead of returning `None` when the hook has been disposed. It is now typed to return `T` instead of `T | None`. `async for` over a hook will stop iterating on disposal, still. - Make sleep() and retry delays treat numbers as seconds, not ms (#346) This matches Python standard library APIs. - Use type annotations on workflows and step to allow passing Pydantic models and dataclasses. (#317) This is a breaking change, because type annotations will now be enforced. Passing a `dict` when the declaration expects a `list` will fail. Pydantic models and dataclasses can no longer be passed to `@serializable` or `register_serializable()`. Annotate the workflow or step parameter or return value with their type instead. Features -------- - Support `call_later`, `call_at`, and `now` in the event loop implementation. (#343) This enables use of `asyncio.sleep()` as well as `asyncio.timeout` and the `timeout` parameter of `asyncio.wait_for`. - Add opt-in cancellable steps: `@workflows.step(cancellable=True)`. When `cancel()` is called on a cancellable step, we send a message on a stream that the step will listen for. If it gets a message, it will exit. Note that like regular asyncio tasks, `cancel()` does not cause the step to immediately become "cancelled". Waiting on it will still wait for the step to actually terminate. If there are still cancellable steps running when a workflow function completes, they will be cancelled and the workflow will wait for them to finish before terminating. - `get_workflow_metadata()` returns the current run's `WorkflowInfo` (run id, workflow name, start time, deployment URL, and feature flags), callable from a workflow body or a step body — mirroring the JS SDK's `getWorkflowMetadata()`. (#320) One current limitation is that `started_at` is `None` from inside a step. - Make `HookEvent` an async context manager (#354) This matches TS, which supports `using`. ``` # disposes the hook on block exit async with SomeHook.wait(...) as hook: res = await hook ``` - Add `HookEvent.get_conflict()` to check for a token conflict without waiting for hook data. - `BaseHook.wait()` accepts `metadata` to record on the hook, and `get_hook_by_token()` reads it back for a resumer. (#301) - A step can raise `RetryableError` to control when its next attempt runs. (#302) - Accept `specVersion` 7 sealed noop event logs. (#319) - Failed run and step events now preserve serialized error classes, messages, stacks, and causes. Failed runs also expose a plaintext `errorCode`. (#304) - A workflow or step can attach plaintext metadata to its run with `set_attributes()`. (#303) - Add a `share_sandboxes` parameter to `SandboxPolicy` to enable reusing already created sandboxes instead of creating a new one on each invocation. This speeds up workflows but means that modifications to global state may persist between invocations. (#310) - Support `timedelta` arguments for workflow `sleep()` and retry delays. (#342) - Expose unstable API to serve workflow HTTP endpoint from your own web framework. (#294) - Added semi-internal manifest API for TS tools and e2e test. (#296) Bug Fixes --------- - Fix failing or even crashing cipher calls inside the workflow sandbox. (#305) - Fail a workflow run with `HookConflictError` when another run already owns its hook token instead of leaving it running indefinitely. (#327) - Fix a bug that caused reusing a hook token after disposing the previous hook to conflict with the same workflow run. - Support resuming hooks with payload in the queue message. (#300) - Prevent recursive workflow sandbox imports on Windows and decode Node CLI output as UTF-8. - Fix some bugs involving hooks arriving when the workflow was not yet blocked on them. (#339) - Fixed nulls rejected by server, requiring Pydantic 2.12 or newer. (#321) - Prevent workflows from having side effects while suspending. (#332) `hook.dispose()` will now work properly in a `finally` block. (That is, the hook will be disposed only when the workflow is actually terminating, and not every time it gets replayed.) - Fail an unregistered workflow step permanently and resume its workflow with a clear error instead of returning a `KeyError` and redelivering forever. - More reliably fail runs whose replay diverges from the event log. (#347) Runs will now fail even in the case where the main thread of execution is not directly blocked on the suspension that is erroring. - Fixed workflow and step calls with both positional-or-keyword parameters and `*args` failing during replay because their arguments were recorded in an unbindable shape. (#312) Internal -------- - Remove a just-added return from a finally block. (#344) - Correct internal workflow type annotations found by checking untyped function bodies. (#337) - Refactored event replay. (#341) - Construct the protocol models by Python field name. (#322) vercel ------ 0.11.0 - 2026-09-01 ------------------- Features -------- - Expose `get_deadline()` for reading the current Function invocation deadline. (#306) - Answer workflow health checks for both queue-based transport and HTTP. (#292) - Add support to read the sealed (`encp`) workflow payloads (X25519 + AES-GCM) an outside writer addresses to a run, under the `encryption` extra. (#297) Bug Fixes --------- - Remove upper bounds on aggregate Sandbox and Workflow dependencies so sibling releases cannot make the `vercel` package un-installable. (#334) - Start a workflow run even when its queue message arrives before the `run_created` event has landed. (#284) Internal -------- - The Workflows implementation now ships in the separate `vercel-workflow` distribution, which `vercel` depends on, so `vercel.workflow` imports keep working without installing anything extra. (#299) vercel-apscheduler ------------------ 0.3.0 - 2026-09-01 ------------------ Breaking Changes ---------------- - The managed Redis backend was removed. The integration now always runs on its managed job store (Vercel Runtime Cache); a configured default `RedisJobStore` is rejected at import, `VERCEL_APSCHEDULER_BACKEND` accepts only `cache`, and the `redis` dependency is gone. The scheduler's durable identity now always derives from the builder-assigned subscriber id (previously the Redis `jobs_key`); the `scheduler_id` option still pins an identity explicitly. (#286) vercel-celery ------------- 0.7.5 - 2026-09-01 ------------------ - Update dependencies. vercel-django-tasks ------------------- 0.7.0 - 2026-09-01 ------------------ Features -------- - Add a Vercel Queues backend for Django Tasks and use it by default when no task backends are configured. (#291) vercel-dramatiq --------------- 0.7.4 - 2026-09-01 ------------------ - Update dependencies.
Importing everything on every workflow invocation is quite slow,
especially when using pydantic or similar.
I am planning to add automatic support for using pydantic to
serialize/validate arguments, and regenerating the pydantic validators
on every invocation will make it even more expensive. Using a shared
sandbox eliminates that problem.
Using a shared sandbox means that we still get all of the benefits of
preventing nondeterminstic calls, but that modifications to global
variables will stay visible.
But I think a good workflow shouldn't really be using globals
anyway, so...
I think I'm planning to basically immediately make a PR that will
switch the default to
share_sandboxes=True, but for cleanliness I'mseparating it.
To do this, I:
Workflowsresponsible for producing a sandboxweird cyclic init races.
Questions:
runs? If so, we can maintain a pool of unused sandboxes and create
a new one when necessary.