> ## Documentation Index
> Fetch the complete documentation index at: https://praison.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Turn Lock Protocol • AI Agent SDK

> TurnLockProtocol: Contract for serialising a session's turns — cluster-wide or in-process.

# TurnLockProtocol

> Defined in the [**protocols**](../modules/protocols) module.

<Badge color="blue">AI Agent</Badge>

Contract for serialising a session's turns — cluster-wide or in-process.

The gateway holds this lock for the *whole* agent turn keyed on the
resolved session id, so only one turn ever runs against one session's
transcript at a time. With the default in-process backend
(:class:`LocalTurnLock`) this reproduces today's `asyncio.Lock` behaviour
exactly and adds no dependency. With a distributed backend (a
`RedisTurnLock` in the wrapper/bot package, reusing the scheduler's proven
`owner`+TTL lease pattern) the same `async with` seam serialises turns
across every replica.

Contract:

* :meth:`acquire` blocks until the lease for `key` is held, then
  returns a :class:`TurnLeaseToken`. `ttl` bounds how long the lease
  survives without renewal so a crashed holder self-heals.
* :meth:`release` is identity-checked against the token's `owner` and
  idempotent: releasing an already-expired/reclaimed lease is a no-op,
  never an error and never another owner's lease.
* :meth:`hold` is the ergonomic async context manager wrapping
  acquire/release, used at the `async with self._turn_lock.hold(...)`
  call site.

A backend outage must fail *open* (degrade to a loud warning rather than
wedging a healthy session), mirroring the fail-safe defaults elsewhere.

## Methods

<CardGroup cols={2}>
  <Card title="acquire()" icon="function" href="../functions/TurnLockProtocol-acquire">
    Block until the lease for `key` is held; return its token.
  </Card>

  <Card title="release()" icon="function" href="../functions/TurnLockProtocol-release">
    Release `token`'s lease (identity-checked, idempotent).
  </Card>

  <Card title="hold()" icon="function" href="../functions/TurnLockProtocol-hold">
    Return an async context manager holding the lease for the block.
  </Card>
</CardGroup>

## Source

<Card title="View on GitHub" icon="github" href="https://github.com/MervinPraison/PraisonAI/blob/main/src/praisonai-agents/praisonaiagents/gateway/protocols.py#L5393">
  `praisonaiagents/gateway/protocols.py` at line 5393
</Card>
