From bceaa010ab0f77f2c7ed8bb1e5e3783f45c72fc7 Mon Sep 17 00:00:00 2001 From: Piotr Biernat Date: Fri, 7 Nov 2025 13:24:06 +0100 Subject: [PATCH] Single connection to external services --- src/app/plugins.go | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/src/app/plugins.go b/src/app/plugins.go index 2e34836..4e91898 100644 --- a/src/app/plugins.go +++ b/src/app/plugins.go @@ -3,6 +3,7 @@ package app import ( "context" "log" + "sync/atomic" "time" redis "github.com/go-redis/redis/v8" @@ -41,70 +42,84 @@ func (pm *PluginManager) GetDatabase() *pgxpool.Pool { } func CachePlugin(cnf *Config, w WorkerInterface) Plugin { + var redisConn atomic.Value + connectFn := func(w WorkerInterface) *redis.Client { log.Println("establishing api-cache connection...") - return redis.NewClient(&redis.Options{ + conn := redis.NewClient(&redis.Options{ Addr: cnf.CacheAddr, Username: cnf.CacheUsername, Password: cnf.CachePassword, DB: 0, // TODO DialTimeout: 100 * time.Millisecond, // TODO }) + redisConn.Store(conn) + + return conn } + connectFn(w) + // checking if the connection is still alive and try to reconnect when it is not - go func(conn *redis.Client) { + go func() { tick := time.NewTicker(5 * time.Second) // is 5 seconds is not too much? defer tick.Stop() for range tick.C { + conn := redisConn.Load().(*redis.Client) if err := conn.Ping(context.Background()).Err(); err != nil { log.Println("lost connection with api-cache. Reconnecting...") - conn = connectFn(w) + connectFn(w) } } - }(connectFn(w)) + }() return Plugin{ name: "cache", connect: func(w *WorkerInterface) any { - return connectFn(*w) + return redisConn.Load().(*redis.Client) }, } } func DatabasePlugin(cnf *Config, w WorkerInterface) Plugin { + var dbConn atomic.Value + connectFn := func(w WorkerInterface) *pgxpool.Pool { log.Println("establishing db-postgres connection...") conn, err := pgxpool.New(context.Background(), cnf.DbURL) if err != nil { log.Printf("failed to connect to the database: %s. Err: %s\n", cnf.DbURL, err.Error()) + return nil - // os.Exit(1) } + dbConn.Store(conn) return conn } + connectFn(w) + // checking if the connection is still alive and try to reconnect when it is not - go func(conn *pgxpool.Pool) { + go func() { tick := time.NewTicker(5 * time.Second) // is 5 seconds is not too much? defer tick.Stop() for range tick.C { + conn := dbConn.Load().(*pgxpool.Pool) if err := conn.Ping(context.Background()); err != nil { log.Println("lost connection with db-postgres. Reconnecting...") - conn = connectFn(w) + connectFn(w) } } - }(connectFn(w)) + }() return Plugin{ name: "database", connect: func(w *WorkerInterface) any { - return connectFn(*w) + return dbConn.Load().(*pgxpool.Pool) }, } }