Skip to content

Commit c96a492

Browse files
committed
Add pg_durable.worker_role GUC and use -U postgres consistently
Replace PGUSER/USER env var detection with a Postmaster-context GUC (default: azuresu). Scripts and e2e tests updated to connect as postgres and include user= in dblink connection strings.
1 parent 5ecd649 commit c96a492

8 files changed

Lines changed: 57 additions & 21 deletions

File tree

scripts/pg-start.sh

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,19 @@ cargo pgrx install --pg-config "$PG_CONFIG" 2>&1 | grep -v "^warning:" || true
3333
# Initialize data directory if it doesn't exist
3434
if [ ! -d "$DATA_DIR" ]; then
3535
echo -e "\033[0;33mInitializing PostgreSQL data directory...\033[0m"
36-
"$PGRX_BIN_DIR/initdb" -D "$DATA_DIR" 2>/dev/null || true
36+
"$PGRX_BIN_DIR/initdb" -D "$DATA_DIR" -U postgres 2>/dev/null || true
3737
fi
3838

39-
# Configure shared_preload_libraries for background worker
39+
# Configure shared_preload_libraries for background worker and pg_durable.worker_role
4040
if [ -f "$PG_CONF" ]; then
4141
if ! grep -q "shared_preload_libraries.*pg_durable" "$PG_CONF"; then
4242
echo -e "\033[0;33mConfiguring shared_preload_libraries...\033[0m"
4343
echo "shared_preload_libraries = 'pg_durable'" >> "$PG_CONF"
4444
fi
45+
if ! grep -q "^pg_durable.worker_role" "$PG_CONF"; then
46+
echo -e "\033[0;33mConfiguring pg_durable.worker_role...\033[0m"
47+
echo "pg_durable.worker_role = 'postgres'" >> "$PG_CONF"
48+
fi
4549
fi
4650

4751
echo -e "\033[0;33mStarting PostgreSQL...\033[0m"
@@ -55,16 +59,13 @@ for i in {1..30}; do
5559
sleep 0.2
5660
done
5761

58-
# Create extension if needed
59-
"$PGRX_BIN_DIR/psql" -h localhost -p 28817 -d postgres -c "CREATE EXTENSION IF NOT EXISTS pg_durable;" 2>/dev/null || true
60-
6162
# Show version
62-
VERSION=$("$PGRX_BIN_DIR/psql" -h localhost -p 28817 -d postgres -t -c "SELECT df.version();" 2>/dev/null | tr -d ' \n')
63+
VERSION=$("$PGRX_BIN_DIR/psql" -h localhost -p 28817 -U postgres -d postgres -t -c "SELECT df.version();" 2>/dev/null | tr -d ' \n')
6364
echo -e "\033[0;32mPostgreSQL started with pg_durable $VERSION\033[0m"
6465

6566
echo ""
6667
echo -e "\033[0;36mConnect:\033[0m"
67-
echo " $PGRX_BIN_DIR/psql -h localhost -p 28817 -d postgres"
68+
echo " $PGRX_BIN_DIR/psql -h localhost -p 28817 -U postgres -d postgres"
6869
echo ""
6970
echo -e "\033[0;36mLogs:\033[0m"
7071
echo " tail -f ~/.pgrx/17.log"

scripts/test-e2e-local.sh

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ done
7979
# pgrx settings
8080
PGRX_HOME="$HOME/.pgrx"
8181
PG_PORT="$((28800 + PG_VERSION))"
82-
PG_USER="$USER"
82+
PG_USER="postgres"
8383
PG_DB="postgres"
8484

8585
# Default non-privileged role for E2E tests (created by 00_setup_playground.sql)
@@ -149,6 +149,11 @@ ensure_config() {
149149
sed -i.bak '/^#*shared_preload_libraries/d' "$DATA_DIR/postgresql.conf"
150150
echo "shared_preload_libraries = 'pg_durable'" >> "$DATA_DIR/postgresql.conf"
151151
fi
152+
# Ensure worker_role is set
153+
if ! grep -q "^pg_durable.worker_role" "$DATA_DIR/postgresql.conf" 2>/dev/null; then
154+
echo "Configuring pg_durable.worker_role..."
155+
echo "pg_durable.worker_role = 'postgres'" >> "$DATA_DIR/postgresql.conf"
156+
fi
152157
# Ensure port is set
153158
if ! grep -q "^port = $PG_PORT" "$DATA_DIR/postgresql.conf" 2>/dev/null; then
154159
sed -i.bak '/^#*port = /d' "$DATA_DIR/postgresql.conf"
@@ -187,7 +192,7 @@ start_server() {
187192
# Initialize if needed
188193
if [ ! -d "$DATA_DIR" ]; then
189194
echo "Initializing database..."
190-
"$PGRX_BIN/initdb" -D "$DATA_DIR" --no-locale -E UTF8 >/dev/null 2>&1
195+
"$PGRX_BIN/initdb" -D "$DATA_DIR" -U postgres --no-locale -E UTF8 >/dev/null 2>&1
191196
fi
192197

193198
# Ensure config is correct (with or without preload)
@@ -202,7 +207,7 @@ start_server() {
202207
# 2. Restart server (so background worker reconnects with fresh cached plans)
203208
if "$PG_ISREADY" -h localhost -p $PG_PORT &>/dev/null; then
204209
# Drop schemas before restart (background worker will recreate on reconnect)
205-
"$PSQL" -h localhost -p $PG_PORT -d $PG_DB -c "DROP SCHEMA IF EXISTS duroxide CASCADE; DROP EXTENSION IF EXISTS pg_durable CASCADE;" >/dev/null 2>&1
210+
"$PSQL" -h localhost -p $PG_PORT -U $PG_USER -d $PG_DB -c "DROP SCHEMA IF EXISTS duroxide CASCADE; DROP EXTENSION IF EXISTS pg_durable CASCADE;" >/dev/null 2>&1
206211
echo -e "${YELLOW}Restarting PostgreSQL to reload extension...${NC}"
207212
stop_server
208213
fi
@@ -215,10 +220,10 @@ start_server() {
215220
if [ "$NO_PRELOAD" = true ]; then
216221
# Drop extension if it exists from a previous run (e.g., unit tests)
217222
# so the no-preload test can verify CREATE EXTENSION fails correctly
218-
"$PSQL" -h localhost -p $PG_PORT -d $PG_DB -c "DROP EXTENSION IF EXISTS pg_durable CASCADE; DROP SCHEMA IF EXISTS duroxide CASCADE;" >/dev/null 2>&1
223+
"$PSQL" -h localhost -p $PG_PORT -U $PG_USER -d $PG_DB -c "DROP EXTENSION IF EXISTS pg_durable CASCADE; DROP SCHEMA IF EXISTS duroxide CASCADE;" >/dev/null 2>&1
219224
else
220225
# Create extension (duroxide schema will be created by background worker on first connect)
221-
"$PSQL" -h localhost -p $PG_PORT -d $PG_DB -c "CREATE EXTENSION IF NOT EXISTS pg_durable;" >/dev/null 2>&1
226+
"$PSQL" -h localhost -p $PG_PORT -U $PG_USER -d $PG_DB -c "CREATE EXTENSION IF NOT EXISTS pg_durable;" >/dev/null 2>&1
222227
fi
223228
}
224229

@@ -242,7 +247,7 @@ start_server
242247
# Show version and run setup (only when extension is loaded, not in --no-preload mode)
243248
if [ "$NO_PRELOAD" = false ]; then
244249
echo -n "pg_durable version: "
245-
"$PSQL" -h localhost -p $PG_PORT -d $PG_DB -t -c "SELECT df.version();" 2>/dev/null | tr -d ' \n'
250+
"$PSQL" -h localhost -p $PG_PORT -U $PG_USER -d $PG_DB -t -c "SELECT df.version();" 2>/dev/null | tr -d ' \n'
246251
echo ""
247252
echo ""
248253

src/lib.rs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,17 @@
33
//! This extension provides durable, fault-tolerant function execution within PostgreSQL
44
//! using the Duroxide runtime for persistence.
55
6+
use pgrx::guc::*;
67
use pgrx::prelude::*;
8+
use std::ffi::{CStr, CString};
9+
10+
// ============================================================================
11+
// GUC Definitions
12+
// ============================================================================
13+
14+
pub static WORKER_ROLE: GucSetting<Option<CString>> = GucSetting::<Option<CString>>::new(Some(unsafe {
15+
CStr::from_bytes_with_nul_unchecked(b"azuresu\0")
16+
}));
717

818
// Module declarations
919
pub mod activities;
@@ -32,6 +42,15 @@ pub extern "C-unwind" fn _PG_init() {
3242
"pg_durable must be loaded via shared_preload_libraries.\n\nHINT: Add 'pg_durable' to shared_preload_libraries in postgresql.conf and restart the server."
3343
);
3444
}
45+
GucRegistry::define_string_guc(
46+
c"pg_durable.worker_role",
47+
c"PostgreSQL role used by the pg_durable background worker",
48+
c"",
49+
&WORKER_ROLE,
50+
GucContext::Postmaster,
51+
GucFlags::default(),
52+
);
53+
3554
worker::register_background_worker();
3655
}
3756

@@ -1554,6 +1573,9 @@ pub mod pg_test {
15541573

15551574
#[must_use]
15561575
pub fn postgresql_conf_options() -> Vec<&'static str> {
1557-
vec!["shared_preload_libraries = 'pg_durable'"]
1576+
vec![
1577+
"shared_preload_libraries = 'pg_durable'",
1578+
"pg_durable.worker_role = 'postgres'",
1579+
]
15581580
}
15591581
}

