steve/pkg/aggregation/listener.go

71 lines
1.1 KiB
Go

package aggregation
import (
"context"
"io"
"net"
"sync"
)
type addr string
func (a addr) String() string {
return string(a)
}
func (a addr) Network() string {
return "tcp"
}
type Listener struct {
sync.RWMutex
address addr
connections chan net.Conn
closed bool
}
func NewListener(address string) *Listener {
return &Listener{
address: addr(address),
connections: make(chan net.Conn, 5),
}
}
func (l *Listener) Accept() (net.Conn, error) {
conn, ok := <-l.connections
if !ok {
return nil, io.ErrClosedPipe
}
return conn, nil
}
func (l *Listener) Close() error {
l.Lock()
defer l.Unlock()
if !l.closed {
close(l.connections)
l.closed = true
}
return nil
}
func (l *Listener) Dial(ctx context.Context, network, address string) (net.Conn, error) {
left, right := net.Pipe()
l.RLock()
defer l.RUnlock()
if l.closed {
return nil, io.ErrClosedPipe
}
select {
case l.connections <- right:
return left, nil
case <-ctx.Done():
return nil, io.ErrClosedPipe
}
}
func (l *Listener) Addr() net.Addr {
return l.address
}