From 5679a675f345b151fd6b079c799f6849800822fa Mon Sep 17 00:00:00 2001 From: Mohammed Sohail Date: Thu, 16 Mar 2023 08:01:58 +0000 Subject: [PATCH] fix: system global lock * add middleware to entire API group * setNX system lock key --- cmd/service/api.go | 10 +++------- pkg/redis/pool.go | 23 ++++++++++++++--------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/cmd/service/api.go b/cmd/service/api.go index 99d7e9d..a628507 100644 --- a/cmd/service/api.go +++ b/cmd/service/api.go @@ -1,7 +1,6 @@ package main import ( - "errors" "net/http" "time" @@ -11,7 +10,6 @@ import ( "github.com/grassrootseconomics/cic-custodial/internal/custodial" "github.com/labstack/echo/v4" "github.com/labstack/echo/v4/middleware" - "github.com/redis/go-redis/v9" ) const ( @@ -49,9 +47,7 @@ func initApiServer(custodialContainer *custodial.Custodial) *echo.Echo { }) } - apiRoute := server.Group("/api") - - apiRoute.Use(systemGlobalLock) + apiRoute := server.Group("/api", systemGlobalLock) apiRoute.POST("/account/create", api.HandleAccountCreate) apiRoute.POST("/sign/transfer", api.HandleSignTransfer) @@ -95,12 +91,12 @@ func systemGlobalLock(next echo.HandlerFunc) echo.HandlerFunc { ) locked, err := cu.RedisClient.Get(c.Request().Context(), systemGlobalLockKey).Bool() - if !errors.Is(err, redis.Nil) { + if err != nil { return err } if locked { - return c.JSON(http.StatusOK, api.ErrResp{ + return c.JSON(http.StatusServiceUnavailable, api.ErrResp{ Ok: false, Message: "System manually locked.", }) diff --git a/pkg/redis/pool.go b/pkg/redis/pool.go index 4513ae8..4965404 100644 --- a/pkg/redis/pool.go +++ b/pkg/redis/pool.go @@ -7,14 +7,20 @@ import ( "github.com/redis/go-redis/v9" ) -type RedisPoolOpts struct { - DSN string - MinIdleConns int -} +const ( + systemGlobalLockKey = "system:global_lock" +) -type RedisPool struct { - Client *redis.Client -} +type ( + RedisPoolOpts struct { + DSN string + MinIdleConns int + } + + RedisPool struct { + Client *redis.Client + } +) // NewRedisPool creates a reusable connection across the cic-custodial componenent. // Note: Each db namespace requires its own connection pool. @@ -31,8 +37,7 @@ func NewRedisPool(ctx context.Context, o RedisPoolOpts) (*RedisPool, error) { ctx, cancel := context.WithTimeout(ctx, 5*time.Second) defer cancel() - _, err = redisClient.Ping(ctx).Result() - if err != nil { + if err := redisClient.SetNX(ctx, systemGlobalLockKey, false, 0).Err(); err != nil { return nil, err }