baraldi-l-proxaut opened a new issue, #1781:
URL: https://github.com/apache/plc4x/issues/1781

   I wrote a Camel route that reads signals from a Phoenix I/O via modbus 
protocol every 500 milliseconds.
   The I/o Phoenix is connected to my laptop via ethernet cable.
   
   Initially the connection was opened and closed for each read instruction, 
but subsequently I moved to a managed pool of connections to reuse the same 
connection.
   In this way I managed to reduce reading times and avoided saturating the PLC 
connections.
   Before, opening and closing the connection, took me a total of 1 (max 2) 
seconds to read each reading.
   With a managed pool of already open connections, I can read within the 
expected 500 ms.
   
   
   The problem I'm facing now is that if the ethernet cable is disconnected, an 
Exception is thrown that I can't catch and subsequently the connection to that 
IP is no longer usable until the route is restarted.
   
   Do you have any idea on how to catch the java.net.SocketException Connection 
reset?
   
   
   This is the java.net.SocketException thrown:
   
   `2024-09-23T18:18:44.111+02:00  WARN 29312 --- [ntLoopGroup-3-1] 
i.netty.channel.DefaultChannelPipeline   : An exceptionCaught() event was 
fired, and it reached at the tail of the pipeline. It usually means the last 
handler in the pipeline did not handle the exception.
   java.net.SocketException: Connection reset
        at 
java.base/sun.nio.ch.SocketChannelImpl.throwConnectionReset(SocketChannelImpl.java:394)
 ~[na:na]
        at 
java.base/sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:426) ~[na:na]
        at io.netty.buffer.PooledByteBuf.setBytes(PooledByteBuf.java:254) 
~[netty-buffer-4.1.97.Final.jar:4.1.97.Final]
        at 
io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:1132) 
~[netty-buffer-4.1.97.Final.jar:4.1.97.Final]
        at 
io.netty.channel.socket.nio.NioSocketChannel.doReadBytes(NioSocketChannel.java:357)
 ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at 
io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:151)
 ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at 
io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:788) 
~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at 
io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:724)
 ~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at 
io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:650) 
~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562) 
~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
        at 
io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)
 ~[netty-common-4.1.97.Final.jar:4.1.97.Final]
        at 
io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) 
~[netty-common-4.1.97.Final.jar:4.1.97.Final]
        at 
io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
 ~[netty-common-4.1.97.Final.jar:4.1.97.Final]
        at java.base/java.lang.Thread.run(Thread.java:840) ~[na:na]
   `
   
   This is the Camel route:
   
   ```java
   fromF("timer:%s?period=%d", tagGroupName, interval)
           .routeId(tagGroupName)
           .process(exchange -> {
               Map<String, Object> result = 
tagReaderService.directRead(tagGroupTriggerData.getHost(),
                       tagGroupTriggerData.getPort(),
                       DevicePlugin.MODBUS,
                       tagGroupTriggerData.getTagList());
               exchange.getIn().setBody(result);
           })
           .marshal().json(JsonLibrary.Jackson)
           .process(exchange -> {
               String body = exchange.getIn().getBody(String.class);
               tagReaderService.put(tagGroupName, body);
           });
   ```
   This the tagReaderService.directRead method:
   ```java
       public Map<String, Object> directRead(final String host, final Integer 
port, final DevicePlugin devicePlugin,
                                             final List<TagTriggerData> tags) 
throws PlcConnectionException, ExecutionException, InterruptedException {
           if (devicePlugin == DevicePlugin.OMRON_FINS_UDP) {
               Map<String, Object> result = new HashMap<>(tags.size());
               for (var tagDTO : tags) {
                   OmronReadRequest request = new OmronReadRequest();
                   request.setAddress(tagDTO.getAddress());
                   OmronReadResponse response = 
producerTemplate.requestBody("direct:read-omron-single", request, 
OmronReadResponse.class);
                   result.put(tagDTO.getName(), response.getResponse());
               }
               return result;
           } else {
               return plcPoolConnectionService.readValues(host, port, 
devicePlugin, tags);
           }
       }
   ```
   
   This is the plcPoolConnectionService.readValues invoked:
   ```java
       public Map<String, Object> readValues(final String host, final Integer 
port, final DevicePlugin devicePlugin, final List<TagTriggerData> tags) throws 
PlcConnectionException, ExecutionException, InterruptedException {
           ConnectionWrapper connection = getConnectionWrapper(host, port, 
devicePlugin);
           return connection.readValues(tags);
       }
   ```
   This is the getConnectionWrapper:
   ```java
       private ConnectionWrapper getConnectionWrapper(final String host, final 
Integer port, final DevicePlugin devicePlugin) throws PlcConnectionException {
           String key = host + 
ofNullable(port).map(Object::toString).orElse("");
           ConnectionWrapper connection = connections.get(key);
           if (connection == null) {
               connection = createNewConnection(host, port, devicePlugin);
               connections.put(key, connection);
           }
           return connection;
       }
   ```
   
   And here i create the connection:
   ```java
       private ConnectionWrapper createNewConnection(final String host, final 
Integer port, final DevicePlugin devicePlugin) throws PlcConnectionException {
           return switch (devicePlugin) {
               case S7COMM -> ConnectionWrapper.s7Connection(driverManager, 
host);
               case MODBUS -> 
ConnectionWrapper.modbusTcpConnection(driverManager, host, port);
               default -> throw new RuntimeException("Unsupported device 
plugin: " + devicePlugin);
           };
       }
   
       public static ConnectionWrapper modbusTcpConnection(final 
PlcDriverManager driverManager, final String host, final Integer port) throws 
PlcConnectionException {
           String connectionString = 
String.format(MODBUS_TCP_CONNECTION_STRING, host);
           return new ConnectionWrapper(driverManager, connectionString);
       }
   
       private ConnectionWrapper(final PlcDriverManager driverManager, final 
String connectionString) throws PlcConnectionException {
           connection = driverManager.getConnection(connectionString);
       }
   ```
   
[TagGroupRouteBuilder.zip](https://github.com/user-attachments/files/17100934/TagGroupRouteBuilder.zip)
   
   
   Feel free to write to me for any information and if there are any points to 
explore further.
   Thank you,
   Luca
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to