-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtypes.go
More file actions
142 lines (113 loc) · 4.23 KB
/
types.go
File metadata and controls
142 lines (113 loc) · 4.23 KB
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
package connpool
import (
"context"
"fmt"
"math/rand/v2"
"net"
"time"
)
var (
ErrClosed = fmt.Errorf("pool is closed")
ErrExhausted = fmt.Errorf("pool is exhausted")
)
// Factory creates a new net.Conn. It is called when the pool needs to grow.
type Factory func() (net.Conn, error)
// PingFunc checks whether a connection is still alive.
// Return nil if the connection is healthy, or an error to discard it.
type PingFunc func(net.Conn) error
// Pool is a thread-safe connection pool for net.Conn.
type Pool interface {
// Name returns the pool name.
Name() string
// Get returns a healthy connection from the pool.
// It blocks until a connection is available, the context is cancelled,
// or the pool is closed.
Get(ctx context.Context) (net.Conn, error)
// Stop shuts down the pool and closes all connections.
Stop() error
// Stats returns a snapshot of pool statistics.
Stats() Stats
// MarkUnusable marks a connection so it will be destroyed instead of
// returned to the pool on Close().
MarkUnusable(conn net.Conn)
}
// Config controls pool behavior.
type Config struct {
// MinSize is the number of connections created on startup and maintained
// by the background evictor. Must be >= 0.
MinSize int
// MaxSize is the maximum number of connections (idle + active). Must be > 0.
MaxSize int
// Increment is how many connections to create at once when the pool needs
// to grow. Must be >= 1 and <= MaxSize - MinSize.
Increment int
// IdleTimeout is how long a connection can sit idle before being evicted.
// Zero means no idle timeout.
IdleTimeout time.Duration
// MaxLifetime is the maximum duration a connection can live since creation.
// Connections older than this are closed on Get() and by the evictor.
// A jitter of up to 10% is applied to prevent thundering herd.
// Zero means no max lifetime.
MaxLifetime time.Duration
// Ping is an optional health check function called on Get() before
// returning a connection. If it returns an error, the connection is
// discarded and a new one is tried.
Ping PingFunc
// EvictInterval is how often the background evictor runs.
// Zero defaults to 30 seconds. Set to -1 to disable the evictor.
EvictInterval time.Duration
}
func (c *Config) validate() error {
if c.MinSize < 0 || c.MaxSize <= 0 || c.MinSize > c.MaxSize {
return fmt.Errorf("invalid configuration: MinSize=%d MaxSize=%d (need 0 <= MinSize <= MaxSize, MaxSize > 0)", c.MinSize, c.MaxSize)
}
if c.Increment < 1 {
return fmt.Errorf("invalid configuration: Increment must be >= 1, got %d", c.Increment)
}
if c.MinSize > 0 && c.MinSize < c.MaxSize && c.Increment > (c.MaxSize-c.MinSize) {
return fmt.Errorf("invalid configuration: Increment=%d exceeds MaxSize-MinSize=%d", c.Increment, c.MaxSize-c.MinSize)
}
return nil
}
func (c *Config) evictInterval() time.Duration {
if c.EvictInterval > 0 {
return c.EvictInterval
}
if c.EvictInterval < 0 {
return 0 // disabled
}
return 30 * time.Second
}
// maxLifetimeWithJitter returns the max lifetime with up to 10% random jitter.
// This prevents thundering herd — all connections created at the same time
// won't expire at the same moment.
func (c *Config) maxLifetimeWithJitter() time.Duration {
if c.MaxLifetime <= 0 {
return 0
}
jitter := time.Duration(rand.Int64N(int64(c.MaxLifetime) / 10))
return c.MaxLifetime + jitter
}
// Stats is a snapshot of pool statistics.
type Stats interface {
// Available is the number of idle connections in the pool.
Available() int
// Active is the number of connections currently checked out.
Active() int
// Size is the total number of connections (idle + active).
Size() int
// Request is the total number of Get() calls.
Request() int
// Success is the total number of successful Get() calls.
Success() int
// IdleClosed is the total number of connections closed due to idle timeout.
IdleClosed() int
// LifetimeClosed is the total number of connections closed due to max lifetime.
LifetimeClosed() int
// PingFailed is the total number of connections discarded due to ping failure.
PingFailed() int
// WaitCount is the total number of Get() calls that had to wait for a connection.
WaitCount() int
// WaitTime is the cumulative time spent waiting for connections.
WaitTime() time.Duration
}