Loading…
Loading…
Configure the worker service's database connection pool, including IAM and password authentication, multi-tenancy, resilience, and performance tuning.
This document describes the database DataSource configuration for the worker service. This component establishes and manages a pool of connections to the primary PostgreSQL database, ensuring resilient, performant, and secure data access for all worker operations.
The configuration provides two primary authentication methods:
Beyond authentication, this component is responsible for:
All worker processes that interact with the database, including background job processors and event listeners, use the DataSource configured here.
The system initializes a single DataSource bean on startup. The configuration process follows several key steps: authentication mode selection, pool configuration, and multi-tenancy enforcement.
flowchart TD
subgraph Initialization
A[Start] --> B{Check S2R_DB_IAM_AUTH_ENABLED};
B -- "Is 'false'" --> PwAuth[Use Password Auth];
B -- "Is not 'false' (default)" --> C{Check authMode property};
C -- "Is 'iam'" --> IamAuth[Use IAM Auth];
C -- "Is not 'iam'" --> PwAuth;
end
subgraph Configuration
IamAuth --> D[Configure Cloud SQL Connector];
PwAuth --> E[Configure Standard JDBC];
D --> F[Set Pool Properties];
E --> F;
F --> G[Apply Socket Timeouts];
G --> H[Set Dynamic Leak Detection];
end
subgraph Finalization
H --> I[Wrap for Tenant ID Binding];
I --> J[Install SaaS Security Gate];
J --> K[DataSource Ready];
endThe choice between IAM and password authentication is determined by the S2R_DB_IAM_AUTH_ENABLED environment variable and the authMode configuration property.
S2R_DB_IAM_AUTH_ENABLED is not set to false (case-insensitive) AND the authMode property is set to iam.S2R_DB_IAM_AUTH_ENABLED to false or using an authMode other than iam.A log message S2R-CFG: IAM DB auth disabled — using password auth (worker) is emitted when password authentication is activated via the environment variable.
When IAM authentication is active, the system configures the connection pool to use the Cloud SQL Java connector (com.google.cloud.sql.postgres.SocketFactory).
jdbc:postgresql:///<database_name>, omitting the host and port.cloudSqlInstance connection name (e.g., project:region:instance).PRIVATE or PUBLIC) can be specified via the ipType property.A log message S2R-CFG: Cloud SQL connector IAM auth (worker) instance=... ipType=... confirms this mode is active.
When password authentication is active, the system configures a standard JDBC connection.
host, port, name, and password.jdbc:postgresql://<host>:<port>/<name>?sslmode=<ssl_mode>.sslmode defaults to require if not otherwise specified.The service uses a HikariDataSource instance with settings tailored for the worker's workload.
maximumPoolSize) and a minimum of 4 idle connections (minimumIdle). This provides headroom for high-load events like data replay storms.socketTimeoutSeconds) is applied to each underlying database connection. This ensures that a connection borrowed from the pool will not hang indefinitely on a dead socket, allowing the application to handle the error and the pool to self-heal once network connectivity is restored.IMPORTANT
The socketTimeoutSeconds setting is critical for service stability. Without it, a network partition can wedge all active connections, leading to pool exhaustion and requiring a service restart to recover.
leakDetectionThreshold) is dynamically set to twice the value of the socketTimeoutSeconds. This avoids spurious "leak" warnings for long-running but legitimate queries, ensuring that logged warnings are more likely to indicate a genuine problem, such as a connection that is stuck or not being closed properly. If socketTimeoutSeconds is 0, leak detection is disabled.After the base connection pool is configured, it is wrapped to support multi-tenancy.
Tenant ID Binding: The DataSource is wrapped in a TenantBindingDataSource. This wrapper ensures that for every connection borrowed from the pool, the session variable app.tenant_id is set to the ID of the current tenant in context. This mechanism is foundational for enabling database-level Row-Level Security (RLS). A log message S2R-TENANCY-DB binding=app.tenant_id ... is emitted.
SaaS Security Gate: A "SaaS gate" is installed on the DataSource. In a multi-tenant deployment, this gate prevents database operations from executing if no tenant context is bound to the connection. This acts as a fail-safe mechanism, ensuring that code cannot accidentally access data without proper tenant scoping. The gate's status is determined by SettingBackedSaasCapability, which relies on a cached value and does not query the database during the check. A log message S2R-TENANCY-DB saas-unbound-gate installed=true ... confirms its installation.
Configuration is provided through a combination of environment variables and a DbProperties object, which is typically populated from the application's configuration files or environment variables.
| Parameter | Type | Default | Required | Description |
|---|---|---|---|---|
S2R_DB_IAM_AUTH_ENABLED | String (env var) | true | No | If set to false (case-insensitive), forces password authentication. Otherwise, IAM auth is determined by authMode. |
user | String | — | Yes | The database user to connect as. Corresponds to S2R_DB_USER. |
authMode | String | — | No | The authentication mode. Set to iam to enable IAM-based authentication. |
instanceConnectionName | String | — | Yes, for IAM auth | The Cloud SQL instance connection name (format: project:region:instance). Corresponds to S2R_DB_INSTANCE_CONNECTION_NAME. |
ipType | String | PRIVATE | No | The IP type for Cloud SQL IAM connections (e.g., PRIVATE, PUBLIC). |
name | String | — | Yes | The name of the database to connect to. |
host | String | — | Yes, for password auth | The hostname or IP address of the database server. Corresponds to S2R_DB_HOST. |
port | Integer | — | Yes, for password auth | The port number of the database server. |
password | String | — | Yes, for password auth | The password for the database user. Corresponds to S2R_DB_PASSWORD. |
sslMode | String | require | No | The SSL mode for password-based connections (e.g., disable, allow, prefer, require, verify-ca, verify-full). |
socketTimeoutSeconds | Integer | — | No | Socket read timeout in seconds. A value > 0 is strongly recommended for resilience. |
connectTimeoutSeconds | Integer | — | No | Database connection timeout in seconds. |
The following HikariCP settings are hardcoded in the worker configuration to optimize for its specific workload. They are not user-configurable.
| Setting | Value | Description |
|---|---|---|
poolName | s2r-worker-hikari | The name of the connection pool, visible in logs and metrics. |
maximumPoolSize | 16 | Maximum number of connections in the pool. Sized for replay-storm bursts. |
minimumIdle | 4 | Minimum number of idle connections maintained by the pool. |
registerMbeans | true | Exposes pool metrics via JMX for monitoring. |
connectionTimeout | 3000 ms | Maximum time to wait for a connection from the pool. |
validationTimeout | 2000 ms | Maximum time to wait for a connection to be validated. |
initializationFailTimeout | -1 | Fail-fast on startup if a connection cannot be established. |
maxLifetime | 30 minutes | Maximum lifetime of a connection in the pool. |
keepaliveTime | 10 minutes | Time between keepalive probes to prevent idle connections from being terminated by firewalls. |
leakDetectionThreshold | 2 * socketTimeoutSeconds | Time a connection can be in-use before a leak is suspected and logged. Disabled if socketTimeoutSeconds is 0. |
The service will fail to start if required configuration is missing. Check the logs for one of the following IllegalStateException messages:
S2R_DB_USER must be configured: The user property is missing or empty.S2R_DB_INSTANCE_CONNECTION_NAME required for IAM auth: IAM authentication is enabled, but the instanceConnectionName property is missing.S2R_DB_HOST must be configured for password auth: Password authentication is enabled, but the host property is missing.S2R-TENANCY-UNBOUND, it means a database connection was used without a tenant context being set. This is a security measure to prevent cross-tenant data access. The calling code must be wrapped in a tenant context (e.g., via TenantContext.runAs).leakDetectionThreshold. This indicates a slow database query or an application code path that is not closing a database connection in a timely manner.app.tenant_id session variable and its role in the multi-tenancy architecture, refer to the platform's data model documentation.