Skip to content

GigExpiryWorkerService processes expirations sequentially within a single sweep #236

Description

@meshackyaro

Description

GigExpiryWorkerService.runOnce() (src/gig/gig-expiry-worker.service.ts) iterates this.gigService.findExpirable() in a plain for...of loop, awaiting webhookService.dispatch(...) for each expired gig one at a time. WebhookService.dispatch() (src/webhook/webhook.service.ts) itself fans out to all registered endpoints with retries (up to 3 attempts with growing backoff per endpoint), so a sweep with many simultaneously-expiring gigs and a slow/unreachable webhook endpoint serializes all of that retry latency across the whole batch, potentially causing one sweep's runOnce() to still be running when the next interval tick fires. This is a single-instance throughput concern, distinct from the multi-instance coordination work tracked in #182.

Component

Backend

Difficulty

🟡 Medium

Tasks

  • Process expirable gigs within a sweep with bounded concurrency (e.g. a small worker pool via Promise.allSettled over chunks) instead of a fully sequential loop
  • Add a guard against overlapping sweeps (e.g. skip/log if a previous runOnce() is still in flight when the timer fires)
  • Add a test with multiple expirable gigs and a slow mock webhook endpoint, asserting the sweep completes faster than the fully-sequential baseline / doesn't overlap itself

Acceptance Criteria

  • A sweep with N expirable gigs and slow webhook endpoints no longer takes O(N × endpoint retry latency) to complete
  • Overlapping sweep runs are prevented or explicitly handled
  • A test demonstrates the improved throughput or non-overlap guarantee

Estimated Time

1 day

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions