套接字读取在 Docker Java 的回调期间中断
Socket read interrupted during callback from Docker Java
上下文
我有一个网络服务在队列中写入一个测试 ID。然后,侦听器读取队列、搜索测试并启动它。在这些步骤中,它会在数据库中写入测试更新,以便向用户显示。更准确地说:测试在 docker 容器中启动,在它结束时,我想将测试状态更新为 FINISHED
。为此,我使用带有回调的 docker java 库。
问题
在调用回调时,我在调用更新测试时收到多条错误消息(但它只发生一次,如果我第二次尝试两次就可以了,但它仍然会写很多错误消息来自事务管理器)。
以下是记录的错误消息:
2020-11-20 09:20:43,639 WARN [docker-java-stream--1032099154] (org.jboss.jca.core.connectionmanager.listener.TxConnectionListener) IJ000305: Connection error occured: org.jboss.jca.core.connectionmanager.listener.TxConnectionListener@600268e6[state=NORMAL managed connection=org.jboss.jca.adapters.jdbc.local.LocalManagedConnection@236f1a69 connection handles=1 lastReturned=1605860423264 lastValidated=1605860242146 lastCheckedOut=1605860443564 trackByTx=true pool=org.jboss.jca.core.connectionmanager.pool.strategy.OnePool@2efb0d3b mcp=SemaphoreConcurrentLinkedQueueManagedConnectionPool@3e8e7a62[pool=ApplicationDS] xaResource=LocalXAResourceImpl@482fdad2[connectionListener=600268e6 connectionManager=4c83f895 warned=false currentXid=null productName=Oracle productVersion=Oracle Database 18c Enterprise Edition Release 18.0.0.0.0 - Production
Version 18.3.0.0.0 jndiName=java:/ApplicationDS] txSync=TransactionSynchronization@1387480544{tx=Local transaction (delegate=TransactionImple < ac, BasicAction: 0:ffffac110002:-50a6b0bf:5fb6bdb9:73db4 status: ActionStatus.ABORTING >, owner=Local transaction context for provider JBoss JTA transaction provider) wasTrackByTx=true enlisted=true cancel=false}]: java.sql.SQLRecoverableException: IO Error: Socket read interrupted
2020-11-20 09:20:43,647 INFO [docker-java-stream--1032099154] (org.jboss.jca.core.connectionmanager.listener.TxConnectionListener) IJ000302: Unregistered handle that was not registered: org.jboss.jca.adapters.jdbc.jdk8.WrappedConnectionJDK8@4f3c1cb2 for managed connection: org.jboss.jca.adapters.jdbc.local.LocalManagedConnection@236f1a69
2020-11-20 09:20:43,656 WARN [docker-java-stream--1032099154] (com.arjuna.ats.jta) ARJUNA016031: XAOnePhaseResource.rollback for < formatId=131077, gtrid_length=29, bqual_length=36, tx_uid=0:ffffac110002:-50a6b0bf:5fb6bdb9:73db4, node_name=1, branch_uid=0:ffffac110002:-50a6b0bf:5fb6bdb9:73db8, subordinatenodename=null, eis_name=java:/ApplicationDS > failed with exception: org.jboss.jca.core.spi.transaction.local.LocalXAException: IJ001160: Could not rollback local transaction
Caused by: org.jboss.jca.core.spi.transaction.local.LocalResourceException: IO Error: Socket read interrupted
at org.jboss.ironjacamar.jdbcadapters@1.4.22.Final//org.jboss.jca.adapters.jdbc.local.LocalManagedConnection.rollback(LocalManagedConnection.java:139)
...
Caused by: java.sql.SQLRecoverableException: IO Error: Socket read interrupted
at com.oracle.jdbc//oracle.jdbc.driver.T4CConnection.doRollback(T4CConnection.java:1140)
...
Caused by: java.io.InterruptedIOException: Socket read interrupted
at com.oracle.jdbc//oracle.net.nt.TimeoutSocketChannel.handleInterrupt(TimeoutSocketChannel.java:258)
...
说明
一开始我想到了一个连接的问题,可能是回调的时候交易已经不可用了(因为docker 运行时间太长了),可能只好作废。
但最后,如控制台中所写,它来自线程在尝试获取锁以更新测试时的中断,我发现了这个中断的来源:我看了一下method executeAndStream
in DefaultInvocationBuilder
来自 docker java 库,我发现了这个:
Thread thread = new Thread(() -> {
Thread streamingThread = Thread.currentThread();
try (DockerHttpClient.Response response = execute(request)) {
callback.onStart(() -> {
streamingThread.interrupt();
response.close();
});
sourceConsumer.accept(response);
callback.onComplete();
} catch (Exception e) {
callback.onError(e);
}
}, "docker-java-stream-" + Objects.hashCode(request));
thread.setDaemon(true);
thread.start();
在这里,给 onStart
的 closable 中断了线程。在那之后,我在 method onComplete
from ResultCallbackTemplate
中发现(我正在为我的回调扩展)关闭那个可关闭的:
@Override
public void onComplete() {
try {
close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
分辨率
问题终于出在我写的下面这段代码中:
@Override
public void onComplete() {
super.onComplete();
updateTest(FINISHED);
}
我像往常一样从父级调用 onComplete
方法,但首先是在执行任何其他操作之前。为了纠正这个问题,我只需要在最后调用 super 方法:
@Override
public void onComplete() {
updateTest(FINISHED);
super.onComplete();
}
上下文
我有一个网络服务在队列中写入一个测试 ID。然后,侦听器读取队列、搜索测试并启动它。在这些步骤中,它会在数据库中写入测试更新,以便向用户显示。更准确地说:测试在 docker 容器中启动,在它结束时,我想将测试状态更新为 FINISHED
。为此,我使用带有回调的 docker java 库。
问题
在调用回调时,我在调用更新测试时收到多条错误消息(但它只发生一次,如果我第二次尝试两次就可以了,但它仍然会写很多错误消息来自事务管理器)。
以下是记录的错误消息:
2020-11-20 09:20:43,639 WARN [docker-java-stream--1032099154] (org.jboss.jca.core.connectionmanager.listener.TxConnectionListener) IJ000305: Connection error occured: org.jboss.jca.core.connectionmanager.listener.TxConnectionListener@600268e6[state=NORMAL managed connection=org.jboss.jca.adapters.jdbc.local.LocalManagedConnection@236f1a69 connection handles=1 lastReturned=1605860423264 lastValidated=1605860242146 lastCheckedOut=1605860443564 trackByTx=true pool=org.jboss.jca.core.connectionmanager.pool.strategy.OnePool@2efb0d3b mcp=SemaphoreConcurrentLinkedQueueManagedConnectionPool@3e8e7a62[pool=ApplicationDS] xaResource=LocalXAResourceImpl@482fdad2[connectionListener=600268e6 connectionManager=4c83f895 warned=false currentXid=null productName=Oracle productVersion=Oracle Database 18c Enterprise Edition Release 18.0.0.0.0 - Production
Version 18.3.0.0.0 jndiName=java:/ApplicationDS] txSync=TransactionSynchronization@1387480544{tx=Local transaction (delegate=TransactionImple < ac, BasicAction: 0:ffffac110002:-50a6b0bf:5fb6bdb9:73db4 status: ActionStatus.ABORTING >, owner=Local transaction context for provider JBoss JTA transaction provider) wasTrackByTx=true enlisted=true cancel=false}]: java.sql.SQLRecoverableException: IO Error: Socket read interrupted
2020-11-20 09:20:43,647 INFO [docker-java-stream--1032099154] (org.jboss.jca.core.connectionmanager.listener.TxConnectionListener) IJ000302: Unregistered handle that was not registered: org.jboss.jca.adapters.jdbc.jdk8.WrappedConnectionJDK8@4f3c1cb2 for managed connection: org.jboss.jca.adapters.jdbc.local.LocalManagedConnection@236f1a69
2020-11-20 09:20:43,656 WARN [docker-java-stream--1032099154] (com.arjuna.ats.jta) ARJUNA016031: XAOnePhaseResource.rollback for < formatId=131077, gtrid_length=29, bqual_length=36, tx_uid=0:ffffac110002:-50a6b0bf:5fb6bdb9:73db4, node_name=1, branch_uid=0:ffffac110002:-50a6b0bf:5fb6bdb9:73db8, subordinatenodename=null, eis_name=java:/ApplicationDS > failed with exception: org.jboss.jca.core.spi.transaction.local.LocalXAException: IJ001160: Could not rollback local transaction
Caused by: org.jboss.jca.core.spi.transaction.local.LocalResourceException: IO Error: Socket read interrupted
at org.jboss.ironjacamar.jdbcadapters@1.4.22.Final//org.jboss.jca.adapters.jdbc.local.LocalManagedConnection.rollback(LocalManagedConnection.java:139)
...
Caused by: java.sql.SQLRecoverableException: IO Error: Socket read interrupted
at com.oracle.jdbc//oracle.jdbc.driver.T4CConnection.doRollback(T4CConnection.java:1140)
...
Caused by: java.io.InterruptedIOException: Socket read interrupted
at com.oracle.jdbc//oracle.net.nt.TimeoutSocketChannel.handleInterrupt(TimeoutSocketChannel.java:258)
...
说明
一开始我想到了一个连接的问题,可能是回调的时候交易已经不可用了(因为docker 运行时间太长了),可能只好作废。
但最后,如控制台中所写,它来自线程在尝试获取锁以更新测试时的中断,我发现了这个中断的来源:我看了一下method executeAndStream
in DefaultInvocationBuilder
来自 docker java 库,我发现了这个:
Thread thread = new Thread(() -> {
Thread streamingThread = Thread.currentThread();
try (DockerHttpClient.Response response = execute(request)) {
callback.onStart(() -> {
streamingThread.interrupt();
response.close();
});
sourceConsumer.accept(response);
callback.onComplete();
} catch (Exception e) {
callback.onError(e);
}
}, "docker-java-stream-" + Objects.hashCode(request));
thread.setDaemon(true);
thread.start();
在这里,给 onStart
的 closable 中断了线程。在那之后,我在 method onComplete
from ResultCallbackTemplate
中发现(我正在为我的回调扩展)关闭那个可关闭的:
@Override
public void onComplete() {
try {
close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
分辨率
问题终于出在我写的下面这段代码中:
@Override
public void onComplete() {
super.onComplete();
updateTest(FINISHED);
}
我像往常一样从父级调用 onComplete
方法,但首先是在执行任何其他操作之前。为了纠正这个问题,我只需要在最后调用 super 方法:
@Override
public void onComplete() {
updateTest(FINISHED);
super.onComplete();
}