From 6814b69a09c6b653de8e7226c85a69611768b148 Mon Sep 17 00:00:00 2001 From: Gabriel Adrian Samfira Date: Tue, 28 Jan 2025 20:00:49 +0000 Subject: [PATCH] Add knob to tweak _busy_timeout In SQLite3 we may need to set a busy_timeout in the case of instances with high load. This change adds a knob that allows users to set a timeout if a database is locked for writing by another routine. Signed-off-by: Gabriel Adrian Samfira --- config/config.go | 10 ++++++++-- config/config_test.go | 6 ++++++ testdata/config.toml | 5 +++++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/config/config.go b/config/config.go index 04d26ada..d485d871 100644 --- a/config/config.go +++ b/config/config.go @@ -551,7 +551,8 @@ func (d *Database) Validate() error { // SQLite is the config entry for the sqlite3 section type SQLite struct { - DBFile string `toml:"db_file" json:"db-file"` + DBFile string `toml:"db_file" json:"db-file"` + BusyTimeoutSeconds int `toml:"busy_timeout_seconds" json:"busy-timeout-seconds"` } func (s *SQLite) Validate() error { @@ -571,7 +572,12 @@ func (s *SQLite) Validate() error { } func (s *SQLite) ConnectionString() (string, error) { - return fmt.Sprintf("%s?_journal_mode=WAL&_foreign_keys=ON", s.DBFile), nil + connectionString := fmt.Sprintf("%s?_journal_mode=WAL&_foreign_keys=ON", s.DBFile) + if s.BusyTimeoutSeconds > 0 { + timeout := s.BusyTimeoutSeconds * 1000 + connectionString = fmt.Sprintf("%s&_busy_timeout=%d", connectionString, timeout) + } + return connectionString, nil } // MySQL is the config entry for the mysql section diff --git a/config/config_test.go b/config/config_test.go index b94956fc..792130eb 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -389,6 +389,12 @@ func TestGormParams(t *testing.T) { require.Equal(t, SQLiteBackend, dbType) require.Equal(t, filepath.Join(dir, "garm.db?_journal_mode=WAL&_foreign_keys=ON"), uri) + cfg.SQLite.BusyTimeoutSeconds = 5 + dbType, uri, err = cfg.GormParams() + require.Nil(t, err) + require.Equal(t, SQLiteBackend, dbType) + require.Equal(t, filepath.Join(dir, "garm.db?_journal_mode=WAL&_foreign_keys=ON&_busy_timeout=5000"), uri) + cfg.DbBackend = MySQLBackend cfg.MySQL = getMySQLDefaultConfig() cfg.SQLite = SQLite{} diff --git a/testdata/config.toml b/testdata/config.toml index b3e5fb1d..ee85ee33 100644 --- a/testdata/config.toml +++ b/testdata/config.toml @@ -97,6 +97,11 @@ time_to_live = "8760h" [database.sqlite3] # Path on disk to the sqlite3 database file. db_file = "/etc/garm/garm.db" + # busy_timeout_seconds is an optional parameter that will set the + # sqlite3_busy_timeout to the specified value. This is useful when + # GARM may be under heavy load and the database is locked by some + # other go routine. The default value is 0. + busy_timeout_seconds = 5 # Currently, providers are defined statically in the config. This is due to the fact # that we have not yet added support for storing secrets in something like Barbican