Skip to content

Commit 470215a

Browse files
committed
feat(tfo): add preview support for TFO
This update adds preview support for TCP Fast Open. When TFO is enabled the driver either sends Bolt Handshake (for non-encrypted connections) or TLS handshake (for encrypted connections). The TCP Fast Open is only supported when all of the following is true: - The system the driver is running on supports and has TCP Fast Open enabled. - One of the following connection URI schemes is used: - neo4j - neo4j+s - neo4j+ssc - bolt - bolt+s - bolt+ssc - One of the following Netty Native Transports that is compatible with the system the driver is running on is added to the runtime by the user: - netty-transport-native-io_uring (Netty 4.2+ only) - netty-transport-native-epoll - netty-transport-native-kqueue Even when all of the above is true, it is important to make sure that the endpoint the driver connects to also supports and has TCP Fast Open enabled. At present, this is an opt-in `Config` option available via `ConfigBuilder#withTcpFastOpenEnabled(boolean)`. It is `false` by default.
1 parent dd3dca2 commit 470215a

File tree

2 files changed

+71
-4
lines changed

2 files changed

+71
-4
lines changed

driver/src/main/java/org/neo4j/driver/Config.java

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,11 +156,20 @@ public final class Config implements Serializable {
156156
private final boolean telemetryDisabled;
157157
/**
158158
* The {@link ObservationProvider} if configured.
159+
*
159160
* @since 6.0.0
160161
*/
161162
@Preview(name = "Observability")
162163
private final transient ObservationProvider observationProvider;
163164

165+
/**
166+
* Defines whether the driver should try using TCP Fast Open if the runtime supports it. This option is ignored
167+
* when the conditions described in {@link ConfigBuilder#withTcpFastOpenEnabled(boolean)} are not met.
168+
* @since 6.0.0
169+
*/
170+
@Preview(name = "TFO")
171+
private final boolean tcpFastOpenEnabled;
172+
164173
private Config(ConfigBuilder builder) {
165174
this.logging = builder.logging;
166175
this.logLeakedSessions = builder.logLeakedSessions;
@@ -183,6 +192,7 @@ private Config(ConfigBuilder builder) {
183192
this.eventLoopThreads = builder.eventLoopThreads;
184193
this.telemetryDisabled = builder.telemetryDisabled;
185194
this.observationProvider = builder.observationProvider;
195+
this.tcpFastOpenEnabled = builder.tcpFastOpenEnabled;
186196
}
187197

188198
/**
@@ -403,6 +413,20 @@ public Optional<ObservationProvider> observationProvider() {
403413
return Optional.ofNullable(observationProvider);
404414
}
405415

416+
/**
417+
* Returns whether the driver should try using TCP Fast Open if the runtime supports it. This option is ignored
418+
* when the conditions described in {@link ConfigBuilder#withTcpFastOpenEnabled(boolean)} are not met.
419+
* <p>
420+
* The default is {@literal false}.
421+
*
422+
* @return {@literal true} to enable and {@literal false} to disable
423+
* @since 6.0.0
424+
*/
425+
@Preview(name = "TFO")
426+
public boolean isTcpFastOpenEnabled() {
427+
return tcpFastOpenEnabled;
428+
}
429+
406430
/**
407431
* Used to build new config instances
408432
*/
@@ -425,6 +449,7 @@ public static final class ConfigBuilder {
425449
private long fetchSize = 1000;
426450
private int eventLoopThreads = 0;
427451
private ObservationProvider observationProvider;
452+
private boolean tcpFastOpenEnabled;
428453

429454
@SuppressWarnings("deprecation")
430455
private NotificationConfig notificationConfig = NotificationConfig.defaultConfig();
@@ -874,6 +899,47 @@ public ConfigBuilder withTelemetryDisabled(boolean telemetryDisabled) {
874899
return this;
875900
}
876901

902+
/**
903+
* Sets whether the driver should try using TCP Fast Open if the runtime supports it. This option is ignored
904+
* when the conditions described below are not met.
905+
* <p>
906+
* The default is {@literal false}.
907+
* <p>
908+
* The TCP Fast Open is only supported when all of the following is true:
909+
* <ul>
910+
* <li>The system the driver is running on supports and has TCP Fast Open enabled.</li>
911+
* <li>One of the following connection URI schemes is used:
912+
* <ul>
913+
* <li>neo4j</li>
914+
* <li>neo4j+s</li>
915+
* <li>neo4j+ssc</li>
916+
* <li>bolt</li>
917+
* <li>bolt+s</li>
918+
* <li>bolt+ssc</li>
919+
* </ul>
920+
* </li>
921+
* <li>One of the following Netty Native Transports that is compatible with the system the driver is running on
922+
* is added to the runtime by the user:
923+
* <ul>
924+
* <li>netty-transport-native-io_uring (Netty 4.2+ only)</li>
925+
* <li>netty-transport-native-epoll</li>
926+
* <li>netty-transport-native-kqueue</li>
927+
* </ul>
928+
* </li>
929+
* </ul>
930+
* <p>
931+
* Even when all of the above is true, it is important to make sure that the endpoint the driver connects to also
932+
* supports and has TCP Fast Open enabled.
933+
* @param enabled {@literal true} to enable and {@literal false} to disable
934+
* @return this builder
935+
* @since 6.0.0
936+
*/
937+
@Preview(name = "TFO")
938+
public ConfigBuilder withTcpFastOpenEnabled(boolean enabled) {
939+
this.tcpFastOpenEnabled = enabled;
940+
return this;
941+
}
942+
877943
/**
878944
* Create a config instance from this builder.
879945
*

driver/src/main/java/org/neo4j/driver/internal/DriverFactory.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ private BoltConnectionSourceFactory createPooledBoltConnectionSource(
361361
eventLoopGroup,
362362
clock,
363363
loggingProvider,
364-
config.eventLoopThreads(),
364+
config,
365365
observationProvider,
366366
boltConnectionProviderFactory);
367367
var listeningBoltConnectionProvider = BoltConnectionListener.listeningBoltConnectionProvider(
@@ -401,20 +401,21 @@ private BoltConnectionProvider createBoltConnectionProvider(
401401
ScheduledExecutorService eventLoopGroup,
402402
Clock clock,
403403
LoggingProvider loggingProvider,
404-
int eventLoopThreads,
404+
Config config,
405405
BoltObservationProvider observationProvider,
406406
BoltConnectionProviderFactory boltConnectionProviderFactory) {
407407
var additionalConfig = new HashMap<String, Object>();
408408
additionalConfig.put("clock", clock);
409409
if (eventLoopGroup != null) {
410410
additionalConfig.put("eventLoopGroup", eventLoopGroup);
411-
} else if (eventLoopThreads > 0) {
412-
additionalConfig.put("eventLoopThreads", eventLoopThreads);
411+
} else if (config.eventLoopThreads() > 0) {
412+
additionalConfig.put("eventLoopThreads", config.eventLoopThreads());
413413
}
414414
var localAddress = localAddress();
415415
if (localAddress != null) {
416416
additionalConfig.put("localAddress", localAddress);
417417
}
418+
additionalConfig.put("enableFastOpen", config.isTcpFastOpenEnabled());
418419
return boltConnectionProviderFactory.create(
419420
loggingProvider, BoltValueFactory.getInstance(), observationProvider, additionalConfig);
420421
}

0 commit comments

Comments
 (0)