mirror of
https://github.com/photoprism/photoprism.git
synced 2025-09-26 21:01:58 +08:00
Config: Set TCP timeout for establishing a database connection #4059
Signed-off-by: Michael Mayer <michael@photoprism.app>
This commit is contained in:
@@ -41,7 +41,7 @@ services:
|
||||
PHOTOPRISM_DATABASE_PASSWORD: "photoprism"
|
||||
PHOTOPRISM_TEST_DRIVER: "sqlite"
|
||||
PHOTOPRISM_TEST_DSN: ".test.db"
|
||||
PHOTOPRISM_TEST_DSN_MYSQL8: "root:photoprism@tcp(mysql:4001)/photoprism?charset=utf8mb4,utf8&collation=utf8mb4_unicode_ci&parseTime=true"
|
||||
# PHOTOPRISM_TEST_DSN_MYSQL8: "root:photoprism@tcp(mysql:4001)/photoprism?charset=utf8mb4,utf8&collation=utf8mb4_unicode_ci&parseTime=true&timeout=15s"
|
||||
PHOTOPRISM_ASSETS_PATH: "/go/src/github.com/photoprism/photoprism/assets"
|
||||
PHOTOPRISM_STORAGE_PATH: "/go/src/github.com/photoprism/photoprism/storage"
|
||||
PHOTOPRISM_ORIGINALS_PATH: "/go/src/github.com/photoprism/photoprism/storage/originals"
|
||||
|
@@ -78,7 +78,7 @@ services:
|
||||
PHOTOPRISM_DATABASE_USER: "root"
|
||||
PHOTOPRISM_DATABASE_PASSWORD: "photoprism"
|
||||
PHOTOPRISM_TEST_DRIVER: "sqlite"
|
||||
# PHOTOPRISM_TEST_DSN_MYSQL8: "root:photoprism@tcp(mysql:4001)/photoprism?charset=utf8mb4,utf8&collation=utf8mb4_unicode_ci&parseTime=true"
|
||||
# PHOTOPRISM_TEST_DSN_MYSQL8: "root:photoprism@tcp(mysql:4001)/photoprism?charset=utf8mb4,utf8&collation=utf8mb4_unicode_ci&parseTime=true&timeout=15s"
|
||||
PHOTOPRISM_ASSETS_PATH: "/go/src/github.com/photoprism/photoprism/assets"
|
||||
PHOTOPRISM_STORAGE_PATH: "/go/src/github.com/photoprism/photoprism/storage"
|
||||
PHOTOPRISM_ORIGINALS_PATH: "/go/src/github.com/photoprism/photoprism/storage/originals"
|
||||
|
@@ -72,20 +72,22 @@ func (c *Config) DatabaseDsn() string {
|
||||
}
|
||||
|
||||
return fmt.Sprintf(
|
||||
"%s:%s@%s/%s?charset=utf8mb4,utf8&collation=utf8mb4_unicode_ci&parseTime=true",
|
||||
"%s:%s@%s/%s?charset=utf8mb4,utf8&collation=utf8mb4_unicode_ci&parseTime=true&timeout=%ds",
|
||||
c.DatabaseUser(),
|
||||
c.DatabasePassword(),
|
||||
address,
|
||||
c.DatabaseName(),
|
||||
c.DatabaseTimeout(),
|
||||
)
|
||||
case Postgres:
|
||||
return fmt.Sprintf(
|
||||
"user=%s password=%s dbname=%s host=%s port=%d sslmode=disable TimeZone=UTC",
|
||||
"user=%s password=%s dbname=%s host=%s port=%d connect_timeout=%d sslmode=disable TimeZone=UTC",
|
||||
c.DatabaseUser(),
|
||||
c.DatabasePassword(),
|
||||
c.DatabaseName(),
|
||||
c.DatabaseHost(),
|
||||
c.DatabasePort(),
|
||||
c.DatabaseTimeout(),
|
||||
)
|
||||
case SQLite3:
|
||||
return filepath.Join(c.StoragePath(), "index.db?_busy_timeout=5000")
|
||||
@@ -209,6 +211,21 @@ func (c *Config) DatabasePassword() string {
|
||||
return c.options.DatabasePassword
|
||||
}
|
||||
|
||||
// DatabaseTimeout returns the TCP timeout in seconds for establishing a database connection:
|
||||
// - https://github.com/photoprism/photoprism/issues/4059#issuecomment-1989119004
|
||||
// - https://github.com/go-sql-driver/mysql/blob/master/README.md#timeout
|
||||
func (c *Config) DatabaseTimeout() int {
|
||||
// Ensure that the timeout is between 1 and a maximum
|
||||
// of 60 seconds, with a default of 15 seconds.
|
||||
if c.options.DatabaseTimeout <= 0 {
|
||||
return 15
|
||||
} else if c.options.DatabaseTimeout > 60 {
|
||||
return 60
|
||||
}
|
||||
|
||||
return c.options.DatabaseTimeout
|
||||
}
|
||||
|
||||
// DatabaseConns returns the maximum number of open connections to the database.
|
||||
func (c *Config) DatabaseConns() int {
|
||||
limit := c.options.DatabaseConns
|
||||
|
@@ -96,7 +96,7 @@ func TestConfig_DatabaseDsn(t *testing.T) {
|
||||
assert.Equal(t, SQLite3, driver)
|
||||
c.options.DatabaseDsn = ""
|
||||
c.options.DatabaseDriver = "MariaDB"
|
||||
assert.Equal(t, "photoprism:@tcp(localhost)/photoprism?charset=utf8mb4,utf8&collation=utf8mb4_unicode_ci&parseTime=true", c.DatabaseDsn())
|
||||
assert.Equal(t, "photoprism:@tcp(localhost)/photoprism?charset=utf8mb4,utf8&collation=utf8mb4_unicode_ci&parseTime=true&timeout=15s", c.DatabaseDsn())
|
||||
c.options.DatabaseDriver = "tidb"
|
||||
assert.Equal(t, "/go/src/github.com/photoprism/photoprism/storage/testdata/index.db?_busy_timeout=5000", c.DatabaseDsn())
|
||||
c.options.DatabaseDriver = "Postgres"
|
||||
@@ -117,6 +117,21 @@ func TestConfig_DatabaseFile(t *testing.T) {
|
||||
assert.Equal(t, "/go/src/github.com/photoprism/photoprism/storage/testdata/index.db?_busy_timeout=5000", c.DatabaseDsn())
|
||||
}
|
||||
|
||||
func TestConfig_DatabaseTimeout(t *testing.T) {
|
||||
c := NewConfig(CliTestContext())
|
||||
assert.Equal(t, 15, c.DatabaseTimeout())
|
||||
c.options.DatabaseTimeout = 1
|
||||
assert.Equal(t, 1, c.DatabaseTimeout())
|
||||
c.options.DatabaseTimeout = -1
|
||||
assert.Equal(t, 15, c.DatabaseTimeout())
|
||||
c.options.DatabaseTimeout = 120
|
||||
assert.Equal(t, 60, c.DatabaseTimeout())
|
||||
c.options.DatabaseTimeout = 0
|
||||
assert.Equal(t, 15, c.DatabaseTimeout())
|
||||
c.options.DatabaseTimeout = 15
|
||||
assert.Equal(t, 15, c.DatabaseTimeout())
|
||||
}
|
||||
|
||||
func TestConfig_DatabaseConns(t *testing.T) {
|
||||
c := NewConfig(CliTestContext())
|
||||
c.options.DatabaseConns = 28
|
||||
|
@@ -571,6 +571,12 @@ var Flags = CliFlags{
|
||||
Usage: "database user `PASSWORD`",
|
||||
EnvVar: EnvVar("DATABASE_PASSWORD"),
|
||||
}}, {
|
||||
Flag: cli.IntFlag{
|
||||
Name: "database-timeout",
|
||||
Usage: "timeout in `SECONDS` for establishing a database connection (1-60)",
|
||||
EnvVar: EnvVar("DATABASE_TIMEOUT"),
|
||||
Value: 15,
|
||||
}}, {
|
||||
Flag: cli.IntFlag{
|
||||
Name: "database-conns",
|
||||
Usage: "maximum `NUMBER` of open database connections",
|
||||
|
@@ -128,6 +128,7 @@ type Options struct {
|
||||
DatabaseServer string `yaml:"DatabaseServer" json:"-" flag:"database-server"`
|
||||
DatabaseUser string `yaml:"DatabaseUser" json:"-" flag:"database-user"`
|
||||
DatabasePassword string `yaml:"DatabasePassword" json:"-" flag:"database-password"`
|
||||
DatabaseTimeout int `yaml:"DatabaseTimeout" json:"-" flag:"database-timeout"`
|
||||
DatabaseConns int `yaml:"DatabaseConns" json:"-" flag:"database-conns"`
|
||||
DatabaseConnsIdle int `yaml:"DatabaseConnsIdle" json:"-" flag:"database-conns-idle"`
|
||||
SipsBin string `yaml:"SipsBin" json:"-" flag:"sips-bin"`
|
||||
|
@@ -179,6 +179,7 @@ func (c *Config) Report() (rows [][]string, cols []string) {
|
||||
{"database-port", c.DatabasePortString()},
|
||||
{"database-user", c.DatabaseUser()},
|
||||
{"database-password", strings.Repeat("*", utf8.RuneCountInString(c.DatabasePassword()))},
|
||||
{"database-timeout", fmt.Sprintf("%d", c.DatabaseTimeout())},
|
||||
{"database-conns", fmt.Sprintf("%d", c.DatabaseConns())},
|
||||
{"database-conns-idle", fmt.Sprintf("%d", c.DatabaseConnsIdle())},
|
||||
{"mariadb-bin", c.MariadbBin()},
|
||||
|
Reference in New Issue
Block a user