diff --git a/README.md b/README.md index 71e60b6..ccb89e9 100644 --- a/README.md +++ b/README.md @@ -433,8 +433,10 @@ Additional arguments can be passed to `./SewerRat` to control its behavior (chec - `-update` controls the frequency of index updates. This defaults to 24 hours. - `-session` specifies the lifetime of a registration sesssion - (i.e., the maximum time between starting and finishing the registration, see below). + (i.e., the maximum time between starting and finishing the registration, see above). This defaults to 10 minutes. +- `-checkpoint` specifies the frequency of SQLite checkpoints, to manually synchronize the write-ahead log with the SQLite database file. + This defaults to 60 minutes. - `-finish` specifies the time spent polling for the verification code after a request has been made to `/register/finish` or `/deregister/finish`. A non-zero value is often necessary on network filesystems where newly written files do not immediately synchronize. This defaults to 30 seconds. diff --git a/database.go b/database.go index fd3bec0..72839cf 100644 --- a/database.go +++ b/database.go @@ -97,10 +97,6 @@ func initializeDatabase(path string) (*sql.DB, error) { // time; everyone else will have to block on the connection availability. db.SetMaxOpenConns(1) - // Make sure to eventually close all idle connections in the pool so that - // SQLite actually commits its WAL journal. - db.SetConnMaxIdleTime(1 * time.Minute) - if (!accessible) { err := func () error { atx, err := createTransaction(db) @@ -176,11 +172,6 @@ func initializeReadOnlyDatabase(path string) (*sql.DB, error) { if err != nil { return nil, fmt.Errorf("failed to open read-only SQLite handle; %w", err) } - - // Make sure to eventually close all idle connections in the pool so that - // SQLite actually commits its WAL journal. - ro_db.SetConnMaxIdleTime(1 * time.Minute) - return ro_db, nil } diff --git a/main.go b/main.go index 4aa12dd..c197af4 100644 --- a/main.go +++ b/main.go @@ -16,6 +16,7 @@ func main() { timeout0 := flag.Int("finish", 30, "Maximum time spent polling for the verification code when finishing (de)registration, in seconds") prefix0 := flag.String("prefix", "", "Prefix to add to each endpoint, after removing any leading or trailing slashes (default \"\")") lifetime0 := flag.Int("session", 10, "Maximum lifetime of a (de)registration session from start to finish, in minutes") + checkpoint0 := flag.Int("checkpoint", 60, "Frequency of checkpoints to synchronise the WAL journal with the SQLite file, in minutes") flag.Parse() dbpath := *dbpath0 @@ -66,6 +67,19 @@ func main() { http.HandleFunc(prefix + "/", newDefaultHandler()) + // Adding an hourly job that does a full checkpoint. + { + lifetime := time.Duration(*checkpoint0) * time.Minute + ticker := time.NewTicker(lifetime) + defer ticker.Stop() + go func() { + for { + <-ticker.C + db.Exec("PRAGMA wal_checkpoint(PASSIVE)") + } + }() + } + // Adding a hour job that purges various old verification sessions. { lifetime := time.Duration(*lifetime0) * time.Minute