rsocket / rsocket-go

rsocket-go implementation
Apache License 2.0
511 stars 46 forks source link

Server.Serve() Got panic when shutting down client channel #43

Closed larryrun closed 5 years ago

larryrun commented 5 years ago

Hi team, I'm trying the client.RequestChannel feature and got panic in server side when shutting down the client side.(kill the client's process) The testing code is very simple: server:

err := rsocket.Receive().
    Resume().
    Acceptor(func(setup payload.SetupPayload, sendingSocket rsocket.CloseableRSocket) (rsocket.RSocket, error) {
        return rsocket.NewAbstractSocket(
            rsocket.RequestResponse(func(msg payload.Payload) mono.Mono {
                log.Printf("msg received: %+v", msg)
                return mono.Just(payload.NewString("OK", ""))
            }),
            rsocket.RequestChannel(func(msgs rx.Publisher) flux.Flux {
                return msgs.(flux.Flux).DoOnNext(func(msg payload.Payload) {
                    log.Printf("msg received: %+v", msg)
                })
            }),
        ), nil
    }).
    Transport("tcp://0.0.0.0:7878").
    Serve(context.Background())

the panic:

2019/11/18 20:37:35 [WARN] send frame failed: send on closed channel
panic: close of closed channel

goroutine 23 [running]:
github.com/rsocket/rsocket-go/internal/framing.(*BaseFrame).Done(0xc0003f8d80)
        /Users/my-path/go_home/pkg/mod/github.com/rsocket/rsocket-go@v0.5.0/internal/framing/frame.go:160 +0x2f
github.com/rsocket/rsocket-go/internal/transport.(*Transport).Send(0xc000186000, 0x13f8760, 0xc0003b1378, 0x0, 0x13eed80, 0xc000122500)
        /Users/my-path/go_home/pkg/mod/github.com/rsocket/rsocket-go@v0.5.0/internal/transport/transport.go:82 +0x1a3
github.com/rsocket/rsocket-go/internal/socket.(*DuplexRSocket).drainOutBack(0xc000190000)
        /Users/my-path/go_home/pkg/mod/github.com/rsocket/rsocket-go@v0.5.0/internal/socket/duplex.go:984 +0xe5
github.com/rsocket/rsocket-go/internal/socket.(*DuplexRSocket).loopWrite(0xc000190000, 0x13f51c0, 0xc0000e0300, 0x0, 0x0)
        /Users/my-path/go_home/pkg/mod/github.com/rsocket/rsocket-go@v0.5.0/internal/socket/duplex.go:1065 +0x109
github.com/rsocket/rsocket-go/internal/socket.(*resumeServerSocket).Start(0xc000122080, 0x13f51c0, 0xc0000e0300, 0x0, 0x0)
        /Users/my-path/go_home/pkg/mod/github.com/rsocket/rsocket-go@v0.5.0/internal/socket/server_resume.go:36 +0x89
github.com/rsocket/rsocket-go.(*server).serve.func3.2(0x13f51c0, 0xc0000e0300, 0x13f8b60, 0xc000122080)
        /Users/my-path/go_home/pkg/mod/github.com/rsocket/rsocket-go@v0.5.0/server.go:220 +0x49
created by github.com/rsocket/rsocket-go.(*server).serve.func3
        /Users/my-path/go_home/pkg/mod/github.com/rsocket/rsocket-go@v0.5.0/server.go:219 +0x316

although the client was shutdown without closing the channel, I suppose the server should still be running instead of exit directly

jjeffcaii commented 5 years ago

Thanks for bug report 👍 I'm working on it. It'll be fixed in next patch.

larryrun commented 5 years ago

Wow, thanks for the quick fix!

larryrun commented 5 years ago

@jjeffcaii I just ran my test again, but I still got the similar panic:

2019/11/19 09:53:38 [WARN] send frame failed: send on closed channel
panic: close of closed channel

goroutine 24 [running]:
github.com/rsocket/rsocket-go/internal/framing.(*BaseFrame).Done(0xc000363be0)
        /Users/my-path/go_home/pkg/mod/github.com/rsocket/rsocket-go@v0.5.1/internal/framing/frame.go:160 +0x36
github.com/rsocket/rsocket-go/internal/transport.(*Transport).Send(0xc000180000, 0x1515320, 0xc0002eb760, 0xc000180000, 0x150c560, 0xc0003eb420)
        /Users/my-path/go_home/pkg/mod/github.com/rsocket/rsocket-go@v0.5.1/internal/transport/transport.go:82 +0x11d
github.com/rsocket/rsocket-go/internal/socket.(*DuplexRSocket).drainOutBack(0xc00018a000)
        /Users/my-path/go_home/pkg/mod/github.com/rsocket/rsocket-go@v0.5.1/internal/socket/duplex.go:988 +0x188
github.com/rsocket/rsocket-go/internal/socket.(*DuplexRSocket).loopWrite(0xc00018a000, 0x15123c0, 0xc000092340, 0x0, 0x0)
        /Users/my-path/go_home/pkg/mod/github.com/rsocket/rsocket-go@v0.5.1/internal/socket/duplex.go:1069 +0x3f2
github.com/rsocket/rsocket-go/internal/socket.(*resumeServerSocket).Start(0xc0000f6080, 0x15123c0, 0xc000092340, 0x0, 0x0)
        /Users/my-path/go_home/pkg/mod/github.com/rsocket/rsocket-go@v0.5.1/internal/socket/server_resume.go:36 +0x9b
github.com/rsocket/rsocket-go.(*server).serve.func3.2(0x15123c0, 0xc000092340, 0x1515720, 0xc0000f6080)
        /Users/my-path/go_home/pkg/mod/github.com/rsocket/rsocket-go@v0.5.1/server.go:220 +0x57
created by github.com/rsocket/rsocket-go.(*server).serve.func3
        /Users/my-path/go_home/pkg/mod/github.com/rsocket/rsocket-go@v0.5.1/server.go:219 +0x67e
Exiting.

Is there any change required in my code?

jjeffcaii commented 5 years ago

@larryrun Can you show client codes?

larryrun commented 5 years ago

client:

cli, err := rsocket.Connect().
    Resume().
    Fragment(1024).
    Transport("tcp://127.0.0.1:7878").
    Start(context.Background())
if err != nil {
    panic(err)
}
payloadSize := 100
payloadCount := 50000
reqPayloads := genSizedPayload(payloadSize, payloadCount)
send := flux.Create(func(ctx context.Context, s flux.Sink) {
    for _, p := range reqPayloads {
        s.Next(p)
    }
    s.Complete()
})
_, err = cli.RequestChannel(send).BlockLast(context.Background())
if err != nil {
    panic(err)
}
jjeffcaii commented 5 years ago

Thanks! I'll check it later.

jjeffcaii commented 5 years ago

Fixed in release v0.5.2. Please check it. Thanks again!

larryrun commented 5 years ago

It looks good. thanks!