Skip to content

Performance [P3]: Index sandbox activity overlap validation #190

Description

What is the issue?

Sandbox worker profile construction checks every new activity against every previously registered activity to detect overlap.

What is the impact?

Profile validation is quadratic in the number of configured activities. It is startup-only work, but can slow profile declaration for large generated or versioned sandbox configurations.

Details about the issue including code reference

Relevant code:

def build_sandbox_worker_profiles() -> list[pb.SandboxWorkerProfile]:
"""Build sandbox worker_profiles from worker profile configuration."""
worker_profiles: list[pb.SandboxWorkerProfile] = []
activity_owners: list[tuple[SandboxActivity, str]] = []
for profile in registered_sandbox_worker_profiles():
activities = resolve_activities(profile.activities)
for activity in activities:
existing_profile = next((owner_profile for owner_activity, owner_profile in activity_owners
if activities_overlap(owner_activity, activity)
and owner_profile != profile.worker_profile_id), None)
if existing_profile:
raise ValueError(
f"Sandbox activity '{format_activity(activity)}' is assigned to both worker profile "
f"'{existing_profile}' and '{profile.worker_profile_id}'.")
activity_owners.append((activity, profile.worker_profile_id))

def activities_overlap(
left: SandboxActivity,
right: SandboxActivity) -> bool:
return (
left.name.casefold() == right.name.casefold()
and (left.version is None or right.version is None or left.version == right.version))

build_sandbox_worker_profiles() stores activity owners in a list. For each activity, it uses next() over that full list with activities_overlap(). The overlap helper compares normalized names and treats an unversioned activity as overlapping every version.

A potential or proposed solution

Maintain indexes by normalized activity name and version, plus an entry for an unversioned owner. Preserve the existing semantics: same-name activities with different explicit versions are allowed, while an unversioned declaration overlaps all versions. Keep the current conflict message unchanged.

Cold-start relevance

This is a one-time control-plane startup cost when SandboxActivitiesClient.enable_sandbox_activities() is called. It does not affect normal worker process startup or first work-item dispatch.

Relevant code:

def enable_sandbox_activities(self) -> None:
"""Declare all configured sandbox worker profiles with Durable Task Scheduler."""
worker_profiles = build_sandbox_worker_profiles()
if not worker_profiles:
raise ValueError("No configured sandbox activities were found.")
for worker_profile in worker_profiles:
self._transport.declare_sandbox_worker_profile(worker_profile)

Metadata

Metadata

Assignees

No one assigned

    Labels

    performance / optimizationUsed for issues or PRs purely focused on performance and optimizations, not bugs.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions