Skip to content

perf(workflows): reuse S3 payload clients - #601

Open
lucasmrdt wants to merge 1 commit into
mainfrom
lm/payload-offloading-client-pool
Open

perf(workflows): reuse S3 payload clients#601
lucasmrdt wants to merge 1 commit into
mainfrom
lm/payload-offloading-client-pool

Conversation

@lucasmrdt

Copy link
Copy Markdown
Contributor

Summary

Adds an opt-in reusable S3 client for workflow payload offloading so a worker can reuse a single aioboto3 S3 client across many offload/reload calls instead of opening (and tearing down) a new client for every payload.

  • BlobStorageConfig.reuse_client (default False) — fully backward compatible; the current per-context client behavior is unchanged unless a caller opts in.
  • When reuse_client=True, get_blob_storage pools one S3BlobStorage per safe key (bucket_name, prefix, region_name, endpoint_url, access_key, secret_key), so repeated contexts for the same destination share one open client.
  • S3BlobStorage now tracks its client context explicitly (_client_context), returns early from __aenter__ when a client is already open, and only tears down on __aexit__ when it is not reusing. Real teardown lives in aclose(...).
  • close_cached_blob_storages() closes every pooled client and is safe to call repeatedly (idempotent) — intended for worker shutdown.
  • A client that fails to enter is never left half-open in the pool, and context exit still forwards the original exception (faithful to async with).

Scope is intentionally minimal: only the reusable-client mechanism is added. No caching layer, no HEAD/existence-check changes, no other config fields.

Changes

  • src/mistralai/extra/workflows/encoding/config.py: add reuse_client: bool = False.
  • src/mistralai/extra/workflows/encoding/storage/_s3.py: explicit client-context tracking, reuse guard, aclose, reuse-aware __aexit__.
  • src/mistralai/extra/workflows/encoding/storage/blob_storage.py: keyed S3 client pool, reuse-aware construction, close_cached_blob_storages, safe enter/exit lifecycle.
  • src/mistralai/extra/tests/test_workflow_payload_client_pool.py: new tests.

All edited files are hand-owned (listed in .genignore); no generated SDK surface is touched.

Verification

  • New tests: test_workflow_payload_client_pool.py — default False, independent clients when disabled, single client reuse when enabled, distinct clients per distinct reuse config, repeatable cleanup, and enter/exit failure lifecycle (root error preserved, no cache leak).
  • uv run python -m unittest discover -s src/mistralai/extra/tests -t src — 152 passed (CI path).
  • uv run pytest tests/ — 358 passed, 46 skipped.
  • uv run ruff check src/mistralai/extra/ — clean.
  • uv run --all-extras mypy src/mistralai/extra/ — clean.
  • uv run --all-extras pyright src/mistralai/extra/ — 0 errors.
  • uv build — sdist + wheel build successfully.
  • git diff --check — clean.
  • Isolated fake-aioboto3 manual QA (no network) proving creation counts and cleanup: reuse_client=False → 2 clients for 2 contexts; reuse_client=True → 1 client kept open; close_cached_blob_storages() closes once and is idempotent; enter/exit failures surface the root error; repeated interruptions leave the pool stable.

Add an opt-in reusable S3 client for workflow payload offloading.

BlobStorageConfig gains reuse_client (default False), preserving the
current per-context client behavior. When reuse_client is True,
get_blob_storage pools one S3BlobStorage per safe credential/location
key so a worker reuses a single aioboto3 client across offload calls
instead of opening one per payload.

S3BlobStorage tracks its client context explicitly, skips re-entering
an already-open client, and only tears down on __aexit__ when not
reusing; aclose performs the real teardown. close_cached_blob_storages
closes every pooled client and is safe to call repeatedly. A failed
client enter never leaves a half-open entry in the pool, and context
exit still forwards the original exception.

Tests cover the default, independent clients when disabled, single
client reuse when enabled, repeatable cleanup, and enter/exit failure
lifecycle.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant