agent/grpc: use a separate channel for closing the Accept
Closing l.conns can lead to a race and a 'panic: send on closed chan' when a connection is in the middle of being handled when the server is shutting down. Found using '-race -count=800'
This commit is contained in:
parent
e640d47319
commit
7e338693a8
|
@ -22,7 +22,7 @@ func NewHandler(addr net.Addr, register func(server *grpc.Server)) *Handler {
|
||||||
)
|
)
|
||||||
register(srv)
|
register(srv)
|
||||||
|
|
||||||
lis := &chanListener{addr: addr, conns: make(chan net.Conn)}
|
lis := &chanListener{addr: addr, conns: make(chan net.Conn), done: make(chan struct{})}
|
||||||
return &Handler{srv: srv, listener: lis}
|
return &Handler{srv: srv, listener: lis}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,22 +51,22 @@ func (h *Handler) Shutdown() error {
|
||||||
type chanListener struct {
|
type chanListener struct {
|
||||||
conns chan net.Conn
|
conns chan net.Conn
|
||||||
addr net.Addr
|
addr net.Addr
|
||||||
|
done chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Accept blocks until a connection is received from Handle, and then returns the
|
// Accept blocks until a connection is received from Handle, and then returns the
|
||||||
// connection. Accept implements part of the net.Listener interface for grpc.Server.
|
// connection. Accept implements part of the net.Listener interface for grpc.Server.
|
||||||
func (l *chanListener) Accept() (net.Conn, error) {
|
func (l *chanListener) Accept() (net.Conn, error) {
|
||||||
select {
|
select {
|
||||||
case c, ok := <-l.conns:
|
case c := <-l.conns:
|
||||||
if !ok {
|
|
||||||
return nil, &net.OpError{
|
|
||||||
Op: "accept",
|
|
||||||
Net: l.addr.Network(),
|
|
||||||
Addr: l.addr,
|
|
||||||
Err: fmt.Errorf("listener closed"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return c, nil
|
return c, nil
|
||||||
|
case <-l.done:
|
||||||
|
return nil, &net.OpError{
|
||||||
|
Op: "accept",
|
||||||
|
Net: l.addr.Network(),
|
||||||
|
Addr: l.addr,
|
||||||
|
Err: fmt.Errorf("listener closed"),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ func (l *chanListener) Addr() net.Addr {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *chanListener) Close() error {
|
func (l *chanListener) Close() error {
|
||||||
close(l.conns)
|
close(l.done)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue