Close the message cache before the other stores on shutdown

On Postgres all stores share one pool, and closeDatabases closed the user
manager first, which closed the pool under the message cache's final batch
write ("Cannot write message batch: sql: database is closed").
This commit is contained in:
binwiederhier committed 2026-10-03 15:06:45 +00:00
1 parent bc1e879dc4
commit e63ec41b2e
2 files changed
+26 -3

No files matched your search

+5 -3
View File
@@ -481,12 +481,14 @@ func (s *Server) stop() {
}
func (s *Server) closeDatabases() {
if s.userManager != nil {
s.userManager.Close()
}
// Message cache first: it may still be writing its last batch, and on Postgres all stores
// share one pool, so closing any other store first would close the pool under that write
if s.messageCache != nil {
s.messageCache.Close()
}
if s.userManager != nil {
s.userManager.Close()
}
if s.webPush != nil {
s.webPush.Close()
}
+21
View File
@@ -26,6 +26,7 @@ import (
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/stretchr/testify/require"
"golang.org/x/crypto/bcrypt"
"heckel.io/ntfy/v2/db/pg"
dbtest "heckel.io/ntfy/v2/db/test"
"heckel.io/ntfy/v2/log"
"heckel.io/ntfy/v2/message"
@@ -5476,3 +5477,23 @@ func TestServer_StopFlushesBatchedMessages(t *testing.T) {
require.Nil(t, err)
require.Equal(t, 2, len(messages))
}
func TestServer_StopFlushesBatchedMessages_Postgres(t *testing.T) {
// Same as TestServer_StopFlushesBatchedMessages on Postgres, where all stores share one
// pool: closing another store first used to close the pool under the pending batch write
schemaDSN := dbtest.CreateTestPostgresSchema(t)
conf := newTestConfig(t, schemaDSN)
conf.CacheBatchSize = 100
conf.CacheBatchTimeout = time.Hour
s := newTestServer(t, conf)
require.Equal(t, 200, request(t, s, "PUT", "/mytopic", "batched 1", nil).Code)
require.Equal(t, 200, request(t, s, "PUT", "/mytopic", "batched 2", nil).Code)
s.Stop()
host, err := pg.Open(schemaDSN)
require.Nil(t, err)
defer host.DB.Close()
var count int
require.Nil(t, host.DB.QueryRow(`SELECT COUNT(*) FROM message WHERE topic = 'mytopic'`).Scan(&count))
require.Equal(t, 2, count)
}