SolarNetwork/nifty-modbus

call client.start().get(); on stopped client causes error.

dafik opened this issue · 6 comments

dafik commented

example code:

NettyRtuModbusClientConfig config = new NettyRtuModbusClientConfig(uart.uartConfig.file, params);
final ModbusClient  client = new RtuNettyModbusClient(config, new JscSerialPortProvider());

client.start().get();

RegistersModbusMessage request = RegistersModbusMessage.readRegistersRequest(ModbusBlockType.valueOf(type.getType()), unitId, address, 1);
ModbusMessage response = client.send(request);
RegistersModbusMessage responseMessage = response.unwrap(RegistersModbusMessage.class);

client.stop();

client.start().get();

17:11:25.512 [globalEventExecutor-2-2 ] WARN io.netty.util.concurrent.DefaultPromise ::notifyListener0 - An exception was thrown by net.solarnetwork.io.modbus.netty.handler.NettyModbusClient$$Lambda$207/0xa93b22d0.operationComplete(): java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask@12662c2[Not completed, task = java.util.concurrent.Executors$RunnableAdapter@133e8d6[Wrapped task = net.solarnetwork.io.modbus.netty.handler.NettyModbusClient$$Lambda$211/0xa93f8480@e97581]] rejected from java.util.concurrent.ScheduledThreadPoolExecutor@1395e7e[Terminated, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0]
at java.base/java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2057)
at java.base/java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:827)
at java.base/java.util.concurrent.ScheduledThreadPoolExecutor.delayedExecute(ScheduledThreadPoolExecutor.java:340)
at java.base/java.util.concurrent.ScheduledThreadPoolExecutor.schedule(ScheduledThreadPoolExecutor.java:562)
at java.base/java.util.concurrent.Executors$DelegatedScheduledExecutorService.schedule(Executors.java:779)
at net.solarnetwork.io.modbus.netty.handler.NettyModbusClient.handleCloseAndScheduleReconnectIfRequired(NettyModbusClient.java:254)
at net.solarnetwork.io.modbus.netty.handler.NettyModbusClient.lambda$handleConnect$2(NettyModbusClient.java:240)
at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:577)
at io.netty.util.concurrent.DefaultPromise.access$300(DefaultPromise.java:35)
at io.netty.util.concurrent.DefaultPromise$2.run(DefaultPromise.java:531)
at io.netty.util.concurrent.GlobalEventExecutor$TaskRunner.run(GlobalEventExecutor.java:243)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:831)

tried on different serialPort implenentation with same result.

Docs for interface allow that.

/**
 * Stop the client.
 * 
 * <p>
 * This method shuts the client down, disconnecting it from whatever Modbus
 * network it had been connected to. It can be started again by calling
 * {@link #start()}. **Calling this method on a client that has already been
 * stopped is allowed and will not result in any error.**
 * </p>
 * 
 * <p>
 * After calling this method {@link #isStarted()} will return
 * {@literal false}.
 * </p>
 */
void stop();
msqr commented

You are correct, the intention is to be able to re-start the client. It was working when an external ScheduledExecutorService and EventLoopGroup were passed to the constructor, but not when the client created and managed its own. I just pushed a fix... are you able to build and test the latest in your project?

dafik commented

I confirm its working.
Thaks for super fast patch and response

msqr commented

Excellent, thank you for taking the time to report the issue. I've pushed out a 0.4.0 release to Maven Central now that includes the fix.

dafik commented

After about 24 hours of operation, starting the client before reading and closing after reading in 60s intervals, I get an endless loop of the client cannot be started because there is a timeout on closing

Jul 28 19:16:52 boneio-2 java[30152]: 19:16:52.537 [sbc2ha-1-thread-1             ] WARN  arnetwork.io.modbus.rtu.netty.RtuNettyModbusClient::stop                                - Timeout waiting for /dev/ttyS4 9600 8N1 EventLoopGroup to shutdown
Jul 28 19:16:52 boneio-2 java[30152]: 19:16:52.576 [sbc2ha-1-thread-1             ] ERROR com.dfi.sbc2ha.modbus.Modbus                      ::readMany                            - read many: java.util.concurrent.ExecutionException: java.util.concu
Jul 28 19:16:52 boneio-2 java[30152]:         at java.base/java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:395)
Jul 28 19:16:52 boneio-2 java[30152]:         at java.base/java.util.concurrent.CompletableFuture.get(CompletableFuture.java:2069)
Jul 28 19:16:52 boneio-2 java[30152]:         at com.dfi.sbc2ha.modbus.Modbus.readMany(Modbus.java:85)
Jul 28 19:16:52 boneio-2 java[30152]:         at com.dfi.sbc2ha.sensor.modbus.ModbusSensor.run(ModbusSensor.java:99)
Jul 28 19:16:52 boneio-2 java[30152]:         at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
Jul 28 19:16:52 boneio-2 java[30152]:         at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305)
Jul 28 19:16:52 boneio-2 java[30152]:         at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305)
Jul 28 19:16:52 boneio-2 java[30152]:         at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
Jul 28 19:16:52 boneio-2 java[30152]:         at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
Jul 28 19:16:52 boneio-2 java[30152]:         at java.base/java.lang.Thread.run(Thread.java:831)
Jul 28 19:16:52 boneio-2 java[30152]: Caused by: java.util.concurrent.RejectedExecutionException: shutting down
Jul 28 19:16:52 boneio-2 java[30152]:         at io.netty.channel.ThreadPerChannelEventLoopGroup.nextChild(ThreadPerChannelEventLoopGroup.java:308)
Jul 28 19:16:52 boneio-2 java[30152]:         at io.netty.channel.ThreadPerChannelEventLoopGroup.register(ThreadPerChannelEventLoopGroup.java:277)
Jul 28 19:16:52 boneio-2 java[30152]:         at io.netty.bootstrap.AbstractBootstrap.initAndRegister(AbstractBootstrap.java:323)
Jul 28 19:16:52 boneio-2 java[30152]:         at io.netty.bootstrap.Bootstrap.doResolveAndConnect(Bootstrap.java:155)
Jul 28 19:16:52 boneio-2 java[30152]:         at io.netty.bootstrap.Bootstrap.connect(Bootstrap.java:116)
Jul 28 19:16:52 boneio-2 java[30152]:         at net.solarnetwork.io.modbus.rtu.netty.RtuNettyModbusClient.connect(RtuNettyModbusClient.java:177)
Jul 28 19:16:52 boneio-2 java[30152]:         at net.solarnetwork.io.modbus.netty.handler.NettyModbusClient.handleConnect(NettyModbusClient.java:238)
Jul 28 19:16:52 boneio-2 java[30152]:         at net.solarnetwork.io.modbus.netty.handler.NettyModbusClient.start(NettyModbusClient.java:185)

msqr commented

Hi @dafik I moved your comment to a new issue, #8.

msqr commented

Hi @dafik just following up here to see if you had any more info available for #8?