-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Open
Labels
bugSomething isn't workingSomething isn't workinggoPull requests that update Go codePull requests that update Go code
Description
Describe the Bug
The SQL and Redis datasource implementations spawn background goroutines for:
- Connection retries (
retryConnection,retryConnect) - Metrics collection (
pushDBMetrics)
These goroutines run in infinite loops without monitoring a cancellation context or stop signal.
When the application shuts down (via app.Shutdown() or container.Close()), these goroutines continue to run indefinitely, resulting in:
- Goroutine leaks — resources are never freed.
- Log noise — the application continues logging connection errors even after shutdown.
To Reproduce
Steps to Reproduce
- Initialize a GoFr application with a SQL or Redis datasource configured to use an unreachable host (so the retry loop activates).
- Start the application.
- Trigger a shutdown (e.g., via
SIGINT). - Observe that the background retry logic continues to execute and log errors even after shutdown.
Minimal Example
package main
import (
"time"
"gofr.dev/pkg/gofr"
)
func main() {
app := gofr.New()
// Configure a non-existent DB to force retry loop
app.Config.Set("DB_HOST", "unreachable-host")
app.Config.Set("DB_DIALECT", "mysql")
go func() {
time.Sleep(5 * time.Second)
// Simulate shutdown
// Even after this, the retryConnection goroutine keeps running
app.Shutdown()
}()
app.Run()
} Expected behavior
When container.SQL.Close() or container.Redis.Close() is called (typically during app.Shutdown()),
all associated background goroutines (retry logic, metrics pushers, etc.) should:
Terminate immediately and gracefully.
Stop retrying connections or pushing metrics.
Release resources cleanly.
.
Environments (please complete the following information):
- OS: [macOS]
- gofr version [Latest source from development branch]
- go version [1.25 (as per go.mod)]
More description
- Add a
stopSignalchannel (andsync.Oncefor safety) to the DB and Redis structs. - Initialize this channel in
NewSQLandNewClient. - Close this channel in the
Close()method. - Update
retryConnectionandpushDBMetricsloops to listen for<-stopSignaland exit when triggered.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't workinggoPull requests that update Go codePull requests that update Go code