# `DurableObject.Scheduler`
[🔗](https://github.com/ChristianAlexander/durable_object/blob/v0.3.2/lib/durable_object/scheduler.ex#L1)

Behaviour for alarm scheduling backends.

Implementations must handle:
- Scheduling alarms for future execution
- Cancelling pending alarms
- Resurrecting alarms after process/node crashes

## Built-in Implementations

  * `DurableObject.Scheduler.Polling` - Database-backed polling scheduler (default)
  * `DurableObject.Scheduler.Oban` - Oban-based scheduler (requires oban dependency)

## Configuration

### Polling Scheduler (default)

    config :durable_object,
      scheduler: DurableObject.Scheduler.Polling,
      scheduler_opts: [
        repo: MyApp.Repo,
        polling_interval: :timer.seconds(30)
      ]

### Oban Scheduler

For applications already using Oban, the Oban scheduler leverages your existing
Oban infrastructure for alarm delivery.

    config :durable_object,
      scheduler: DurableObject.Scheduler.Oban,
      scheduler_opts: [oban_queue: :durable_object_alarms]

You must also add the queue to your Oban configuration:

    config :my_app, Oban,
      repo: MyApp.Repo,
      queues: [durable_object_alarms: 5]

If your app uses a custom Oban instance name, specify it with `oban_instance`:

    scheduler_opts: [oban_instance: MyApp.Oban, oban_queue: :durable_object_alarms]

# `alarm_name`
[🔗](https://github.com/ChristianAlexander/durable_object/blob/v0.3.2/lib/durable_object/scheduler.ex#L48)

```elixir
@type alarm_name() :: atom()
```

# `delay_ms`
[🔗](https://github.com/ChristianAlexander/durable_object/blob/v0.3.2/lib/durable_object/scheduler.ex#L49)

```elixir
@type delay_ms() :: non_neg_integer()
```

# `object_ref`
[🔗](https://github.com/ChristianAlexander/durable_object/blob/v0.3.2/lib/durable_object/scheduler.ex#L47)

```elixir
@type object_ref() :: {module :: module(), object_id :: String.t()}
```

# `cancel`
[🔗](https://github.com/ChristianAlexander/durable_object/blob/v0.3.2/lib/durable_object/scheduler.ex#L62)

```elixir
@callback cancel(object_ref(), alarm_name(), opts :: keyword()) :: :ok | {:error, term()}
```

Cancel a pending alarm.
Returns :ok even if the alarm doesn't exist.

# `cancel_all`
[🔗](https://github.com/ChristianAlexander/durable_object/blob/v0.3.2/lib/durable_object/scheduler.ex#L68)

```elixir
@callback cancel_all(object_ref(), opts :: keyword()) :: :ok | {:error, term()}
```

Cancel all alarms for an object.

# `child_spec`
[🔗](https://github.com/ChristianAlexander/durable_object/blob/v0.3.2/lib/durable_object/scheduler.ex#L82)

```elixir
@callback child_spec(opts :: keyword()) :: [Supervisor.child_spec()]
```

Child spec for the scheduler's supervision tree (poller, etc).
Return an empty list if no children are needed.

# `list`
[🔗](https://github.com/ChristianAlexander/durable_object/blob/v0.3.2/lib/durable_object/scheduler.ex#L75)

```elixir
@callback list(object_ref(), opts :: keyword()) ::
  {:ok, [{alarm_name(), DateTime.t()}]} | {:error, term()}
```

List all pending alarms for an object.
Returns a list of {alarm_name, scheduled_at} tuples.

# `schedule`
[🔗](https://github.com/ChristianAlexander/durable_object/blob/v0.3.2/lib/durable_object/scheduler.ex#L55)

```elixir
@callback schedule(object_ref(), alarm_name(), delay_ms(), opts :: keyword()) ::
  :ok | {:error, term()}
```

Schedule an alarm to fire after `delay_ms` milliseconds.
If an alarm with the same name already exists, it should be replaced.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
