коммит произвёл
GitHub
родитель
0319daf9bb
Коммит
0f98620b65
@@ -58,6 +58,7 @@ type WebConn struct {
|
|||||||
isWindows bool
|
isWindows bool
|
||||||
endWritePump chan struct{}
|
endWritePump chan struct{}
|
||||||
pumpFinished chan struct{}
|
pumpFinished chan struct{}
|
||||||
|
closeOnce sync.Once
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewWebConn returns a new WebConn instance.
|
// NewWebConn returns a new WebConn instance.
|
||||||
@@ -94,15 +95,20 @@ func (a *App) NewWebConn(ws net.Conn, session model.Session, t i18n.TranslateFun
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Close closes the WebConn.
|
// Close closes the WebConn.
|
||||||
|
// It is made idempotent in nature by using a sync.Once
|
||||||
|
// to avoid a race condition that happens when an EventReadHup event
|
||||||
|
// and a connection close event happens at the same time.
|
||||||
func (wc *WebConn) Close() {
|
func (wc *WebConn) Close() {
|
||||||
wc.WebSocket.Close()
|
wc.closeOnce.Do(func() {
|
||||||
if !wc.isWindows {
|
wc.WebSocket.Close()
|
||||||
// This triggers the pump exit.
|
if !wc.isWindows {
|
||||||
// If the pump has already exited, this just becomes a noop.
|
// This triggers the pump exit.
|
||||||
close(wc.endWritePump)
|
// If the pump has already exited, this just becomes a noop.
|
||||||
}
|
close(wc.endWritePump)
|
||||||
// We wait for the pump to fully exit.
|
}
|
||||||
<-wc.pumpFinished
|
// We wait for the pump to fully exit.
|
||||||
|
<-wc.pumpFinished
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSessionExpiresAt returns the time at which the session expires.
|
// GetSessionExpiresAt returns the time at which the session expires.
|
||||||
|
|||||||
@@ -90,6 +90,20 @@ func TestHubStopWithMultipleConnections(t *testing.T) {
|
|||||||
defer wc3.Close()
|
defer wc3.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestWebConnDoubleClose(t *testing.T) {
|
||||||
|
th := Setup(t)
|
||||||
|
defer th.TearDown()
|
||||||
|
|
||||||
|
s := httptest.NewServer(dummyWebsocketHandler(t))
|
||||||
|
defer s.Close()
|
||||||
|
|
||||||
|
wc1 := registerDummyWebConn(t, th.App, s.Listener.Addr(), "userID")
|
||||||
|
wc1.Close()
|
||||||
|
require.NotPanics(t, func() {
|
||||||
|
wc1.Close()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// TestHubStopRaceCondition verifies that attempts to use the hub after it has shutdown does not
|
// TestHubStopRaceCondition verifies that attempts to use the hub after it has shutdown does not
|
||||||
// block the caller indefinitely.
|
// block the caller indefinitely.
|
||||||
func TestHubStopRaceCondition(t *testing.T) {
|
func TestHubStopRaceCondition(t *testing.T) {
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user