Fix dropping schema cache reload notifications
* test: bad schema reload * refactor: DRY using the "extra" lib * refactor: move worker funtions inside AppState * Also rename Workers.hs to Admin.hs
This commit is contained in:
@@ -142,3 +142,19 @@ returns text as $$
|
||||
select current_setting('transaction_isolation', true);
|
||||
$$
|
||||
language sql set default_transaction_isolation = 'REPEATABLE READ';
|
||||
|
||||
create or replace function create_function() returns void as $_$
|
||||
drop function if exists mult_them(int, int);
|
||||
create or replace function mult_them(a int, b int) returns int as $$
|
||||
select a*b;
|
||||
$$ language sql;
|
||||
notify pgrst, 'reload schema';
|
||||
$_$ language sql security definer;
|
||||
|
||||
create or replace function migrate_function() returns void as $_$
|
||||
drop function if exists mult_them(int, int);
|
||||
create or replace function mult_them(c int, d int) returns int as $$
|
||||
select c*d;
|
||||
$$ language sql;
|
||||
notify pgrst, 'reload schema';
|
||||
$_$ language sql security definer;
|
||||
|
||||
+39
-1
@@ -551,7 +551,7 @@ def test_pool_size(defaultenv, metapostgrest):
|
||||
|
||||
|
||||
def test_pool_acquisition_timeout(defaultenv, metapostgrest):
|
||||
"Verify that PGRST_DB_POOL_ACQUISITON_TIMEOUT times out when the pool is empty"
|
||||
"Verify that PGRST_DB_POOL_ACQUISITION_TIMEOUT times out when the pool is empty"
|
||||
|
||||
env = {
|
||||
**defaultenv,
|
||||
@@ -946,6 +946,44 @@ def test_isolation_level(defaultenv):
|
||||
assert response.text == '"serializable"'
|
||||
|
||||
|
||||
def test_schema_cache_reloading(defaultenv):
|
||||
"schema cache should reload successfully"
|
||||
|
||||
# If DB_POOL=1, then the second request(/rpc/migrate_function) will just wait(PGRST_DB_POOL_ACQUISITION_TIMEOUT=10) for the schema cache reload to finish.
|
||||
# This is bc the only pool connection will be busy with the PGRST_INTERNAL_SCHEMA_CACHE_SLEEP(does a pg_sleep)
|
||||
# So this must be tested with a DB_POOL size of at least 2. That way the second request will pick the other pool connection and proceed.
|
||||
|
||||
env = {
|
||||
**defaultenv,
|
||||
"PGRST_INTERNAL_SCHEMA_CACHE_SLEEP": "1",
|
||||
"PGRST_DB_CHANNEL_ENABLED": "true",
|
||||
"PGRST_DB_POOL": "2",
|
||||
}
|
||||
|
||||
internal_sleep = int(env["PGRST_INTERNAL_SCHEMA_CACHE_SLEEP"])
|
||||
|
||||
with run(env=env, wait_for_readiness=False) as postgrest:
|
||||
time.sleep(2 * internal_sleep + 0.1) # wait for readiness manually
|
||||
|
||||
response = postgrest.session.post("/rpc/create_function")
|
||||
assert response.status_code == 204
|
||||
|
||||
time.sleep(
|
||||
internal_sleep / 2
|
||||
) # wait to be inside the schema cache reload process
|
||||
|
||||
response = postgrest.session.post("/rpc/migrate_function")
|
||||
assert response.status_code == 204
|
||||
|
||||
time.sleep(
|
||||
2 * internal_sleep
|
||||
) # wait enough time to ensure the schema cache state remains
|
||||
|
||||
response = postgrest.session.get("/rpc/mult_them?c=3&d=4")
|
||||
assert response.text == "12"
|
||||
assert response.status_code == 200
|
||||
|
||||
|
||||
# TODO: This test fails now because of https://github.com/PostgREST/postgrest/pull/2122
|
||||
# The stack size of 1K(-with-rtsopts=-K1K) is not enough and this fails with "stack overflow"
|
||||
# A stack size of 200K seems to be enough for succeess
|
||||
|
||||
+6
-12
@@ -3,8 +3,7 @@ module Main where
|
||||
import qualified Hasql.Pool as P
|
||||
import qualified Hasql.Transaction.Sessions as HT
|
||||
|
||||
import Data.Function (id)
|
||||
import Data.List.NonEmpty (toList)
|
||||
import Data.Function (id)
|
||||
|
||||
import Test.Hspec
|
||||
|
||||
@@ -70,10 +69,8 @@ main = do
|
||||
|
||||
actualPgVersion <- either (panic . show) id <$> P.use pool (queryPgVersion False)
|
||||
|
||||
baseSchemaCache <-
|
||||
loadSchemaCache pool
|
||||
(configDbSchemas testCfg)
|
||||
(configDbExtraSearchPath testCfg)
|
||||
-- cached schema cache so most tests run fast
|
||||
baseSchemaCache <- loadSchemaCache pool testCfg
|
||||
|
||||
let
|
||||
-- For tests that run with the same refSchemaCache
|
||||
@@ -85,10 +82,7 @@ main = do
|
||||
|
||||
-- For tests that run with a different SchemaCache(depends on configSchemas)
|
||||
appDbs config = do
|
||||
customSchemaCache <-
|
||||
loadSchemaCache pool
|
||||
(configDbSchemas config)
|
||||
(configDbExtraSearchPath config)
|
||||
customSchemaCache <- loadSchemaCache pool config
|
||||
appState <- AppState.initWithPool pool config
|
||||
AppState.putPgVersion appState actualPgVersion
|
||||
AppState.putSchemaCache appState (Just customSchemaCache)
|
||||
@@ -265,5 +259,5 @@ main = do
|
||||
describe "Feature.RollbackForcedSpec" Feature.RollbackSpec.forced
|
||||
|
||||
where
|
||||
loadSchemaCache pool schemas extraSearchPath =
|
||||
either (panic.show) id <$> P.use pool (HT.transaction HT.ReadCommitted HT.Read $ querySchemaCache (toList schemas) extraSearchPath True)
|
||||
loadSchemaCache pool conf =
|
||||
either (panic.show) id <$> P.use pool (HT.transaction HT.ReadCommitted HT.Read $ querySchemaCache conf)
|
||||
|
||||
@@ -113,6 +113,7 @@ baseCfg = let secret = Just $ encodeUtf8 "reallyreallyreallyreallyverysafe" in
|
||||
, configDbTxRollbackAll = True
|
||||
, configAdminServerPort = Nothing
|
||||
, configRoleSettings = mempty
|
||||
, configInternalSCSleep = Nothing
|
||||
}
|
||||
|
||||
testCfg :: AppConfig
|
||||
|
||||
Reference in New Issue
Block a user