forked from Coccodrillo/apns
/
connection_pool.go
83 lines (69 loc) · 1.79 KB
/
connection_pool.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
package apns
import "sync"
import "github.com/uber-go/zap"
type ConnectionPool struct {
sync.Mutex
client *Client
NumConnections int
connections chan *Connection
pushQueue chan *PushNotification
responseQueue chan BadPushNotification
stopped sync.WaitGroup
}
func NewConnectionPool(client *Client, numConnections int, logger zap.Logger) (*ConnectionPool, error) {
connections := make(chan *Connection, numConnections)
responseQueue := make(chan BadPushNotification, 10000)
for i := numConnections; i >= 1; i-- {
newConnection := NewConnection(client, i, responseQueue)
err := newConnection.Start(logger)
if err != nil {
return nil, err
}
connections <- newConnection
}
connPool := &ConnectionPool {
client: client,
NumConnections: numConnections,
connections: connections,
pushQueue: make(chan *PushNotification, numConnections * 3),
responseQueue: responseQueue,
}
connPool.Start(logger)
return connPool, nil
}
func (conn_pool *ConnectionPool) Start(logger zap.Logger) {
logger.Info("APNS: Starting pool of connections")
go conn_pool.sendLoop()
}
func (conn_pool *ConnectionPool) Errors() <-chan BadPushNotification {
return conn_pool.responseQueue
}
func (conn_pool *ConnectionPool) Enqueue(pn *PushNotification) {
conn_pool.pushQueue <- pn
}
func (conn_pool *ConnectionPool) sendLoop() {
conn_pool.stopped.Add(1)
defer conn_pool.stopped.Done()
for {
pn, ok := <- conn_pool.pushQueue
if !ok {
return
}
conn := <- conn_pool.connections
conn.Enqueue(pn)
// release connection
conn_pool.connections <- conn
}
}
func (conn_pool *ConnectionPool) Stop(logger zap.Logger) {
close(conn_pool.pushQueue)
conn_pool.stopped.Wait()
close(conn_pool.connections)
for {
conn, ok := <- conn_pool.connections
if !ok {
break
}
<- conn.Stop(logger)
}
}