Skip to content

Defer Cadwyn import to keep FastAPI off the Task SDK worker path - #69016

Merged
jason810496 merged 1 commit into
apache:mainfrom
jason810496:fix/task-sdk/lazy-cadwyn-import
Jun 26, 2026
Merged

Defer Cadwyn import to keep FastAPI off the Task SDK worker path#69016
jason810496 merged 1 commit into
apache:mainfrom
jason810496:fix/task-sdk/lazy-cadwyn-import

Conversation

@jason810496

@jason810496jason810496 commented Jun 26, 2026

Copy link
Copy Markdown
Member

Why

The execution-time schema package imported cadwyn (pulling in FastAPI/Starlette/Jinja2) at module load, but cadwyn is only needed on the Multi-Lang task execution path. Imported lazily after the Celery prefork, every pool worker paid this in private pages, raising worker memory on Python 3.14.

What

  • Build the supervisor VersionBundle lazily behind a functools.cached get_bundle(), with the cadwyn import inside it.
  • Defer generate_versioned_models into SchemaVersionMigrator._versioned_class, the only path that needs it.
  • Keep from ...schema import bundle working via module-level __getattr__, so cadwyn loads only when bundle is accessed.
  • Add a regression test asserting the worker import graph stays cadwyn/fastapi-free, and that accessing bundle loads cadwyn.

Was generative AI tooling used to co-author this PR?

The Task SDK supervisor imports the execution-time schema package on every
worker, and that package imported cadwyn at module load. cadwyn pulls in
FastAPI, Starlette and Jinja2, which are only needed on the foreign-language-SDK
schema-migration path and never for a pure-Python worker. Because the supervisor
is imported lazily after the Celery prefork, each pool worker paid this import
in private (non copy-on-write) pages, raising worker memory on Python 3.14.
Defer the cadwyn import behind a cached bundle accessor and into _versioned_class
so importing the schema package no longer loads FastAPI. The foreign-SDK path is
unchanged; a regression test asserts the worker import graph stays cadwyn-free.
@jason810496
jason810496 merged commit 85aa9b6 into apache:mainJun 26, 2026
102 checks passed
jason810496 added a commit that referenced this pull request Jun 26, 2026
…er path (#69016) (#69029)
The Task SDK supervisor imports the execution-time schema package on every
worker, and that package imported cadwyn at module load. cadwyn pulls in
FastAPI, Starlette and Jinja2, which are only needed on the foreign-language-SDK
schema-migration path and never for a pure-Python worker. Because the supervisor
is imported lazily after the Celery prefork, each pool worker paid this import
in private (non copy-on-write) pages, raising worker memory on Python 3.14.
Defer the cadwyn import behind a cached bundle accessor and into _versioned_class
so importing the schema package no longer loads FastAPI. The foreign-SDK path is
unchanged; a regression test asserts the worker import graph stays cadwyn-free.
(cherry picked from commit 85aa9b6)
karenbraganz pushed a commit to karenbraganz/airflow that referenced this pull request Jun 30, 2026
…che#69016)
The Task SDK supervisor imports the execution-time schema package on every
worker, and that package imported cadwyn at module load. cadwyn pulls in
FastAPI, Starlette and Jinja2, which are only needed on the foreign-language-SDK
schema-migration path and never for a pure-Python worker. Because the supervisor
is imported lazily after the Celery prefork, each pool worker paid this import
in private (non copy-on-write) pages, raising worker memory on Python 3.14.
Defer the cadwyn import behind a cached bundle accessor and into _versioned_class
so importing the schema package no longer loads FastAPI. The foreign-SDK path is
unchanged; a regression test asserts the worker import graph stays cadwyn-free.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@jason810496@amoghrajesh@shahar1