Skip to content

Add hard backlog cap for Sports Lib heavy reparse queue #543

Description

@jimmykane

Problem

The Sports Lib heavy reparse path is rate-limited at execution time, but it does not have a hard backlog-size cap.

Current protections:

  • processSportsLibReparseHeavyTask Cloud Tasks queue runs with maxConcurrentDispatches = 1.
  • Function runtime uses maxInstances = 1, concurrency = 1.
  • Heavy worker runtime is capped around 15-16 minutes per attempt.
  • Retry config is capped at 10 attempts.

What is missing:

  • Nothing prevents many heavy reparse jobs from being enqueued and sitting pending in Cloud Tasks.
  • A large pending heavy backlog would not spike parallel cost, but it can drain slowly for hours/days and create serialized cost/risk if many jobs are pathological.

Proposed Enhancement

Add a hard backlog cap before enqueueing heavy reparse tasks.

Suggested behavior:

  • Check the pending task count for processSportsLibReparseHeavyTask before enqueueing a heavy task.
  • If pending count is above a configured threshold, do not enqueue another heavy task.
  • Leave the job in a clear deferred/failed state rather than silently dropping it.
  • Surface the state in admin queue stats so we can see that heavy jobs are waiting because the heavy queue is full.

Suggested Defaults

Initial conservative cap:

  • SPORTS_LIB_REPARSE_HEAVY_MAX_PENDING_TASKS = 10 or 25.

This should be configurable in code/constants and easy to tune later.

Acceptance Criteria

  • Heavy reparse enqueue path refuses new heavy tasks when the heavy Cloud Tasks backlog is at or above the cap.
  • Refused jobs are marked with an explicit reason, e.g. HEAVY_QUEUE_BACKLOG_FULL or heavy_queue_backlog_full.
  • Admin queue stats/reporting shows pending/deferred heavy jobs distinctly from parse failures.
  • Manual heavy retry returns a clear admin-facing error if the heavy backlog is full.
  • Normal reparse jobs are unaffected.
  • Existing execution caps remain unchanged: one heavy task at a time, one heavy function instance, one request concurrency.

Notes

This is not urgent while heavy retries are manual/admin-driven. It becomes more important if we auto-enqueue heavy jobs broadly.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions