Skip to content

fix: implement libpq semantic for target_session_attrs=prefer-standby#1022

Merged
dvarrazzo merged 2 commits intomasterfrom
fix-target_session_attrs-prefer-standby
Mar 12, 2025
Merged

fix: implement libpq semantic for target_session_attrs=prefer-standby#1022
dvarrazzo merged 2 commits intomasterfrom
fix-target_session_attrs-prefer-standby

Conversation

@dvarrazzo
Copy link
Copy Markdown
Member

First attempt all the servers in standby mode, then fall back to any mode.

Fix #1021.

CC. @AndrewJackson2020

First attempt all the servers in standby mode, then fall back to any
mode.

Fix #1021.
@dvarrazzo
Copy link
Copy Markdown
Member Author

Note: there are both connection tests to verify that the libpq filters the right server (within reason: we only test with a primary server) and unittest level to verify that the attamps made in prefer-standby mode are what expected.

Only one test fails with the currently "oldest" libpq, which is 10.2,
however the docs in libpq 13 are not explicit in which modes are
supported and, afaics, 'replica' shouldn't work either.

https://www.postgresql.org/docs/13/libpq-connect.html
@AndrewJackson2020
Copy link
Copy Markdown

AndrewJackson2020 commented Mar 11, 2025

This is looking good to me so far. Using the below code to test. Have not looked as async yet though, can take a closer look tommorow.

import psycopg
import pytest

def test(hosts: str, ports: str, target_session_attrs: str, expected_port: int) -> None:
    print(target_session_attrs)
    # Connect to an existing database
    if expected_port:
        with psycopg.connect(f"host={hosts} port={ports} dbname=postgres user=andrew target_session_attrs={target_session_attrs}") as conn:

            # Open a cursor to perform database operations
            with conn.cursor() as cur:

                cur.execute("select setting from pg_settings where name = 'port'")
                port = cur.fetchone()[0]
                assert expected_port == int(port)
    else:
        with pytest.raises(Exception):
            psycopg.connect(
                    f"host={hosts} port={ports} dbname=postgres user=andrew target_session_attrs={target_session_attrs}")



def test_all() -> None:
    test(hosts="localhost,localhost", ports="5432,5433",
         target_session_attrs="primary", expected_port=5432)
    test(hosts="localhost,localhost", ports="5432,5433",
         target_session_attrs="read-write", expected_port=5432)
    test(hosts="localhost,localhost", ports="5432,5433",
         target_session_attrs="standby", expected_port=5433)
    test(hosts="localhost,localhost", ports="5432,5433",
         target_session_attrs="prefer-standby", expected_port=5433)
    test(hosts="localhost,localhost", ports="5432,5433",
         target_session_attrs="read-only", expected_port=5433)

    test(hosts="localhost", ports="5432",
         target_session_attrs="primary", expected_port=5432)
    test(hosts="localhost", ports="5432",
         target_session_attrs="read-write", expected_port=5432)
    test(hosts="localhost", ports="5432",
         target_session_attrs="standby", expected_port=None)
    test(hosts="localhost", ports="5432",
         target_session_attrs="prefer-standby", expected_port=5432)
    test(hosts="localhost", ports="5432",
         target_session_attrs="read-only", expected_port=None)

    test(hosts="localhost", ports="5433",
         target_session_attrs="primary", expected_port=None)
    test(hosts="localhost", ports="5433",
         target_session_attrs="read-write", expected_port=None)
    test(hosts="localhost", ports="5433",
         target_session_attrs="standby", expected_port=5433)
    test(hosts="localhost", ports="5433",
         target_session_attrs="prefer-standby", expected_port=5433)
    test(hosts="localhost", ports="5433",
         target_session_attrs="read-only", expected_port=5433)


if __name__ == "__main__":
    test_all()

@dvarrazzo dvarrazzo merged commit 9ba676a into master Mar 12, 2025
146 checks passed
@dvarrazzo dvarrazzo deleted the fix-target_session_attrs-prefer-standby branch March 12, 2025 17:49
@AndrewJackson2020
Copy link
Copy Markdown

Thank you very much for implementing this fix. Looking forward to the next release.

@dvarrazzo
Copy link
Copy Markdown
Member Author

@AndrewJackson2020 no worries and thank you for the report and fix proposal! Psycopg 3.2.6 with this fix will hit PyPI in a few minutes!

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

target_session_attrs=prefer-standby not handled correctly

2 participants