# `QueueKeeperCheck.Guard`
[🔗](https://github.com/TitaniumMonkey/Queue-keeper-check/blob/v0.2.1/lib/queue_keeper_check/guard.ex#L1)

Runs one check's queries under server-side safety limits.

* **Postgres**: one transaction per check. Its first statement is

      SELECT set_config('transaction_read_only', 'on', true),
             set_config('statement_timeout', $1, true),
             set_config('lock_timeout', $2, true),
             set_config('idle_in_transaction_session_timeout', $3, true)

  (`transaction_read_only` only when `read_only: true`). All settings are
  transaction-local. The transaction is always rolled back, never committed. Because
  the settings would otherwise leak into a caller's transaction, calling
  `QueueKeeperCheck.run/2` inside an open transaction is refused.
* **MySQL**: the connection is checked out for the duration of the check,
  `max_execution_time` (which applies to `SELECT` only) is set for the session and
  restored to its previous value afterwards. If the process dies mid-check, DBConnection
  disconnects that connection, so the setting cannot leak back into the pool. Read-only
  enforcement on MySQL comes from the database grants (see `docs/SECURITY_REVIEW.md`).
* **SQLite**: no server-side settings exist; only the client-side timeout applies.

Every engine also gets a client-side `:timeout` of `statement_timeout + 2000` ms on each
query, so a query that the server does not cancel is abandoned by the client, and on
Postgres and MySQL the whole check (one transaction / checkout) is limited to
`check_timeout` ms.

# `preflight`

Checks that must pass before any query: on Postgres, refuse to run inside the caller's
open transaction, where transaction-local settings (read-only, timeouts) would leak.

# `run`

Run `fun` (which issues the check's queries) under the guard.

---

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