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

Polling-based scheduler that persists alarms to the database
and periodically checks for overdue alarms.

This is the default scheduler implementation. It stores alarms in the
`durable_object_alarms` table and fires them by starting the target
object and calling `handle_alarm/2`.

## Configuration

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

## Options

  * `:polling_interval` - How often to check for overdue alarms (default: 30 seconds)
  * `:claim_ttl` - How long a claimed alarm waits before being retried (default: 60 seconds)

## Crash Recovery

The polling scheduler uses claim-based execution for crash recovery:

1. **Claim**: Before firing, the scheduler atomically sets `claimed_at` on the alarm
2. **Fire**: The object's `handle_alarm/2` callback is invoked
3. **Delete**: On success, the alarm is deleted only if still claimed

If a handler reschedules the same alarm, the upsert clears `claimed_at`, so the
delete becomes a no-op and the new alarm persists. If the handler fails or the
server crashes, the alarm remains claimed and will be retried after `claim_ttl`
expires.

This provides **at-least-once delivery** semantics. Handlers should be idempotent.

---

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