src/types.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use chrono::{DateTime, Utc};
44
use cron::Schedule as CronSchedule;
55
use pgrx::prelude::*;
66
use serde::{Deserialize, Serialize};
7+
use std::ffi::CString;
78
use std::str::FromStr;
89
use std::time::Duration;
910
use uuid::Uuid;
@@ -12,6 +13,15 @@ use uuid::Uuid;
1213
// Configuration Functions
1314
// ============================================================================
1415

16+
/// Get the worker role from the `pg_durable.worker_role` GUC.
17+
/// Falls back to `"azuresu"` if the GUC is not set.
18+
pub fn get_worker_role() -> String {
19+
crate::WORKER_ROLE
20+
.get()
21+
.map(|cs: CString| cs.to_string_lossy().into_owned())
22+
.unwrap_or_else(|| "azuresu".to_string())
23+
}
24+
1525
/// Generate a short 8-character instance ID from a UUID
1626
pub fn short_id() -> String {
1727
let uuid = Uuid::new_v4();
@@ -29,9 +39,7 @@ pub fn short_id() -> String {
2939
pub fn postgres_connection_string() -> String {
3040
let host = std::env::var("PGHOST").unwrap_or_else(|_| "127.0.0.1".to_string());
3141
let port = unsafe { pgrx::pg_sys::PostPortNumber };
32-
let user = std::env::var("PGUSER")
33-
.or_else(|_| std::env::var("USER"))
34-
.unwrap_or_else(|_| "postgres".to_string());
42+
let user = get_worker_role();
3543
let database = std::env::var("POSTGRES_DB")
3644
.or_else(|_| std::env::var("PGDATABASE"))
3745
.unwrap_or_else(|_| "postgres".to_string());

src/worker.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ pub extern "C-unwind" fn duroxide_worker_main(_arg: pg_sys::Datum) {
8282
async fn run_duroxide_runtime() {
8383
const WAIT_FOR_EXTENSION_POLL_INTERVAL: Duration = Duration::from_secs(5);
8484
const EXTENSION_DROP_POLL_INTERVAL: Duration = Duration::from_secs(5);
85-
const INIT_RETRY_INTERVAL: Duration = Duration::from_secs(5);
85+
const INIT_RETRY_INTERVAL: Duration = Duration::from_secs(1);
8686
const SHUTDOWN_CHECK_INTERVAL: Duration = Duration::from_secs(1);
8787

8888
let pg_conn_str = postgres_connection_string();

tests/e2e/sql/22_cross_connection.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ CREATE TABLE cross_conn_log (
1818
-- This simulates an external system or different user session
1919
-- Use host=localhost to force TCP connection instead of socket
2020
CREATE TEMP TABLE _dblink_conn AS
21-
SELECT format('host=localhost dbname=postgres port=%s', current_setting('port')) AS connstr;
21+
SELECT format('host=localhost dbname=postgres port=%s user=postgres', current_setting('port')) AS connstr;
2222

2323
-- ============================================================================
2424
-- Test 1: Signal from Different Connection

tests/e2e/sql/23_transactions.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ END $$;
173173

174174
DO $$
175175
DECLARE
176-
connstr TEXT := 'host=localhost dbname=postgres port=28817';
176+
connstr TEXT := format('host=localhost dbname=postgres port=%s user=postgres', current_setting('port'));
177177
result TEXT;
178178
instance_count INT;
179179
BEGIN

tests/e2e/sql/29_database_validation.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ DECLARE
9595
err_msg TEXT;
9696
BEGIN
9797
connstr := format(
98-
'host=localhost dbname=_test_wrong_db port=%s',
98+
'host=localhost dbname=_test_wrong_db port=%s user=postgres',
9999
current_setting('port')
100100
);
101101

0 commit comments

Comments
 (0)