activej / activej

ActiveJ is an alternative Java platform built from the ground up. ActiveJ redefines core, web and high-load programming in Java, providing simplicity, maximum performance and scalability
https://activej.io
Apache License 2.0
828 stars 69 forks source link

RpcClient receive unexpected EOS #294

Closed nguyentamdat closed 8 months ago

nguyentamdat commented 8 months ago

Hi, I have deployed 2 servers: RpcServer and RpcClient. They have run normally for fews days and RpcClient received an EOS message. It closes the connection, throws an AsyncCloseException and doesn't reconnect to RpcServer. Here is my RpcClient setup:

clientLoop = Eventloop.create().withThreadName("RPCClient")
            .withEventloopFatalErrorHandler(FatalErrorHandler.rethrow())
            .withThreadFatalErrorHandler(FatalErrorHandler.rethrow());
        client = RpcClient.create(clientLoop)
                .withMessageTypes(SomeClass.class)
                .withStrategy(server(RPCServer))
                .withReconnectInterval(Duration.of(5, ChronoUnit.SECONDS))
                .withConnectTimeout(Duration.of(10, ChronoUnit.SECONDS))
                .withForcedShutdown()
                .withForcedStart();
        clientLoop.submit(() -> client.start());
        new Thread(clientLoop).start();

And here is my RpcServer setup:

@Provides
  @Eager
  RpcServer rpcServer(Config config, @Named("rpc-server") Eventloop eventloop) {
    return RpcServer.create(eventloop)
        .withMessageTypes(SomeClass.class)
        .withHandler(someHandlers())
        .withListenPort(config.get(ofInteger(), "rpc.listenPort",PORT))
        .withAutoFlushInterval(Duration.ofSeconds(10));
  }

RpcServer is a module in my service, and I use your Launcher and ServiceGraph to start/stop this service. RpcClient is used in other service which doesn't use your Launcher and ServiceGraph. Do I initialize those services correctly? And why RpcClient randomly receive an EOS message?

eduard-vasinskyi commented 8 months ago

Hi, @nguyentamdat

Eventloop runs until it has tasks to execute or any underlying resources (such as RPC connections) are associated with it. Once the RPC connection has been closed, the RPC client initiates a reconnection routine in the background. But since the reconnection is a background task, Eventloop stopped.

When creating Eventloop, you should set the Eventloop#keepAlive(true) parameter to keep Eventloop running even if there are no active tasks or underlying resources. Then, the reconnection would proceed. Or you could use a ServiceGraph, since in this case the keepAlive option is set to Eventloop automatically.

As for why EOS is received, it is most likely due to some network failure. In ActiveJ v6 we will add an option to use explicit end-of-stream for RPC client and server. That way, network failures would not cause EOS to be received.

nguyentamdat commented 8 months ago

Thank you, I will try that config.