<!-- Source: https://medius.k4tech.net/library/lifecycle -->
# Lifecycle

_Holding injected input alive and recovering a dropped link_

The library holds deliberate overrides past the box's [silence-timeout clear](/native/injection.md#safety), and restores them if the link drops and reopens.

-   [`keepalive`](/library/guides/connection.md#keepalive) (automatic) holds an override past the silence timeout.
-   [`reapply`](/library/lifecycle.md#reapply) re-sends the held overrides so the box matches the library.
-   [`reconnect`](/library/lifecycle.md#reconnect) rescans, reopens the port, and restores held state after a dropped link.

## reapply

_Re-send the held overrides so the box matches the library_

```text
fn reapply(&self) -> Result<()>
```

_Fire-and-forget_

One frame goes out per held override; [`reconnect`](/library/lifecycle.md#reconnect) does this for you after a drop.

#### EXAMPLE

```rust
device.press(Button::Left)?;
device.reapply()?; // re-assert the held override, e.g. if the box reset under you
```

#### EXAMPLE

```rust
// The no-op case: reset clears every override, so reapply sends nothing.
device.reset()?;
device.reapply()?; // does nothing, no buttons are held
```

> **Note**
>
> Overrides are keyed by their [`Usage`](/library/types/enums.md#usage) (a button, key, or media usage). [`press`](/library/inject.md#inject) and [`force_release`](/library/inject.md#inject) add a held override; [`release`](/library/inject.md#inject) and [`reset`](/library/admin.md#reset) clear them.

## reconnect

_Rescan, reopen the port, and restore held state_

```text
fn reconnect(&self) -> Result<()>
```

The reader thread auto-reconnects on any read error; call this by hand only to force a rescan. It blocks while it rescans and reopens the port, and returns an error if the box can't be found or opened, but it never waits on a box reply.

On each call:

1.  Rescans for the box by its USB identity, vendor ID `0x1A86` and product ID `0x55D3` (see [Transport](/native/transport.md)).
2.  Reopens the port.
3.  Re-applies the held overrides, the same work as [`reapply`](/library/lifecycle.md#reapply).
4.  Bumps the reconnect counter.

#### EXAMPLE

```rust
// After a known unplug and replug, force a rescan and confirm it took.
let before = device.counters().reconnects;
device.reconnect()?;
let after = device.counters().reconnects;
assert!(after > before);
```

> **Note**
>
> The reconnect count is the `reconnects` field in [diagnostics](/library/diagnostics.md#counters). Held state is keyed by [`Usage`](/library/types/enums.md#usage), so the right inputs come back after a reopen.

## On AsyncDevice

_reapply and reconnect, still direct_

[`AsyncDevice`](/library/features/async.md) exposes `reapply` and `reconnect` directly, same signatures. `reapply` is a fire-and-forget frame; `reconnect` blocks while it rescans and reopens the port, so keep it off a latency-sensitive task.

#### EXAMPLE

```rust
use medius::AsyncDevice;

let device = AsyncDevice::open("/dev/ttyACM0")?;
device.reapply()?;     // re-assert held overrides
device.reconnect()?;   // blocks: rescan + reopen
```

> **Note**
>
> See [async](/library/features/async.md) for the full async surface and how `into_inner` and `into_async` move between the two views.
