Skip to content

Commit 1fbbed8

Browse files
authored
Merge pull request #98 from filecoin-project/fix/rev-client-close
Fix reverse client hang on closed connections
2 parents 6fff219 + 6be5fef commit 1fbbed8

File tree

2 files changed

+60
-2
lines changed

2 files changed

+60
-2
lines changed

options_server.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,7 @@ func WithReverseClient[RP any](namespace string) ServerOption {
6969
}
7070

7171
// todo test that everything is closing correctly
72-
stop := make(chan struct{}) // todo better stop?
73-
cl.exiting = stop
72+
cl.exiting = conn.exiting
7473

7574
requests := cl.setupRequestChan()
7675
conn.requests = requests

rpc_test.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1452,6 +1452,65 @@ func TestReverseCallAliased(t *testing.T) {
14521452
closer()
14531453
}
14541454

1455+
// RevCallDropTestServerHandler attempts to make a client call on a closed connection.
1456+
type RevCallDropTestServerHandler struct {
1457+
closeConn func()
1458+
res chan error
1459+
}
1460+
1461+
func (h *RevCallDropTestServerHandler) Call(ctx context.Context) error {
1462+
revClient, ok := ExtractReverseClient[RevCallTestClientProxy](ctx)
1463+
if !ok {
1464+
return fmt.Errorf("no reverse client")
1465+
}
1466+
1467+
h.closeConn()
1468+
time.Sleep(time.Second)
1469+
1470+
_, err := revClient.CallOnClient(7)
1471+
h.res <- err
1472+
1473+
return nil
1474+
}
1475+
1476+
func TestReverseCallDroppedConn(t *testing.T) {
1477+
// setup server
1478+
1479+
hnd := &RevCallDropTestServerHandler{
1480+
res: make(chan error),
1481+
}
1482+
1483+
rpcServer := NewServer(WithReverseClient[RevCallTestClientProxy]("Client"))
1484+
rpcServer.Register("Server", hnd)
1485+
1486+
// httptest stuff
1487+
testServ := httptest.NewServer(rpcServer)
1488+
defer testServ.Close()
1489+
1490+
// setup client
1491+
1492+
var client struct {
1493+
Call func() error
1494+
}
1495+
closer, err := NewMergeClient(context.Background(), "ws://"+testServ.Listener.Addr().String(), "Server", []interface{}{
1496+
&client,
1497+
}, nil, WithClientHandler("Client", &RevCallTestClientHandler{}))
1498+
require.NoError(t, err)
1499+
1500+
hnd.closeConn = closer
1501+
1502+
// do the call!
1503+
e := client.Call()
1504+
1505+
require.Error(t, e)
1506+
require.Contains(t, e.Error(), "websocket connection closed")
1507+
1508+
res := <-hnd.res
1509+
require.Error(t, res)
1510+
require.Contains(t, res.Error(), "RPC client error: sendRequest failed: websocket routine exiting")
1511+
time.Sleep(100 * time.Millisecond)
1512+
}
1513+
14551514
type BigCallTestServerHandler struct {
14561515
}
14571516

0 commit comments

Comments
 (0)