Skip to content

Configurable pgpool/pgDog backends (multi-emit)#3

Open
raivil wants to merge 9 commits into
cmfrom
pgdog-support
Open

Configurable pgpool/pgDog backends (multi-emit)#3
raivil wants to merge 9 commits into
cmfrom
pgdog-support

Conversation

@raivil

@raivil raivil commented Jun 26, 2026

Copy link
Copy Markdown

What

Generalizes the single primary-pinning comment into a configurable, multi-valued PgpoolNoLoadBalance.backends. The gem can now emit the pgpool hint, the pgDog hint, or both at once during a migration.

Backend Comment emitted
:pgpool (default) /*NO LOAD BALANCE*/
:pgdog /* pgdog_role: primary */
PgpoolNoLoadBalance.backends = [:pgpool]          # default — unchanged behavior
PgpoolNoLoadBalance.backends = [:pgpool, :pgdog]  # /*NO LOAD BALANCE*/ /* pgdog_role: primary */ SELECT ...
PgpoolNoLoadBalance.backends = "pgpool,pgdog"     # comma-string also accepted

Emission order is always pgpool-first regardless of input order. Unknown/empty backends raise ArgumentError. Default [:pgpool] keeps existing behavior identical.

Why both comments work behind either router (verified against source)

  • Pgpool-II: allow_sql_comments defaults to off; is_select_query() routes any SELECT not starting with s/(/w/t to the primary, so any leading comment qualifies.
  • PgDog: parse_edge_comment merges all consecutive leading block comments into one slice before regex-scanning for pgdog_role: (proven by its own test_remove_comment_multiple_leading), so the directive in the second comment is still found.

Compatibility

  • Renames the relation/model/arel API to no_load_balance; pgpool_nlb remains a full alias (method, execute: keyword, unscope symbol).
  • Preserves PgpoolNoLoadBalance.force and the Rails 8 4-arg to_sql_and_binds (the abandoned feature/pgdog-backend-support branch dropped both — this branch is built on cm instead).
  • ExplainSubscriber strips every known backend comment.

Tests

bundle exec rspec → 39 examples, 0 failures.

Deployment prerequisites (not code-enforced)

  • Pgpool: allow_sql_comments off (default).
  • PgDog: comment-based manual routing / parser enabled.

raivil added 9 commits June 26, 2026 14:42
QueryCache#select_all compiles the arel to SQL (adding the backend
comment), then hands that SQL string to DatabaseStatements#select_all,
so to_sql_and_binds runs twice. Under PgpoolNoLoadBalance.force the
thread-local stays true across both passes, so the marker was prepended
twice (e.g. inside Sidekiq jobs / web requests where the query cache is
on). Make prepending idempotent via a shared prepend_comment helper.

Bump to 1.3.1.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant