Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 046c0108b6 | |||
| fb6cac93b7 | |||
| 77ef84758d |
+1
-4
@@ -748,10 +748,7 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
|
||||
var pubsubWatchdogTimeout <-chan struct{}
|
||||
|
||||
maxOpenConns := int(vals.PostgresConnMaxOpen.Value())
|
||||
maxIdleConns, err := codersdk.ComputeMaxIdleConns(maxOpenConns, vals.PostgresConnMaxIdle.Value())
|
||||
if err != nil {
|
||||
return xerrors.Errorf("compute max idle connections: %w", err)
|
||||
}
|
||||
maxIdleConns := int(vals.PostgresConnMaxIdle.Value())
|
||||
logger.Debug(ctx, "creating database connection pool", slog.F("max_open_conns", maxOpenConns), slog.F("max_idle_conns", maxIdleConns))
|
||||
sqlDB, dbURL, err := getAndMigratePostgresDB(ctx, logger, vals.PostgresURL.String(), codersdk.PostgresAuth(vals.PostgresAuth), sqlDriver,
|
||||
WithMaxOpenConns(maxOpenConns),
|
||||
|
||||
+4
-5
@@ -65,12 +65,11 @@ OPTIONS:
|
||||
Type of auth to use when connecting to postgres. For AWS RDS, using
|
||||
IAM authentication (awsiamrds) is recommended.
|
||||
|
||||
--postgres-conn-max-idle string, $CODER_PG_CONN_MAX_IDLE (default: auto)
|
||||
Maximum number of idle connections to the database. Set to "auto" (the
|
||||
default) to use max open / 3. Value must be greater or equal to 0; 0
|
||||
means explicitly no idle connections.
|
||||
--postgres-conn-max-idle int, $CODER_PG_CONN_MAX_IDLE (default: 15)
|
||||
Maximum number of idle connections to the database. Value must be
|
||||
greater or equal to 0; 0 means explicitly no idle connections.
|
||||
|
||||
--postgres-conn-max-open int, $CODER_PG_CONN_MAX_OPEN (default: 10)
|
||||
--postgres-conn-max-open int, $CODER_PG_CONN_MAX_OPEN (default: 30)
|
||||
Maximum number of open connections to the database. Defaults to 10.
|
||||
|
||||
--postgres-url string, $CODER_PG_CONNECTION_URL
|
||||
|
||||
+6
-7
@@ -484,13 +484,12 @@ ephemeralDeployment: false
|
||||
# (default: password, type: enum[password\|awsiamrds])
|
||||
pgAuth: password
|
||||
# Maximum number of open connections to the database. Defaults to 10.
|
||||
# (default: 10, type: int)
|
||||
pgConnMaxOpen: 10
|
||||
# Maximum number of idle connections to the database. Set to "auto" (the default)
|
||||
# to use max open / 3. Value must be greater or equal to 0; 0 means explicitly no
|
||||
# idle connections.
|
||||
# (default: auto, type: string)
|
||||
pgConnMaxIdle: auto
|
||||
# (default: 30, type: int)
|
||||
pgConnMaxOpen: 30
|
||||
# Maximum number of idle connections to the database. Value must be greater or
|
||||
# equal to 0; 0 means explicitly no idle connections.
|
||||
# (default: 15, type: int)
|
||||
pgConnMaxIdle: 15
|
||||
# A URL to an external Terms of Service that must be accepted by users when
|
||||
# logging in.
|
||||
# (default: <unset>, type: string)
|
||||
|
||||
Generated
+1
-1
@@ -14481,7 +14481,7 @@ const docTemplate = `{
|
||||
"type": "string"
|
||||
},
|
||||
"pg_conn_max_idle": {
|
||||
"type": "string"
|
||||
"type": "integer"
|
||||
},
|
||||
"pg_conn_max_open": {
|
||||
"type": "integer"
|
||||
|
||||
Generated
+1
-1
@@ -13051,7 +13051,7 @@
|
||||
"type": "string"
|
||||
},
|
||||
"pg_conn_max_idle": {
|
||||
"type": "string"
|
||||
"type": "integer"
|
||||
},
|
||||
"pg_conn_max_open": {
|
||||
"type": "integer"
|
||||
|
||||
+4
-33
@@ -442,10 +442,6 @@ var PostgresAuthDrivers = []string{
|
||||
string(PostgresAuthAWSIAMRDS),
|
||||
}
|
||||
|
||||
// PostgresConnMaxIdleAuto is the value for auto-computing max idle connections
|
||||
// based on max open connections.
|
||||
const PostgresConnMaxIdleAuto = "auto"
|
||||
|
||||
// DeploymentValues is the central configuration values the coder server.
|
||||
type DeploymentValues struct {
|
||||
Verbose serpent.Bool `json:"verbose,omitempty"`
|
||||
@@ -467,7 +463,7 @@ type DeploymentValues struct {
|
||||
PostgresURL serpent.String `json:"pg_connection_url,omitempty" typescript:",notnull"`
|
||||
PostgresAuth string `json:"pg_auth,omitempty" typescript:",notnull"`
|
||||
PostgresConnMaxOpen serpent.Int64 `json:"pg_conn_max_open,omitempty" typescript:",notnull"`
|
||||
PostgresConnMaxIdle serpent.String `json:"pg_conn_max_idle,omitempty" typescript:",notnull"`
|
||||
PostgresConnMaxIdle serpent.Int64 `json:"pg_conn_max_idle,omitempty" typescript:",notnull"`
|
||||
OAuth2 OAuth2Config `json:"oauth2,omitempty" typescript:",notnull"`
|
||||
OIDC OIDCConfig `json:"oidc,omitempty" typescript:",notnull"`
|
||||
Telemetry TelemetryConfig `json:"telemetry,omitempty" typescript:",notnull"`
|
||||
@@ -2634,7 +2630,7 @@ func (c *DeploymentValues) Options() serpent.OptionSet {
|
||||
Description: "Maximum number of open connections to the database. Defaults to 10.",
|
||||
Flag: "postgres-conn-max-open",
|
||||
Env: "CODER_PG_CONN_MAX_OPEN",
|
||||
Default: "10",
|
||||
Default: "30",
|
||||
Value: serpent.Validate(&c.PostgresConnMaxOpen, func(value *serpent.Int64) error {
|
||||
if value.Value() <= 0 {
|
||||
return xerrors.New("must be greater than zero")
|
||||
@@ -2645,11 +2641,11 @@ func (c *DeploymentValues) Options() serpent.OptionSet {
|
||||
},
|
||||
{
|
||||
Name: "Postgres Connection Max Idle",
|
||||
Description: "Maximum number of idle connections to the database. Set to \"auto\" (the default) to use max open / 3. " +
|
||||
Description: "Maximum number of idle connections to the database. " +
|
||||
"Value must be greater or equal to 0; 0 means explicitly no idle connections.",
|
||||
Flag: "postgres-conn-max-idle",
|
||||
Env: "CODER_PG_CONN_MAX_IDLE",
|
||||
Default: PostgresConnMaxIdleAuto,
|
||||
Default: "15",
|
||||
Value: &c.PostgresConnMaxIdle,
|
||||
YAML: "pgConnMaxIdle",
|
||||
},
|
||||
@@ -4203,28 +4199,3 @@ func (c CryptoKey) CanVerify(now time.Time) bool {
|
||||
beforeDelete := c.DeletesAt.IsZero() || now.Before(c.DeletesAt)
|
||||
return hasSecret && beforeDelete
|
||||
}
|
||||
|
||||
// ComputeMaxIdleConns calculates the effective maxIdleConns value. If
|
||||
// configuredIdle is "auto", it returns maxOpen/3 with a minimum of 1. If
|
||||
// configuredIdle exceeds maxOpen, it returns an error.
|
||||
func ComputeMaxIdleConns(maxOpen int, configuredIdle string) (int, error) {
|
||||
configuredIdle = strings.TrimSpace(configuredIdle)
|
||||
if configuredIdle == PostgresConnMaxIdleAuto {
|
||||
computed := maxOpen / 3
|
||||
if computed < 1 {
|
||||
return 1, nil
|
||||
}
|
||||
return computed, nil
|
||||
}
|
||||
idle, err := strconv.Atoi(configuredIdle)
|
||||
if err != nil {
|
||||
return 0, xerrors.Errorf("invalid max idle connections %q: must be %q or >= 0", configuredIdle, PostgresConnMaxIdleAuto)
|
||||
}
|
||||
if idle < 0 {
|
||||
return 0, xerrors.Errorf("max idle connections must be %q or >= 0", PostgresConnMaxIdleAuto)
|
||||
}
|
||||
if idle > maxOpen {
|
||||
return 0, xerrors.Errorf("max idle connections (%d) cannot exceed max open connections (%d)", idle, maxOpen)
|
||||
}
|
||||
return idle, nil
|
||||
}
|
||||
|
||||
@@ -765,120 +765,3 @@ func TestRetentionConfigParsing(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestComputeMaxIdleConns(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
maxOpen int
|
||||
configuredIdle string
|
||||
expectedIdle int
|
||||
expectError bool
|
||||
errorContains string
|
||||
}{
|
||||
{
|
||||
name: "auto_default_10_open",
|
||||
maxOpen: 10,
|
||||
configuredIdle: "auto",
|
||||
expectedIdle: 3, // 10/3 = 3
|
||||
},
|
||||
{
|
||||
name: "auto_with_whitespace",
|
||||
maxOpen: 10,
|
||||
configuredIdle: " auto ",
|
||||
expectedIdle: 3, // 10/3 = 3
|
||||
},
|
||||
{
|
||||
name: "auto_30_open",
|
||||
maxOpen: 30,
|
||||
configuredIdle: "auto",
|
||||
expectedIdle: 10, // 30/3 = 10
|
||||
},
|
||||
{
|
||||
name: "auto_minimum_1",
|
||||
maxOpen: 1,
|
||||
configuredIdle: "auto",
|
||||
expectedIdle: 1, // 1/3 = 0, but minimum is 1
|
||||
},
|
||||
{
|
||||
name: "auto_minimum_2_open",
|
||||
maxOpen: 2,
|
||||
configuredIdle: "auto",
|
||||
expectedIdle: 1, // 2/3 = 0, but minimum is 1
|
||||
},
|
||||
{
|
||||
name: "auto_3_open",
|
||||
maxOpen: 3,
|
||||
configuredIdle: "auto",
|
||||
expectedIdle: 1, // 3/3 = 1
|
||||
},
|
||||
{
|
||||
name: "explicit_equal_to_max",
|
||||
maxOpen: 10,
|
||||
configuredIdle: "10",
|
||||
expectedIdle: 10,
|
||||
},
|
||||
{
|
||||
name: "explicit_less_than_max",
|
||||
maxOpen: 10,
|
||||
configuredIdle: "5",
|
||||
expectedIdle: 5,
|
||||
},
|
||||
{
|
||||
name: "explicit_with_whitespace",
|
||||
maxOpen: 10,
|
||||
configuredIdle: " 5 ",
|
||||
expectedIdle: 5,
|
||||
},
|
||||
{
|
||||
name: "explicit_0",
|
||||
maxOpen: 10,
|
||||
configuredIdle: "0",
|
||||
expectedIdle: 0,
|
||||
},
|
||||
{
|
||||
name: "error_exceeds_max",
|
||||
maxOpen: 10,
|
||||
configuredIdle: "15",
|
||||
expectError: true,
|
||||
errorContains: "cannot exceed",
|
||||
},
|
||||
{
|
||||
name: "error_exceeds_max_by_1",
|
||||
maxOpen: 10,
|
||||
configuredIdle: "11",
|
||||
expectError: true,
|
||||
errorContains: "cannot exceed",
|
||||
},
|
||||
{
|
||||
name: "error_invalid_string",
|
||||
maxOpen: 10,
|
||||
configuredIdle: "invalid",
|
||||
expectError: true,
|
||||
errorContains: "must be \"auto\" or >= 0",
|
||||
},
|
||||
{
|
||||
name: "error_negative",
|
||||
maxOpen: 10,
|
||||
configuredIdle: "-1",
|
||||
expectError: true,
|
||||
errorContains: "must be \"auto\" or >= 0",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
result, err := codersdk.ComputeMaxIdleConns(tt.maxOpen, tt.configuredIdle)
|
||||
if tt.expectError {
|
||||
require.Error(t, err)
|
||||
require.Contains(t, err.Error(), tt.errorContains)
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, tt.expectedIdle, result)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Generated
+1
-1
@@ -439,7 +439,7 @@ curl -X GET http://coder-server:8080/api/v2/deployment/config \
|
||||
"username_field": "string"
|
||||
},
|
||||
"pg_auth": "string",
|
||||
"pg_conn_max_idle": "string",
|
||||
"pg_conn_max_idle": 0,
|
||||
"pg_conn_max_open": 0,
|
||||
"pg_connection_url": "string",
|
||||
"pprof": {
|
||||
|
||||
Generated
+3
-3
@@ -2915,7 +2915,7 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o
|
||||
"username_field": "string"
|
||||
},
|
||||
"pg_auth": "string",
|
||||
"pg_conn_max_idle": "string",
|
||||
"pg_conn_max_idle": 0,
|
||||
"pg_conn_max_open": 0,
|
||||
"pg_connection_url": "string",
|
||||
"pprof": {
|
||||
@@ -3462,7 +3462,7 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o
|
||||
"username_field": "string"
|
||||
},
|
||||
"pg_auth": "string",
|
||||
"pg_conn_max_idle": "string",
|
||||
"pg_conn_max_idle": 0,
|
||||
"pg_conn_max_open": 0,
|
||||
"pg_connection_url": "string",
|
||||
"pprof": {
|
||||
@@ -3654,7 +3654,7 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o
|
||||
| `oauth2` | [codersdk.OAuth2Config](#codersdkoauth2config) | false | | |
|
||||
| `oidc` | [codersdk.OIDCConfig](#codersdkoidcconfig) | false | | |
|
||||
| `pg_auth` | string | false | | |
|
||||
| `pg_conn_max_idle` | string | false | | |
|
||||
| `pg_conn_max_idle` | integer | false | | |
|
||||
| `pg_conn_max_open` | integer | false | | |
|
||||
| `pg_connection_url` | string | false | | |
|
||||
| `pprof` | [codersdk.PprofConfig](#codersdkpprofconfig) | false | | |
|
||||
|
||||
Generated
+4
-4
@@ -1022,7 +1022,7 @@ Type of auth to use when connecting to postgres. For AWS RDS, using IAM authenti
|
||||
| Type | <code>int</code> |
|
||||
| Environment | <code>$CODER_PG_CONN_MAX_OPEN</code> |
|
||||
| YAML | <code>pgConnMaxOpen</code> |
|
||||
| Default | <code>10</code> |
|
||||
| Default | <code>30</code> |
|
||||
|
||||
Maximum number of open connections to the database. Defaults to 10.
|
||||
|
||||
@@ -1030,12 +1030,12 @@ Maximum number of open connections to the database. Defaults to 10.
|
||||
|
||||
| | |
|
||||
|-------------|--------------------------------------|
|
||||
| Type | <code>string</code> |
|
||||
| Type | <code>int</code> |
|
||||
| Environment | <code>$CODER_PG_CONN_MAX_IDLE</code> |
|
||||
| YAML | <code>pgConnMaxIdle</code> |
|
||||
| Default | <code>auto</code> |
|
||||
| Default | <code>15</code> |
|
||||
|
||||
Maximum number of idle connections to the database. Set to "auto" (the default) to use max open / 3. Value must be greater or equal to 0; 0 means explicitly no idle connections.
|
||||
Maximum number of idle connections to the database. Value must be greater or equal to 0; 0 means explicitly no idle connections.
|
||||
|
||||
### --secure-auth-cookie
|
||||
|
||||
|
||||
@@ -224,12 +224,12 @@ Coder Server maintains a pool of connections to PostgreSQL. You can tune the
|
||||
pool size with these settings:
|
||||
|
||||
- `--postgres-conn-max-open` (env: `CODER_PG_CONN_MAX_OPEN`): Maximum number of open
|
||||
connections. Default: 10. Ensure that your PostgreSQL Server has `max_connections`
|
||||
connections. Default: 30. Ensure that your PostgreSQL Server has `max_connections`
|
||||
set appropriately to accommodate all Coder Server replicas multiplied by the
|
||||
maximum number of open connections. We recommend configuring an additional 20%
|
||||
of connections to account for churn and other clients.
|
||||
- `--postgres-conn-max-idle` (env: `CODER_PG_CONN_MAX_IDLE`): Maximum number of idle
|
||||
connections kept in the pool. Default: "auto", which uses max open / 3.
|
||||
connections kept in the pool. Default: 15.
|
||||
|
||||
When a connection is returned to the pool and the idle pool is already full, the
|
||||
connection is closed immediately. This can cause connection establishment
|
||||
|
||||
+4
-5
@@ -66,12 +66,11 @@ OPTIONS:
|
||||
Type of auth to use when connecting to postgres. For AWS RDS, using
|
||||
IAM authentication (awsiamrds) is recommended.
|
||||
|
||||
--postgres-conn-max-idle string, $CODER_PG_CONN_MAX_IDLE (default: auto)
|
||||
Maximum number of idle connections to the database. Set to "auto" (the
|
||||
default) to use max open / 3. Value must be greater or equal to 0; 0
|
||||
means explicitly no idle connections.
|
||||
--postgres-conn-max-idle int, $CODER_PG_CONN_MAX_IDLE (default: 15)
|
||||
Maximum number of idle connections to the database. Value must be
|
||||
greater or equal to 0; 0 means explicitly no idle connections.
|
||||
|
||||
--postgres-conn-max-open int, $CODER_PG_CONN_MAX_OPEN (default: 10)
|
||||
--postgres-conn-max-open int, $CODER_PG_CONN_MAX_OPEN (default: 30)
|
||||
Maximum number of open connections to the database. Defaults to 10.
|
||||
|
||||
--postgres-url string, $CODER_PG_CONNECTION_URL
|
||||
|
||||
Generated
+1
-8
@@ -1741,7 +1741,7 @@ export interface DeploymentValues {
|
||||
readonly pg_connection_url?: string;
|
||||
readonly pg_auth?: string;
|
||||
readonly pg_conn_max_open?: number;
|
||||
readonly pg_conn_max_idle?: string;
|
||||
readonly pg_conn_max_idle?: number;
|
||||
readonly oauth2?: OAuth2Config;
|
||||
readonly oidc?: OIDCConfig;
|
||||
readonly telemetry?: TelemetryConfig;
|
||||
@@ -3582,13 +3582,6 @@ export type PostgresAuth = "awsiamrds" | "password";
|
||||
|
||||
export const PostgresAuths: PostgresAuth[] = ["awsiamrds", "password"];
|
||||
|
||||
// From codersdk/deployment.go
|
||||
/**
|
||||
* PostgresConnMaxIdleAuto is the value for auto-computing max idle connections
|
||||
* based on max open connections.
|
||||
*/
|
||||
export const PostgresConnMaxIdleAuto = "auto";
|
||||
|
||||
// From codersdk/deployment.go
|
||||
export interface PprofConfig {
|
||||
readonly enable: boolean;
|
||||
|
||||
Reference in New Issue
Block a user