Skip to content

About

Recycle aged Sequel connection so connections can drain cleanly during rollouts. See documents/motivation.adoc.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

sequel-pg_reaper

Table of Contents

A Sequel extension that retires pooled connections once they pass a maximum age.

See the motivation for why it exists.

Usage

DB = Sequel.connect(url, connection_max_lifetime: 90)
DB.extension :pg_reaper
  • connection_max_lifetime is in seconds and defaults to 120

  • The age is checked as a connection is checked out of the pool, so the cost is one hash lookup

  • A connection that is too old is disconnected and replaced before your code sees it

  • A connection already checked out, such as inside a transaction, is never reaped

  • Idle connections are not closed in the background, see Idle connections

  • Single and sharded single pools are not supported

The lifetime can also be changed at runtime with DB.pool.connection_max_lifetime = 60.

Idle connections

Nothing in this extension, or in Sequel’s connection_validator, closes an idle socket in the background. Both act when a connection is checked out:

  • pg_reaper replaces any connection older than connection_max_lifetime, however long it sat idle

  • connection_validator runs a query on connections idle longer than connection_validation_timeout and replaces the ones that fail

For a pgdog rollout pg_reaper is enough, if two conditions hold that this extension does not enforce:

  • The pod’s shutdown grace is longer than connection_max_lifetime, as with pgdog’s 180s against the default 120s

  • New connections stop reaching a pod once it is terminating

Connection age does not tell you a connection is alive. If the grace is shorter than the lifetime, a connection opened just before SIGTERM is still young when the pod dies, and it is handed out dead.

Load connection_validator as well to cover connections that die for other reasons, such as a pgdog crash or a network failure:

DB = Sequel.connect(url, connection_max_lifetime: 120)
DB.extension :connection_validator, :pg_reaper
DB.pool.connection_validation_timeout = 30
  • connection_validation_timeout is an idle threshold, not a detection deadline, so the 30 above is not a promise that a dead connection is found within 30s

  • Only a connection idle longer than the threshold is validated at checkout, and an unused dead connection is not found until something checks it out

  • Set it to -1 to validate on every checkout, which costs a query each time

  • Load order does not matter

A connection checked out for longer than the time left before the pod terminates is not interrupted, keep transactions short

Development

mise install
bundle exec rake

Tests use Sequel.mock, so no database is needed.

Commits and PR titles must follow Conventional Commits to be included in the changelog and release notes. The hooks in .githooks enforce it, and mise run setup enables them.

Releases are cut by release-please and published to rubygems.org.

About

Recycle aged Sequel connection so connections can drain cleanly during rollouts. See documents/motivation.adoc.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages