Skip to content

Prevent overlapping runs of a schedule (dedup across ticks) #718

Description

@Giuzzilla

I have some schedules triggering jobs relying on the fact that just one of them must be running at a time per-schedule (/per-workflow), while also being enqueued on a queue limiting overall concurrency across jobs.

Right now, I'm forcing this with a parent workflow triggering the actual workflow with a constant deduplication id:

@DBOS.workflow()
async def my_workflow(scheduled_time: datetime) -> None:
    # do something
    pass

@DBOS.workflow()
async def my_workflow_parent(
    scheduled_time: datetime, context: Any
) -> None:
    with SetEnqueueOptions(deduplication_id="my-workflow"):
        await DBOS.enqueue_workflow_async(
            QUEUE_NAME,
            my_workflow,
            scheduled_time,
        )


MY_WORKFLOW_SCHEDULE: ScheduleInput = {
    "schedule_name": "my-workflow",
    "workflow_fn": my_workflow_parent,
    "schedule": "*/1 * * * *",
    "context": None,
    "cron_timezone": "UTC",
    "queue_name": QUEUE_NAME,
}

An alternative implementation without changes on DBOS-side would be to use two layers of queueing (more complex than the above).

It'd be nice to have one of these things directly on the library:

  • The possibility to specify a fixed deduplication_id on a schedule (should be easy)
  • Alternatively, a deduplicate flag on the schedule, preventing piling up of jobs (generating an internal deduplication_id).
  • I guess this could be even more complex, like choosing between Allow (current behaviour) | Forbid/Skip (maybe with a custom state?) | Replace (cancel+enqueue). See Kubernetes CronJob concurrencyPolicy
  • Some other way to serialize schedules, similarly (but not exactly) to depends_on_past in Airflow DAGs

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions