23
23
import io .netty .channel .ChannelFutureListener ;
24
24
import io .netty .channel .ChannelHandler ;
25
25
import io .netty .channel .EventLoop ;
26
+ import java .time .Duration ;
26
27
import java .util .Collections ;
28
+ import java .util .Optional ;
27
29
import java .util .concurrent .CompletableFuture ;
28
30
import java .util .concurrent .CompletionStage ;
29
31
import java .util .concurrent .TimeUnit ;
@@ -56,7 +58,8 @@ public class NetworkConnection implements Connection {
56
58
private final boolean ssrEnabled ;
57
59
private final BoltProtocol protocol ;
58
60
59
- private final Long connectionReadTimeout ;
61
+ private final Duration defaultReadTimeout ;
62
+ private Duration readTimeout ;
60
63
61
64
private ChannelHandler connectionReadTimeoutHandler ;
62
65
@@ -70,8 +73,10 @@ public NetworkConnection(Channel channel, LoggingProvider logging) {
70
73
this .telemetryEnabled = ChannelAttributes .telemetryEnabled (channel );
71
74
this .ssrEnabled = ChannelAttributes .ssrEnabled (channel );
72
75
this .protocol = BoltProtocol .forChannel (channel );
73
- this .connectionReadTimeout =
74
- ChannelAttributes .connectionReadTimeout (channel ).orElse (null );
76
+ this .defaultReadTimeout = ChannelAttributes .connectionReadTimeout (channel )
77
+ .map (Duration ::ofSeconds )
78
+ .orElse (null );
79
+ this .readTimeout = defaultReadTimeout ;
75
80
}
76
81
77
82
@ Override
@@ -179,6 +184,25 @@ public EventLoop eventLoop() {
179
184
return channel .eventLoop ();
180
185
}
181
186
187
+ @ Override
188
+ public Optional <Duration > defaultReadTimeoutMillis () {
189
+ return Optional .ofNullable (defaultReadTimeout );
190
+ }
191
+
192
+ @ Override
193
+ public void setReadTimeout (Duration duration ) {
194
+ if (!channel .eventLoop ().inEventLoop ()) {
195
+ throw new IllegalStateException ("This method may only be called in the EventLoop" );
196
+ }
197
+
198
+ if (duration != null && duration .toMillis () > 0 ) {
199
+ // only values greater than zero milliseconds are supported
200
+ this .readTimeout = duration ;
201
+ } else {
202
+ this .readTimeout = this .defaultReadTimeout ;
203
+ }
204
+ }
205
+
182
206
private CompletionStage <Void > writeMessageInEventLoop (Message message , ResponseHandler handler ) {
183
207
var future = new CompletableFuture <Void >();
184
208
Runnable runnable = () -> {
@@ -215,8 +239,9 @@ private void registerConnectionReadTimeout(Channel channel) {
215
239
throw new IllegalStateException ("This method may only be called in the EventLoop" );
216
240
}
217
241
218
- if (connectionReadTimeout != null && connectionReadTimeoutHandler == null ) {
219
- connectionReadTimeoutHandler = new ConnectionReadTimeoutHandler (connectionReadTimeout , TimeUnit .SECONDS );
242
+ if (this .readTimeout != null && connectionReadTimeoutHandler == null ) {
243
+ connectionReadTimeoutHandler =
244
+ new ConnectionReadTimeoutHandler (readTimeout .toMillis (), TimeUnit .MILLISECONDS );
220
245
channel .pipeline ().addFirst (connectionReadTimeoutHandler );
221
246
log .log (System .Logger .Level .DEBUG , "Added ConnectionReadTimeoutHandler" );
222
247
messageDispatcher .setBeforeLastHandlerHook (() -> {
0 commit comments