From 92024b0d10811f97de5b39a520f42039554c6da0 Mon Sep 17 00:00:00 2001 From: Paul Lorenz Date: Wed, 27 Jan 2021 16:05:54 -0500 Subject: [PATCH] Fix close stall by moving notify after seq close --- router/xgress_edge/fabric.go | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/router/xgress_edge/fabric.go b/router/xgress_edge/fabric.go index b9d1082f6..cce1f5021 100644 --- a/router/xgress_edge/fabric.go +++ b/router/xgress_edge/fabric.go @@ -187,15 +187,7 @@ func (conn *edgeXgressConn) close(notify bool, reason string) { } log := pfxlog.ContextLogger(conn.Channel.Label()).WithField("connId", conn.Id()) - log.Debugf("closing message sink, reason: %v", reason) - if notify && !conn.IsClosed() { - // Notify edge client of close - log.Debug("sending closed to SDK client") - closeMsg := edge.NewStateClosedMsg(conn.Id(), reason) - if err := conn.SendState(closeMsg); err != nil { - log.WithError(err).Warn("unable to send close msg to edge client") - } - } + log.Debugf("closing edge xgress conn, reason: %v", reason) conn.mux.RemoveMsgSink(conn) @@ -204,6 +196,17 @@ func (conn *edgeXgressConn) close(notify bool, reason string) { // to terminate log.Debug("closing channel sequencer, which should cause xgress to close") conn.seq.Close() + + // we must close the sequencer first, otherwise we can deadlock. The channel rxer can be blocked submitting + // the sequencer and then notify send will then be stuck writing to a partially closed channel. + if notify && !conn.IsClosed() { + // Notify edge client of close + log.Debug("sending closed to SDK client") + closeMsg := edge.NewStateClosedMsg(conn.Id(), reason) + if err := conn.SendState(closeMsg); err != nil { + log.WithError(err).Warn("unable to send close msg to edge client") + } + } } func (conn *edgeXgressConn) Accept(msg *channel2.Message) {