-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathregistry.go
127 lines (103 loc) · 2.58 KB
/
registry.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
// Copyright 2018 Sergey Novichkov. All rights reserved.
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.
package redigo
import (
"errors"
"net"
"sync"
"time"
"github.com/gomodule/redigo/redis"
)
const (
// DEFAULT is default connection name.
DEFAULT = "default"
// ConfigKey is root config key.
configKey = "redis"
)
type (
// Config is registry configuration item.
Config struct {
Host string `json:"host"`
Port string `json:"port"`
DB int `json:"db"`
Password string `json:"password"`
MaxIdle int `json:"max_idle"`
MaxActive int `json:"max_active"`
IdleTimeout time.Duration `json:"idle_timeout"`
}
// Configs is registry configurations.
Configs map[string]Config
// Registry is database connection registry.
Registry struct {
mux sync.Mutex
pools map[string]*redis.Pool
conf Configs
}
)
// ErrUnknownConnection is error triggered when connection with provided name not founded.
var ErrUnknownConnection = errors.New("unknown connection")
// NewRegistry is registry constructor.
func NewRegistry(conf Configs) *Registry {
return &Registry{
pools: make(map[string]*redis.Pool, 1),
conf: conf,
}
}
// Close is method for close connections.
func (r *Registry) Close() (err error) {
r.mux.Lock()
defer r.mux.Unlock()
for key, pool := range r.pools {
if errClose := pool.Close(); errClose != nil {
err = errClose
}
delete(r.pools, key)
}
return err
}
// Connection is default connection getter.
func (r *Registry) Connection() (*redis.Pool, error) {
return r.ConnectionWithName(DEFAULT)
}
// ConnectionWithName is connection getter by name.
func (r *Registry) ConnectionWithName(name string) (_ *redis.Pool, err error) {
r.mux.Lock()
defer r.mux.Unlock()
var pool, initialized = r.pools[name]
if initialized {
return pool, nil
}
var cfg, exists = r.conf[name]
if !exists {
return nil, ErrUnknownConnection
}
var options = []redis.DialOption{
redis.DialDatabase(cfg.DB),
}
if cfg.Password != "" {
options = append(options, redis.DialPassword(cfg.Password))
}
pool = &redis.Pool{
MaxIdle: cfg.MaxIdle,
MaxActive: cfg.MaxActive,
IdleTimeout: cfg.IdleTimeout,
Dial: func() (redis.Conn, error) {
return redis.Dial(
"tcp",
net.JoinHostPort(
cfg.Host,
cfg.Port,
),
options...,
)
},
}
var conn = pool.Get()
defer conn.Close()
if _, err = conn.Do("PING"); err != nil {
return nil, err
}
r.pools[name] = pool
return pool, nil
}