Iwf Guide
PostgreSQL Runtime Architecture
1. Decision
Iwf's canonical public boundary is the postgres-runtime library plus the Iwf.Database adapter. Application code should depend on those Idris APIs, not on psql, shell commands, process-helper details, or direct libpq calls.
The current backend is a native Idris/C libpq binding hidden behind that boundary. It gives Iwf one parameterized execution path for raw SQL, migrations, fixtures, jobs, transactions, and PreparedQuery execution.
Any future backend should remain hidden behind the same library boundary and preserve the same behavior contract.
2. Contract
Any PostgreSQL runtime backend must preserve these behavior contracts:
- Parameter values are sent separately from SQL text.
- Parameterized worker queries use cached PostgreSQL prepared statements per connection when the backend can support them.
- Checked-out pool slots reuse a long-lived runtime worker where possible.
- Broken idle workers are health-checked, discarded, and replaced.
- Transactions roll back on adapter errors and report the original failure.
withConnectionAppreleases checked-out workers and semaphore slots when typed Idris user code throws.withTransactionApprolls back runtime transactions when typed Idris user code throws.- Nested transactions have one explicit policy instead of implicit savepoint behavior.
- Runtime errors preserve structured SQL context without logging parameter values.
- Pool metrics expose pool size, checked-out slots, idle workers, failed workers, and waiting checkouts.
- Shutdown APIs drain idle workers and close adapter resources explicitly.
3. Non-Goals
This decision does not add an IHP compatibility layer, a public Hasql-like API, or a public psql execution surface. It also does not make PostgreSQL LISTEN/NOTIFY a public realtime feature; AutoRefresh has its own separate contract.
4. Backend Review Criteria
Revisit the libpq backend only when one of these becomes true:
- Database benchmarks show result text encoding is a material bottleneck for common Iwf queries.
- Pool load tests show connection lifecycle, reconnect, or shutdown behavior cannot meet the production contract reliably.
- Another backend can satisfy the same tests with a smaller deployment footprint or a simpler operational model.
Improvements should harden the library boundary and its tests instead of exposing lower-level libpq details to application code.
5. Current Shortcomings
- Plain
withConnectionis anIOconvenience helper. UsewithConnectionAppwhen code can throw typed Idris exceptions and needs cleanup enforced by the framework. - Runtime values cross the Idris/C boundary as text. Parameter values are separated from SQL and prepared statements are cached, but this is not a binary result protocol.
- The pool is intentionally small: it exposes worker health, metrics, shutdown, and reconnect behavior, but not a Hasql-compatible API or advanced connection tuning surface.