# Starting and stopping

Engines only transcode while they run: you start them when you go live and stop them when you are done. You can start and stop each engine on its own, or all engines of a channel at once, which is what most workflows do.

## Engine states

From the moment you start it until it has stopped again, an engine goes through these states:

| State          | Meaning                                                                         |
| -------------- | ------------------------------------------------------------------------------- |
| `stopped`      | The engine is not running. This is the only state from which it can be started. |
| `deploying`    | The start request has been accepted.                                            |
| `provisioning` | Compute is being allocated for the engine and its software is being loaded.     |
| `starting`     | The engine is booting.                                                          |
| `waiting`      | The engine is running and waiting for the contribution from its ingest.         |
| `ingesting`    | The engine is receiving the contribution and preparing its outputs.             |
| `playing`      | The engine is producing all its outputs: the stream is available to viewers.    |
| `stopping`     | The engine is shutting down, after a [stop or force stop](#stopping).           |
| `error`        | The engine ran into an error. [Stop](#rules) it before you start it again.      |

A started engine goes from `deploying` through `provisioning` and `starting` to `waiting`, then to `ingesting` and `playing` as soon as the contribution arrives. If the contribution stops while the engine is `playing`, the engine goes back to `waiting` until the contribution resumes.

The status of a channel is derived from its engines, and the most active engine state wins: a channel with one `playing` and one `stopping` engine is `playing`. A channel is only `stopping` once all its engines are `stopping` or `stopped`, and a channel without engines is `ready`.

## Starting

Starting an engine deploys it in its region and begins its transcoding time, even before a contribution is connected. Starting a channel starts all its engines that are `stopped`, as well as its RTSP pull ingests; engines in any other state are left as they are.

### Auto-stop timeout

An engine that stays `waiting` for longer than the channel's `timeout` is stopped automatically, so an engine without contribution does not keep running. The timeout counts from the moment the engine started waiting, both after a start and after the contribution dropped. It defaults to 3600 seconds (1 hour); set it to `0` to never stop automatically. In the [dashboard](https://dashboard.optiview.dolby.com/), this is the **Auto-stop timeout** of the channel.

## Stopping

You can stop an engine, or all engines of a channel at once, in two ways:

* **Stop** ends the stream and then shuts the engine down gracefully: players stop playback at the end of the stream. This is the right choice when you are done streaming.
* **Force stop** tears the engine down immediately, without ending the stream: [OptiView Player](https://docs-preview.optiview.dolby.com/pr-926/theolive/playback/optiview-player.md) falls back to another engine of the distribution, or playback fails when there is none. Use it to move viewers over to a backup engine, when the engine has to be gone at once, or to cut short a stop that is still in progress.

Either way, the engine's transcoding time stops counting as soon as the stop is requested, not when the engine reaches `stopped`.

### Stop

A stop ends the stream before the engine goes away. The engine closes its playlists (an HLS media playlist gets an `EXT-X-ENDLIST` tag), so players reach the end of the stream instead of running into a playback error. The engine then shuts down: it reports `stopping` for about 10–20 seconds, then `stopped`.

Because the stream ends cleanly, players treat it as finished: they do not fall back to another engine of the distribution. To take one engine of a [redundant setup](https://docs-preview.optiview.dolby.com/pr-926/theolive/distribution/redundancy.md) out of service while viewers keep watching, force stop it instead.

[Schedulers](https://docs-preview.optiview.dolby.com/pr-926/theolive/platform/scheduler.md) and the auto-stop timeout stop engines the same way.

### Force stop

A force stop skips the graceful shutdown: the engine is torn down right away, without closing its playlists. The engine reports `stopping` for a few seconds, then `stopped`.

From the moment of the force stop, playlist requests for the engine intentionally start failing, so players detect that the engine is gone:

* **With redundancy:** when the distribution has other engines, [OptiView Player](https://docs-preview.optiview.dolby.com/pr-926/theolive/playback/optiview-player.md) falls back to the next available engine, as in any [failover](https://docs-preview.optiview.dolby.com/pr-926/theolive/distribution/redundancy.md). Viewers may see a brief interruption but keep watching.
* **Without redundancy:** when the engine was the only one of the distribution, playback fails.

A third-party player that loads the HLS URL of the distribution directly (see [Other HLS player](https://docs-preview.optiview.dolby.com/pr-926/theolive/playback/other-hls-player.md)) may not fall back to another engine: for its viewers, playback may fail even with redundancy.

A force stop works from any state except `stopped`, including while the engine is still `stopping` after a regular stop.

## Rules

* **An engine can only be started again once it is `stopped`.** Starting an engine in any other state fails with `409 already_playing`. Because starting a channel skips engines that are still `stopping`, wait until the channel is `stopped` before you start it again.
* **Stopping an engine that is already `stopping` force stops it.** Calling stop a second time on an engine or a channel therefore has the same effect as a force stop.
* **An engine in `error` is always force stopped.** It has no stream left to end, so a stop tears it down right away.
* **Stopping or force stopping a `stopped` engine fails** with `409 already_stopped`.
* **Starting or stopping a channel covers the whole channel.** It does the same to all its engines and to its RTSP pull ingests.

## API

| Action     | Engine                                   | Channel                                    |
| ---------- | ---------------------------------------- | ------------------------------------------ |
| Start      | `POST /v2/engines/{engineId}/start`      | `POST /v2/channels/{channelId}/start`      |
| Stop       | `POST /v2/engines/{engineId}/stop`       | `POST /v2/channels/{channelId}/stop`       |
| Force stop | `POST /v2/engines/{engineId}/force-stop` | `POST /v2/channels/{channelId}/force-stop` |

All of them return `204` as soon as the request is accepted; the engines then start or shut down in the background. Follow their progress through the `status` of the [engine](https://docs-preview.optiview.dolby.com/pr-926/theolive/api/get-engine.md) or [channel](https://docs-preview.optiview.dolby.com/pr-926/theolive/api/get-channel.md), or through [webhooks](#webhooks).

### API example — [Start a channel](https://docs-preview.optiview.dolby.com/pr-926/theolive/api/start-channel.md)

`POST https://api.theo.live/v2/channels/{channelId}/start`

```bash
curl -X POST https://api.theo.live/v2/channels/ch_abc123/start \
  -H "Authorization: Basic $AUTH"
```

### API example — [Stop a channel](https://docs-preview.optiview.dolby.com/pr-926/theolive/api/stop-channel.md)

`POST https://api.theo.live/v2/channels/{channelId}/stop`

```bash
curl -X POST https://api.theo.live/v2/channels/ch_abc123/stop \
  -H "Authorization: Basic $AUTH"
```

### API example — [Force stop a channel](https://docs-preview.optiview.dolby.com/pr-926/theolive/api/force-stop-channel.md)

`POST https://api.theo.live/v2/channels/{channelId}/force-stop`

```bash
curl -X POST https://api.theo.live/v2/channels/ch_abc123/force-stop \
  -H "Authorization: Basic $AUTH"
```

### API example — [Start an engine](https://docs-preview.optiview.dolby.com/pr-926/theolive/api/start-engine.md)

`POST https://api.theo.live/v2/engines/{engineId}/start`

```bash
curl -X POST https://api.theo.live/v2/engines/eng_ghi789/start \
  -H "Authorization: Basic $AUTH"
```

### API example — [Stop an engine](https://docs-preview.optiview.dolby.com/pr-926/theolive/api/stop-engine.md)

`POST https://api.theo.live/v2/engines/{engineId}/stop`

```bash
curl -X POST https://api.theo.live/v2/engines/eng_ghi789/stop \
  -H "Authorization: Basic $AUTH"
```

### API example — [Force stop an engine](https://docs-preview.optiview.dolby.com/pr-926/theolive/api/force-stop-engine.md)

`POST https://api.theo.live/v2/engines/{engineId}/force-stop`

```bash
curl -X POST https://api.theo.live/v2/engines/eng_ghi789/force-stop \
  -H "Authorization: Basic $AUTH"
```

## Dashboard

In the [dashboard](https://dashboard.optiview.dolby.com/), you start and stop a whole channel from the channel details page or the channels table, and a single engine from its card on the channel details page.

* **Start:** **Start channel** on the channel details page, **Start all engines** in the channels table and the start button of an engine each ask you to confirm before they start.
* **Stop:** every stop button opens a dialog that lets you choose between a stop and a force stop. **Stop channel** on the channel details page, and **Stop all engines** in the channels table, open the **Stop all engines** dialog, with **Stop all** and **Force stop all**. The stop button of an engine opens the **Stop engine** dialog, with **Stop** and **Force stop**.

While an engine or a channel is `stopping`, the graceful option is gone: its stop button becomes **Force stop** (**Force stop channel** on the channel details page, **Force stop all engines** in the channels table), and the dialog only offers the force stop. The start button of an engine only returns once the engine is `stopped`.

## Webhooks

Every state change of an engine sends the matching [engine webhook event](https://docs-preview.optiview.dolby.com/pr-926/theolive/platform/real-time-update-with-webhooks.md#engine-events): `engine.deploying` when a start is accepted, then `engine.provisioning`, `engine.starting`, `engine.waiting`, `engine.ingesting` and `engine.playing` as the engine reports them. The events the engine reports carry its `previousStatus` in `data`, and `engine.error` also carries an `errorMessage`. Starting a channel also sends `channel.deploying` when the start is accepted.

Each way of stopping sends `engine.stopping` and `engine.stopped` at different moments:

| Stopping                                           | `engine.stopping`               | `engine.stopped`                                  |
| -------------------------------------------------- | ------------------------------- | ------------------------------------------------- |
| Stop                                               | When the stop is accepted       | Once the engine is torn down, about 10–20 s later |
| Force stop                                         | When the force stop is accepted | Once the engine is torn down, a few seconds later |
| Stop or force stop of an engine that is `stopping` | Not sent again                  | Once the engine is torn down, a few seconds later |
| Stop of an engine in `error`                       | When the stop is accepted       | Once the engine is torn down, a few seconds later |

`channel.stopped` is sent when a stop or force stop of the channel is accepted, while its engines may still be shutting down. To know when an engine is gone, wait for its `engine.stopped`.
