Skip to content

Performance [P3]: Index sandbox activity overlap validation - #205

Merged
berndverst merged 4 commits into
mainfrom
berndverst-index-sandbox-activity-overlap-validatio
Jul 27, 2026
Merged

Performance [P3]: Index sandbox activity overlap validation#205
berndverst merged 4 commits into
mainfrom
berndverst-index-sandbox-activity-overlap-validatio

Conversation

@berndverst

Copy link
Copy Markdown
Member

Summary

build_sandbox_worker_profiles() validated activity ownership with a linear
next(...) scan over every previously accumulated activity, calling
activities_overlap() for each candidate. That made sandbox worker profile
construction O(n²) in the number of registered activities — startup-only
control-plane work, but it degrades badly for large generated or versioned
sandbox catalogs.

This replaces the scan with _ActivityOwnerIndex, a private index in
profile_builder.py that gives O(1) overlap lookups per activity:

  • _by_name — keyed on the casefolded activity name, used when the incoming
    activity is unversioned (an unversioned activity overlaps all versions of
    the same name).
  • _by_name_and_version — keyed on (casefolded name, version) where None
    represents an unversioned registration, used when the incoming activity has
    an explicit version (it overlaps the same version plus any unversioned
    registration of that name).

Semantics preserved exactly

The index mirrors activities_overlap() byte-for-byte, including its
normalization rules:

Case Overlaps?
Same name (case-insensitive), one side unversioned Yes
Same name, same explicit version Yes
Same name, different explicit versions No
Version comparison Case-sensitive exact string match, as before

Registration order is tracked (_ActivityOwnerSlot retains the first owner plus
the first owner that differs from it) so the profile named in the error is the
same one a linear scan would have reported. The exception type (ValueError)
and message text are unchanged:

Sandbox activity '<activity>' is assigned to both worker profile '<a>' and '<b>'.

Profile ordering in the returned list, the same-profile overlap allowance, and
the truthiness check on the conflicting profile id are all unchanged.

activities_overlap() remains exported from helpers.py — no public API
signature changes, no renames, no removed symbols, no changed import paths.
This is an internal performance refactor with no observable behavior change,
so per repo convention there is no changelog entry.

Fixes #190

Verification

Measured improvement (synthetic catalogs, legacy scan vs. index):

Activities Legacy Indexed Speedup
500 0.019 s 0.0007 s 26x
2000 0.300 s 0.0030 s 99x
8000 4.910 s 0.0133 s 369x

Legacy timings scale ~16x per 4x input (quadratic); indexed timings scale
linearly.

Tests — 4 new tests in tests/durabletask-azuremanaged/test_sandboxes_extension.py:

  • ..._rejects_versioned_activity_overlapping_unversioned_owner — unversioned
    owner vs. versioned candidate, asserts the exact conflict message.
  • ..._rejects_unversioned_activity_overlapping_versioned_owner — versioned
    owner vs. unversioned candidate, asserts the exact conflict message.
  • ..._rejects_identical_activity_versions — same name + same explicit version,
    asserts the exact conflict message.
  • test_activity_owner_index_matches_linear_overlap_scan — differential test
    that replays 48 registrations across 25 seeded shuffles and asserts the index
    agrees with the original activities_overlap() linear scan at every step.

The existing overlap test also gained an exact-message assertion. The
pre-existing same-name/different-version allowance test still passes unchanged.

The differential test was mutation-checked: a variant of the index that drops
its second-owner tracking is caught on the first seed, confirming the test has
teeth.

Commands run (session-local venv, so the shared interpreter was untouched):

  • python -m pytest tests/durabletask-azuremanaged/test_sandboxes_extension.py tests/durabletask-azuremanaged/test_durabletask_grpc_interceptor.py -q46 passed (42 before this change + 4 new)
  • python -m pytest tests/durabletask -q --ignore-glob="*_e2e.py"681 passed, 7 skipped
  • flake8 . in durabletask-azuremanaged/ and tests/durabletask-azuremanaged/ (matching CI) → clean
  • pyright with the repo's strict pyrightconfig.json0 diagnostics in profile_builder.py

Baseline was captured before the change; the only difference was a flaky
pre-existing core test (test_sync_client_recreate_cooldown_prevents_immediate_repeated_recreation)
that passed on re-run. Remaining tests/durabletask-azuremanaged modules require
a live Durable Task Scheduler endpoint (TASKHUB unset) and are out of scope here.

`build_sandbox_worker_profiles()` validated activity ownership by scanning
every previously registered activity with `activities_overlap()` for each new
activity, making sandbox worker profile construction O(n^2) in the number of
registered activities.

Replace the linear scan with `_ActivityOwnerIndex`, which keys owners on the
normalized (casefolded) activity name and on the exact (name, version) pair,
with `None` representing an unversioned registration. Overlap semantics are
unchanged: an unversioned activity overlaps every version of the same name,
identical name+version pairs overlap, and the same name with different explicit
versions does not. Registration order is retained so the reported conflicting
profile is the same one a linear scan would report, keeping the exception type
and message byte-identical.

No public API or observable behavior change, so no changelog entry.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 1bb48ba8-473f-4632-9551-9c8d3c6615de
Copilot AI review requested due to automatic review settings July 27, 2026 06:13

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR optimizes sandbox worker profile construction in durabletask.azuremanaged by replacing a quadratic activity-overlap validation scan with a private indexed lookup structure, preserving existing overlap semantics and error reporting while improving cold-start control-plane performance for large activity catalogs.

Changes:

  • Replaced the linear activities_overlap() scan in build_sandbox_worker_profiles() with _ActivityOwnerIndex for O(1) per-activity overlap lookups.
  • Added _ActivityOwnerSlot tracking to preserve “first conflicting owner” ordering to keep the raised ValueError message identical to the legacy behavior.
  • Expanded unit tests to assert exact overlap error messages and added a differential test to ensure the index matches the legacy linear scan across shuffled registrations.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
durabletask-azuremanaged/durabletask/azuremanaged/preview/sandboxes/profile_builder.py Introduces _ActivityOwnerIndex/_ActivityOwnerSlot and switches overlap validation to indexed lookups while keeping conflict semantics and messaging stable.
tests/durabletask-azuremanaged/test_sandboxes_extension.py Adds targeted overlap regression tests (including exact-message assertions) plus a differential test ensuring indexed behavior matches the legacy scan.

Copilot AI review requested due to automatic review settings July 27, 2026 16:38

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

Bernd Verst added 2 commits July 27, 2026 10:52
…box-activity-overlap-validatio

# Conflicts:
#	tests/durabletask-azuremanaged/test_sandboxes_extension.py
Copilot AI review requested due to automatic review settings July 27, 2026 17:56

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

@berndverst
berndverst merged commit b4270ee into main Jul 27, 2026
25 checks passed
@berndverst
berndverst deleted the berndverst-index-sandbox-activity-overlap-validatio branch July 27, 2026 19:31
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.

Performance [P3]: Index sandbox activity overlap validation

3 participants