Skip to content

Commit

Permalink
test redis connection before start serving traffic
Browse files Browse the repository at this point in the history
  • Loading branch information
dencoded committed Feb 2, 2018
1 parent 0915506 commit a17f4f1
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 0 deletions.
6 changes: 6 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -1091,6 +1091,12 @@ func main() {

start()

// Wait while Redis connection pools are ready before start serving traffic
if !storage.IsConnected() {
log.Fatal("Redis connection pools are not ready. Exiting...")
}
log.Info("Redis connection pools are ready")

if goAgainErr != nil {
var err error
if l, err = generateListener(config.Global.ListenPort); err != nil {
Expand Down
54 changes: 54 additions & 0 deletions storage/redis_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ import (

// ------------------- REDIS CLUSTER STORAGE MANAGER -------------------------------

const (
waitStorageRetriesNum = 10
waitStorageRetriesInterval = 5 * time.Second
)

var (
redisSingletonMu sync.RWMutex
redisClusterSingleton *rediscluster.RedisCluster
Expand All @@ -28,6 +33,55 @@ type RedisCluster struct {
IsCache bool
}

func clusterConnectionIsOpen(cluster *rediscluster.RedisCluster) bool {
// check if at least one of cluster handles has an alive connection
for item := range cluster.Handles.Iter() {
conn := item.Val.(*rediscluster.RedisHandle).GetRedisConn()
isOpen := conn.Err() == nil
conn.Close()
if isOpen {
return true
}
}
return false
}

// IsConnected waits with retries until Redis connection pools are connected
func IsConnected() bool {
// create temporary ones to access singletons
cluster := RedisCluster{}
cacheCluster := RedisCluster{IsCache: true}
cluster.Connect()
cacheCluster.Connect()

// wait for connection pools with retries
retryNum := 0
for {
if retryNum == waitStorageRetriesNum {
log.Error("Waiting for Redis connection pools failed")
return false
}

// check that both have active Redis connections
clusterSingle := cluster.singleton()
cacheClusterSingle := cacheCluster.singleton()
if clusterSingle != nil &&
cacheClusterSingle != nil &&
clusterConnectionIsOpen(clusterSingle) &&
clusterConnectionIsOpen(cacheClusterSingle) {
break
}

// sleep before next check
log.WithField("currRetry", retryNum).Info("Waiting for Redis connection pools to be ready")
time.Sleep(waitStorageRetriesInterval)
retryNum++
}
log.WithField("currRetry", retryNum).Info("Redis connection pools are ready after number of retires")

return true
}

func NewRedisClusterPool(isCache bool) *rediscluster.RedisCluster {
// redisSingletonMu is locked and we know the singleton is nil
cfg := config.Global.Storage
Expand Down

0 comments on commit a17f4f1

Please sign in to comment.