# orca.instances

> A module of morca's API.

Scheduler instances: two `orca scheduler`s of different images overlapping on one Postgres during a deploy (docs/overlap.md).

With `ORCA_OVERLAP=on`, each `orca scheduler` has a row in
`orca.schedulers`, kept fresh on every tick with the runs its processes
are. One instance leads: it holds the session advisory lock `LEAD_LOCK`,
and only it decides (fires, sensors, retries, starts, alerts, sweeps). The
newest live instance takes the lead: an older one that sees a newer one
live, or is asked to (`orca scheduler drain`), gives the lock up and
drains: it starts nothing, keeps supervising the processes it started
until they end, then ends its row and exits. A run an instance started
records it (`runs.instance`), and `orca.live.held_sql` keeps it live while
the instance lists it, so the leader counts it and leaves it alone.

An instance is live while it has been seen within the stale limit and
hasn't ended; "gone" is the opposite, and only then are its runs, once
their heartbeats are stale too, queued again (`Scheduler._requeue_orphans`).

## Functions

### `overlap_on`

```mojo
def overlap_on() -> Bool
```

`ORCA_OVERLAP`: `off` (the default: one scheduler at a time, as before) or `on` (an instance row, a lead, and a drain).

### `live_cond`

```mojo
def live_cond(stale: Float64) -> String
```

SQL true for a row of `orca.schedulers` that is live: not ended, and seen within `stale` seconds.

### `join`

```mojo
def join(mut db: State) -> Int
```

Adds this process's row, waiting, with the migrations it knows and its image (`ORCA_IMAGE`); returns its id.

### `beat`

```mojo
def beat(mut db: State, id: Int, running: String) -> Bool
```

Marks instance `id` seen, with `running` (run ids, comma-separated) its processes' runs; returns whether it was asked to drain.

### `newer`

```mojo
def newer(mut db: State, id: Int) -> Int
```

The newest live instance after `id` that isn't draining, or 0.

### `try_lead`

```mojo
def try_lead(mut db: State, id: Int) -> Bool
```

Takes the lead for instance `id` if no one holds it; records it.

### `step_down`

```mojo
def step_down(mut db: State, id: Int, leading: Bool)
```

Instance `id` drains: gives up the lead if it held it, and records that it drains.

### `end`

```mojo
def end(mut db: State, id: Int)
```

Instance `id` has ended: gone at once, for the leader's requeue.

### `ask_drain`

```mojo
def ask_drain(mut db: State, id: Int) -> Bool
```

Asks live instance `id` to drain; False if there's no such one.

### `instances`

```mojo
def instances(mut db: State) -> List[String]
```

A line for each instance not long gone (ended or unseen within the last hour), oldest first: id, host and pid, role, image, migrations known, runs going, and when it was last seen.

### `overlap_refusal`

```mojo
def overlap_refusal(mut db: State) -> String
```

Why this binary can't start beside the scheduler going now, or empty if it can (docs/overlap.md#deploying): a live instance leads, and no live instance knows fewer migrations than this binary's floor (`orca.state.migration_floor`), which its migrations would raise past it. Doesn't migrate.

### `wait_for_lead`

```mojo
def wait_for_lead(mut db: State, timeout: Float64) -> Bool
```

Waits, up to `timeout` seconds, for the newest live instance to lead (a handover over); True at once with no instance live. A deploy registers the new image's pipelines only after this, so the instance going away never starts their new code.

## Aliases

### `LEAD_LOCK`

```mojo
comptime LEAD_LOCK = 1869767525
```

The session advisory lock the leading instance holds.
