Skip to content
Snippets Groups Projects
  • ale's avatar
    098c74b3
    Initial refactoring for v2 · 098c74b3
    ale authored
    Includes a merge of radiod and redirectord, updates to more modern Go
    idioms, adoption of the higher level etcd concurrency primitives, and
    a lot of other minor implementation changes.
    
    The refactor is still incomplete: the daemons won't compile and the
    code to start the RPC servers is missing.
    098c74b3
    History
    Initial refactoring for v2
    ale authored
    Includes a merge of radiod and redirectord, updates to more modern Go
    idioms, adoption of the higher level etcd concurrency primitives, and
    a lot of other minor implementation changes.
    
    The refactor is still incomplete: the daemons won't compile and the
    code to start the RPC servers is missing.
grpc_conn_cache.go 1.17 KiB
package util

import (
	"context"
	"sync"

	"google.golang.org/grpc"
)

// ConnCache caches GRPC connections for a set of (identical)
// backends, all sharing a common set of options.
type ConnCache struct {
	mx    sync.Mutex
	conns map[string]*grpc.ClientConn
	opts  []grpc.DialOption
}

// NewConnCache returns a new GRPC connection cache with the specified options.
func NewConnCache(opts ...grpc.DialOption) *ConnCache {
	return &ConnCache{
		conns: make(map[string]*grpc.ClientConn),
		opts:  opts,
	}
}

// Get returns a (potentially cached) GRPC connection.
func (c *ConnCache) Get(ctx context.Context, addr string) (*grpc.ClientConn, error) {
	c.mx.Lock()
	defer c.mx.Unlock()

	conn, ok := c.conns[addr]
	if ok {
		return conn, nil
	}

	conn, err := grpc.DialContext(ctx, addr, c.opts...)
	if err != nil {
		return nil, err
	}
	c.conns[addr] = conn
	return conn, nil
}

// Drop notifies the cache of an error with the connection, which will
// be (potentially) closed and dropped from the cache.
func (c *ConnCache) Drop(addr string, conn *grpc.ClientConn) {
	c.mx.Lock()
	if curConn, ok := c.conns[addr]; ok && curConn == conn {
		delete(c.conns, addr)
		conn.Close()
	}
	c.mx.Unlock()
}