Skip to content

Commit 95720c5

Browse files
committed
fix: reloading the Schema Cache unnecessarily on a PGRST002 error
When 503 errors happen if the Schema Cache is empty, it should not retrigger the connection worker since there's no Schema Cache loaded yet.
1 parent 88e9b87 commit 95720c5

File tree

3 files changed

+30
-3
lines changed

3 files changed

+30
-3
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
1212
- Fix not logging transaction variables and db-pre-request function when `log-query=main-query` is enabled by @steve-chavez in #3934
1313
- Fix loading utf-8 config files with `ASCII` locale set in #4386
1414
- Fix not logging the JSON message to stderr on a `PGRST002` error by @laurenceisla in #4129
15+
- Fix reloading the Schema Cache unnecessarily on a `PGRST002` error by @laurenceisla in #4367
1516

1617
### Added
1718

src/PostgREST/App.hs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,14 @@ postgrest logLevel appState connWorker =
109109
runExceptT $ postgrestResponse appState appConf maybeSchemaCache authResult req
110110

111111
response <- either Error.errorResponseFor identity <$> eitherResponse
112-
-- Launch the connWorker when the connection is down. The postgrest
112+
-- Launch the connWorker when the connection is down. The postgrest
113113
-- function can respond successfully (with a stale schema cache) before
114-
-- the connWorker is done.
115-
when (isServiceUnavailable response) connWorker
114+
-- the connWorker is done. However, when there's an empty schema cache
115+
-- postgrest responds with the error `PGRST002`; this means that the schema
116+
-- cache is still loading, so we don't launch the connWorker here because
117+
-- it would duplicate the loading process, e.g. https://github.com/PostgREST/postgrest/issues/3704
118+
-- TODO: this process may be unnecessary when the Listener is enabled. Revisit once https://github.com/PostgREST/postgrest/issues/1766 is done
119+
when (isServiceUnavailable response && isJust maybeSchemaCache) connWorker
116120
resp <- do
117121
delay <- AppState.getNextDelay appState
118122
return $ addRetryHint delay response

test/io/test_io.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1892,6 +1892,28 @@ def test_log_error_when_empty_schema_cache_on_startup_to_stderr(defaultenv):
18921892
assert any(log_err_message in line for line in output_start)
18931893

18941894

1895+
def test_no_double_schema_cache_reload_on_empty_schema(defaultenv):
1896+
"Should only load the schema cache once on a 503 error when there's an empty schema cache on startup"
1897+
1898+
env = {
1899+
**defaultenv,
1900+
"PGRST_INTERNAL_SCHEMA_CACHE_QUERY_SLEEP": "300",
1901+
}
1902+
1903+
with run(env=env, port=freeport(), wait_for_readiness=False) as postgrest:
1904+
postgrest.wait_until_scache_starts_loading()
1905+
1906+
response = postgrest.session.get("/projects")
1907+
assert response.status_code == 503
1908+
1909+
# Should wait enough time to load the schema cache twice to guarantee that the test is valid
1910+
time.sleep(1)
1911+
1912+
response = postgrest.admin.get("/metrics")
1913+
assert response.status_code == 200
1914+
assert 'pgrst_schema_cache_loads_total{status="SUCCESS"} 1.0' in response.text
1915+
1916+
18951917
@pytest.mark.parametrize("level", ["crit", "error", "warn", "info", "debug"])
18961918
def test_log_pool_req_observation(level, defaultenv):
18971919
"PostgREST should log PoolRequest and PoolRequestFullfilled observation when log-level=debug"

0 commit comments

Comments
 (0)