mirror of
https://github.com/go-kit/kit.git
synced 2025-07-17 01:12:38 +02:00
util: documentation updates
This commit is contained in:
5
util/README.md
Normal file
5
util/README.md
Normal file
@ -0,0 +1,5 @@
|
||||
# util
|
||||
|
||||
This directory holds packages of general utility to multiple consumers within Go kit,
|
||||
and potentially other consumers in the wider Go ecosystem.
|
||||
There is no `package util` and will never be.
|
2
util/conn/doc.go
Normal file
2
util/conn/doc.go
Normal file
@ -0,0 +1,2 @@
|
||||
// Package conn provides utilities related to connections.
|
||||
package conn
|
@ -7,18 +7,22 @@ import (
|
||||
"github.com/go-kit/kit/log"
|
||||
)
|
||||
|
||||
// Dialer dials a network and address. net.Dial is a good default Dialer.
|
||||
// Dialer imitates net.Dial. Dialer is assumed to yield connections that are
|
||||
// safe for use by multiple concurrent goroutines.
|
||||
type Dialer func(network, address string) (net.Conn, error)
|
||||
|
||||
// AfterFunc imitates time.After.
|
||||
type AfterFunc func(time.Duration) <-chan time.Time
|
||||
|
||||
// Manager manages a net.Conn. Clients should take the conn when they want to
|
||||
// use it, and put back whatever error they receive from an e.g. Write. When a
|
||||
// non-nil error is put, the conn is invalidated and a new conn is established.
|
||||
// Manager manages a net.Conn.
|
||||
//
|
||||
// Clients provide a way to create the connection with a Dialer, network, and
|
||||
// address. Clients should Take the connection when they want to use it, and Put
|
||||
// back whatever error they receive from its use. When a non-nil error is Put,
|
||||
// the connection is invalidated, and a new connection is established.
|
||||
// Connection failures are retried after an exponential backoff.
|
||||
type Manager struct {
|
||||
dial Dialer
|
||||
dialer Dialer
|
||||
network string
|
||||
address string
|
||||
after AfterFunc
|
||||
@ -28,9 +32,14 @@ type Manager struct {
|
||||
putc chan error
|
||||
}
|
||||
|
||||
// NewManager returns a connection manager using the passed Dialer, network, and
|
||||
// address. The AfterFunc is used to control exponential backoff and retries.
|
||||
// For normal use, pass net.Dial and time.After as the Dialer and AfterFunc
|
||||
// respectively. The logger is used to log errors; pass a log.NopLogger if you
|
||||
// don't care to receive them.
|
||||
func NewManager(d Dialer, network, address string, after AfterFunc, logger log.Logger) *Manager {
|
||||
m := &Manager{
|
||||
dial: d,
|
||||
dialer: d,
|
||||
network: network,
|
||||
address: address,
|
||||
after: after,
|
||||
@ -43,17 +52,21 @@ func NewManager(d Dialer, network, address string, after AfterFunc, logger log.L
|
||||
return m
|
||||
}
|
||||
|
||||
// Take yields the current connection. It may be nil.
|
||||
func (m *Manager) Take() net.Conn {
|
||||
return <-m.takec
|
||||
}
|
||||
|
||||
// Put accepts an error that came from a previously yielded connection. If the
|
||||
// error is non-nil, the manager will invalidate the current connection and try
|
||||
// to reconnect, with exponential backoff. Putting a nil error is a no-op.
|
||||
func (m *Manager) Put(err error) {
|
||||
m.putc <- err
|
||||
}
|
||||
|
||||
func (m *Manager) loop() {
|
||||
var (
|
||||
conn = dial(m.dial, m.network, m.address, m.logger) // may block slightly
|
||||
conn = dial(m.dialer, m.network, m.address, m.logger) // may block slightly
|
||||
connc = make(chan net.Conn)
|
||||
reconnectc <-chan time.Time // initially nil
|
||||
backoff = time.Second
|
||||
@ -62,20 +75,21 @@ func (m *Manager) loop() {
|
||||
for {
|
||||
select {
|
||||
case <-reconnectc:
|
||||
reconnectc = nil
|
||||
go func() { connc <- dial(m.dial, m.network, m.address, m.logger) }()
|
||||
reconnectc = nil // one-shot
|
||||
go func() { connc <- dial(m.dialer, m.network, m.address, m.logger) }()
|
||||
|
||||
case conn = <-connc:
|
||||
if conn == nil {
|
||||
backoff = exponential(backoff)
|
||||
reconnectc = m.after(backoff)
|
||||
// didn't work
|
||||
backoff = exponential(backoff) // wait longer
|
||||
reconnectc = m.after(backoff) // try again
|
||||
} else {
|
||||
backoff = time.Second
|
||||
reconnectc = nil
|
||||
// worked!
|
||||
backoff = time.Second // reset wait time
|
||||
reconnectc = nil // no retry necessary
|
||||
}
|
||||
|
||||
case m.takec <- conn:
|
||||
// might be nil
|
||||
|
||||
case err := <-m.putc:
|
||||
if err != nil && conn != nil {
|
||||
@ -91,7 +105,7 @@ func dial(d Dialer, network, address string, logger log.Logger) net.Conn {
|
||||
conn, err := d(network, address)
|
||||
if err != nil {
|
||||
logger.Log("err", err)
|
||||
conn = nil
|
||||
conn = nil // just to be sure
|
||||
}
|
||||
return conn
|
||||
}
|
||||
|
Reference in New Issue
Block a user