Skip to content

Commit 784aa8b

Browse files
committed
Merge branch 'release/0.8.4'
2 parents eb00d2e + 7fe7d61 commit 784aa8b

21 files changed

+304
-82
lines changed

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,15 @@
11
# Change Log
2+
## [0.8.4](https://github.com/mariadb-corporation/mariadb-connector-r2dbc/tree/0.8.4) (29 Sep 2020)
3+
[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-r2dbc/compare/0.8.3...0.8.4)
4+
5+
First Release Candidate release.
6+
7+
Changes compared to 0.8.3.beta1:
8+
[R2DBC-9] Non pipelining prepare is close 2 time when race condition cache
9+
[R2DBC-8] synchronous close
10+
[R2DBC-7] authentication error when using multiple classloader
11+
[R2DBC-6] socket option configuration addition for socket Timeout, keep alive and force RST
12+
213
## [0.8.3](https://github.com/mariadb-corporation/mariadb-connector-r2dbc/tree/0.8.3) (23 Jul 2020)
314
[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-r2dbc/compare/0.8.2...0.8.3)
415

README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ The MariaDB Connector is available through maven using :
2929
<dependency>
3030
<groupId>org.mariadb</groupId>
3131
<artifactId>r2dbc-mariadb</artifactId>
32-
<version>0.8.3-beta1</version>
32+
<version>0.8.4-rc</version>
3333
</dependency>
3434
```
3535

@@ -82,6 +82,9 @@ Basic example:
8282
| **`port`** | Database server port number. *Not used when using option `socketPath`*|*integer*| 3306|
8383
| **`database`** | Default database to use when establishing the connection. | *string* |
8484
| **`connectTimeout`** | Sets the connection timeout | *Duration* | 10s|
85+
| **`socketTimeout`** | Sets the socket timeout | *Duration* | |
86+
| **`tcpKeepAlive`** | Sets socket keep alive | *Boolean* | false|
87+
| **`tcpAbortiveClose`** | This option can be used in environments where connections are created and closed in rapid succession. Often, it is not possible to create a socket in such an environment after a while, since all local “ephemeral” ports are used up by TCP connections in TCP_WAIT state. Using tcpAbortiveClose works around this problem by resetting TCP connections (abortive or hard close) rather than doing an orderly close. | *boolean* | false|
8588
| **`socket`** | Permits connections to the database through the Unix domain socket for faster connection whe server is local. | *string* |
8689
| **`allowMultiQueries`** | Allows you to issue several SQL statements in a single call. (That is, `INSERT INTO a VALUES('b'); INSERT INTO c VALUES('d');`). <br/><br/>This may be a **security risk** as it allows for SQL Injection attacks.| *boolean* | false|
8790
| **`connectionAttributes`** | When performance_schema is active, permit to send server some client information. <br>Those information can be retrieved on server within tables performance_schema.session_connect_attrs and performance_schema.session_account_connect_attrs. This can permit from server an identification of client/application per connection|*Map<String,String>* |
@@ -99,7 +102,7 @@ Basic example:
99102
| **`useServerPrepStmts`** | Permit to indicate to use text or binary protocol for query with parameter |*boolean* | false |
100103
| **`prepareCacheSize`** | if useServerPrepStmts = true, cache the prepared informations in a LRU cache to avoid re-preparation of command. Next use of that command, only prepared identifier and parameters (if any) will be sent to server. This mainly permit for server to avoid reparsing query. |*int* |256 |
101104
| **`pamOtherPwd`** | Permit to provide additional password for PAM authentication with multiple authentication step. If multiple passwords, value must be URL encoded.|*string* | |
102-
105+
103106
## Roadmap
104107

105108
* Performance !

pom.xml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
<modelVersion>4.0.0</modelVersion>
2323
<groupId>org.mariadb</groupId>
2424
<artifactId>r2dbc-mariadb</artifactId>
25-
<version>0.8.3-beta1</version>
25+
<version>0.8.4-rc</version>
2626
<packaging>jar</packaging>
2727
<url>https://github.com/mariadb-corporation/mariadb-connector-r2dbc</url>
2828

@@ -41,7 +41,7 @@
4141
<r2dbc-spi.version>0.8.2.RELEASE</r2dbc-spi.version>
4242
<reactor.version>Dysprosium-SR9</reactor.version>
4343
<mariadb-jdbc.version>2.6.1</mariadb-jdbc.version>
44-
<r2dbc-mysql.version>0.8.1.RELEASE</r2dbc-mysql.version>
44+
<r2dbc-mysql.version>0.8.2.RELEASE</r2dbc-mysql.version>
4545
<uberjar.name>benchmarks</uberjar.name>
4646
</properties>
4747

@@ -53,15 +53,15 @@
5353
</licenses>
5454

5555
<organization>
56-
<name>mariadb.com</name>
57-
<url>https://mariadb.com</url>
56+
<name>MariaDB Corporation Ab</name>
57+
<url>https://www.mariadb.com</url>
5858
</organization>
5959

6060
<developers>
6161
<developer>
62-
<id>mariadbJdbcDevelopers</id>
63-
<name>mariadb jdbc developers</name>
64-
<url>http://mariadb.org/</url>
62+
<id>mariadbDevelopers</id>
63+
<name>mariadb developers</name>
64+
<url>http://www.mariadb.com</url>
6565
</developer>
6666
</developers>
6767

src/main/java/org/mariadb/r2dbc/MariadbConnectionConfiguration.java

Lines changed: 90 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,11 @@ public final class MariadbConnectionConfiguration {
3434
public static final int DEFAULT_PORT = 3306;
3535
private final String database;
3636
private final String host;
37+
3738
private final Duration connectTimeout;
39+
private final Duration socketTimeout;
40+
private final boolean tcpKeepAlive;
41+
private final boolean tcpAbortiveClose;
3842
private final CharSequence password;
3943
private final CharSequence[] pamOtherPwd;
4044
private final int port;
@@ -54,6 +58,9 @@ public final class MariadbConnectionConfiguration {
5458

5559
private MariadbConnectionConfiguration(
5660
@Nullable Duration connectTimeout,
61+
@Nullable Duration socketTimeout,
62+
@Nullable Boolean tcpKeepAlive,
63+
@Nullable Boolean tcpAbortiveClose,
5764
@Nullable String database,
5865
@Nullable String host,
5966
@Nullable Map<String, String> connectionAttributes,
@@ -77,6 +84,9 @@ private MariadbConnectionConfiguration(
7784
@Nullable Integer prepareCacheSize,
7885
@Nullable CharSequence[] pamOtherPwd) {
7986
this.connectTimeout = connectTimeout == null ? Duration.ofSeconds(10) : connectTimeout;
87+
this.socketTimeout = socketTimeout;
88+
this.tcpKeepAlive = tcpKeepAlive == null ? Boolean.FALSE : tcpKeepAlive;
89+
this.tcpAbortiveClose = tcpAbortiveClose == null ? Boolean.FALSE : tcpAbortiveClose;
8090
this.database = database;
8191
this.host = host;
8292
this.connectionAttributes = connectionAttributes;
@@ -112,6 +122,16 @@ static boolean boolValue(Object value) {
112122
throw new IllegalArgumentException(String.format("Option %s wrong boolean format", value));
113123
}
114124

125+
static Duration durationValue(Object value) {
126+
if (value instanceof Duration) {
127+
return ((Duration) value);
128+
}
129+
if (value instanceof String) {
130+
return Duration.parse(value.toString());
131+
}
132+
throw new IllegalArgumentException(String.format("Option %s wrong duration format", value));
133+
}
134+
115135
static int intValue(Object value) {
116136
if (value instanceof Number) {
117137
return ((Number) value).intValue();
@@ -124,7 +144,6 @@ static int intValue(Object value) {
124144

125145
public static Builder fromOptions(ConnectionFactoryOptions connectionFactoryOptions) {
126146
Builder builder = new Builder();
127-
builder.connectTimeout(connectionFactoryOptions.getValue(CONNECT_TIMEOUT));
128147
builder.database(connectionFactoryOptions.getValue(DATABASE));
129148

130149
if (connectionFactoryOptions.hasOption(MariadbConnectionFactoryProvider.SOCKET)) {
@@ -141,6 +160,31 @@ public static Builder fromOptions(ConnectionFactoryOptions connectionFactoryOpti
141160
MariadbConnectionFactoryProvider.ALLOW_MULTI_QUERIES)));
142161
}
143162

163+
if (connectionFactoryOptions.hasOption(ConnectionFactoryOptions.CONNECT_TIMEOUT)) {
164+
builder.connectTimeout(
165+
durationValue(
166+
connectionFactoryOptions.getValue(ConnectionFactoryOptions.CONNECT_TIMEOUT)));
167+
}
168+
169+
if (connectionFactoryOptions.hasOption(MariadbConnectionFactoryProvider.SOCKET_TIMEOUT)) {
170+
builder.socketTimeout(
171+
durationValue(
172+
connectionFactoryOptions.getValue(MariadbConnectionFactoryProvider.SOCKET_TIMEOUT)));
173+
}
174+
175+
if (connectionFactoryOptions.hasOption(MariadbConnectionFactoryProvider.TCP_KEEP_ALIVE)) {
176+
builder.tcpKeepAlive(
177+
boolValue(
178+
connectionFactoryOptions.getValue(MariadbConnectionFactoryProvider.TCP_KEEP_ALIVE)));
179+
}
180+
181+
if (connectionFactoryOptions.hasOption(MariadbConnectionFactoryProvider.TCP_ABORTIVE_CLOSE)) {
182+
builder.tcpAbortiveClose(
183+
boolValue(
184+
connectionFactoryOptions.getValue(
185+
MariadbConnectionFactoryProvider.TCP_ABORTIVE_CLOSE)));
186+
}
187+
144188
if (connectionFactoryOptions.hasOption(MariadbConnectionFactoryProvider.ALLOW_PIPELINING)) {
145189
builder.allowPipelining(
146190
boolValue(
@@ -307,6 +351,18 @@ public int getPrepareCacheSize() {
307351
return prepareCacheSize;
308352
}
309353

354+
public Duration getSocketTimeout() {
355+
return socketTimeout;
356+
}
357+
358+
public boolean isTcpKeepAlive() {
359+
return tcpKeepAlive;
360+
}
361+
362+
public boolean isTcpAbortiveClose() {
363+
return tcpAbortiveClose;
364+
}
365+
310366
@Override
311367
public String toString() {
312368
StringBuilder hiddenPwd = new StringBuilder();
@@ -335,6 +391,12 @@ public String toString() {
335391
+ '\''
336392
+ ", connectTimeout="
337393
+ connectTimeout
394+
+ ", socketTimeout="
395+
+ socketTimeout
396+
+ ", tcpKeepAlive="
397+
+ tcpKeepAlive
398+
+ ", tcpAbortiveClose="
399+
+ tcpAbortiveClose
338400
+ ", password="
339401
+ hiddenPwd
340402
+ ", port="
@@ -386,6 +448,9 @@ public static final class Builder implements Cloneable {
386448
private boolean allowPublicKeyRetrieval;
387449
@Nullable private String username;
388450
@Nullable private Duration connectTimeout;
451+
@Nullable private Duration socketTimeout;
452+
@Nullable private Boolean tcpKeepAlive;
453+
@Nullable private Boolean tcpAbortiveClose;
389454
@Nullable private String database;
390455
@Nullable private String host;
391456
@Nullable private Map<String, String> sessionVariables;
@@ -429,6 +494,9 @@ public MariadbConnectionConfiguration build() {
429494

430495
return new MariadbConnectionConfiguration(
431496
this.connectTimeout,
497+
this.socketTimeout,
498+
this.tcpKeepAlive,
499+
this.tcpAbortiveClose,
432500
this.database,
433501
this.host,
434502
this.connectionAttributes,
@@ -464,6 +532,21 @@ public Builder connectTimeout(@Nullable Duration connectTimeout) {
464532
return this;
465533
}
466534

535+
public Builder socketTimeout(@Nullable Duration socketTimeout) {
536+
this.socketTimeout = socketTimeout;
537+
return this;
538+
}
539+
540+
public Builder tcpKeepAlive(@Nullable Boolean tcpKeepAlive) {
541+
this.tcpKeepAlive = tcpKeepAlive;
542+
return this;
543+
}
544+
545+
public Builder tcpAbortiveClose(@Nullable Boolean tcpAbortiveClose) {
546+
this.tcpAbortiveClose = tcpAbortiveClose;
547+
return this;
548+
}
549+
467550
public Builder connectionAttributes(@Nullable Map<String, String> connectionAttributes) {
468551
this.connectionAttributes = connectionAttributes;
469552
return this;
@@ -747,6 +830,12 @@ public String toString() {
747830
+ '\''
748831
+ ", connectTimeout="
749832
+ connectTimeout
833+
+ ", socketTimeout="
834+
+ socketTimeout
835+
+ ", tcpKeepAlive="
836+
+ tcpKeepAlive
837+
+ ", tcpAbortiveClose="
838+
+ tcpAbortiveClose
750839
+ ", database='"
751840
+ database
752841
+ '\''

src/main/java/org/mariadb/r2dbc/MariadbConnectionFactoryProvider.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import io.r2dbc.spi.ConnectionFactoryOptions;
2222
import io.r2dbc.spi.ConnectionFactoryProvider;
2323
import io.r2dbc.spi.Option;
24+
import java.time.Duration;
2425
import org.mariadb.r2dbc.util.Assert;
2526

2627
public final class MariadbConnectionFactoryProvider implements ConnectionFactoryProvider {
@@ -36,6 +37,9 @@ public final class MariadbConnectionFactoryProvider implements ConnectionFactory
3637
public static final Option<String> SSL_MODE = Option.valueOf("sslMode");
3738
public static final Option<String> CONNECTION_ATTRIBUTES = Option.valueOf("connectionAttributes");
3839
public static final Option<String> PAM_OTHER_PASSWORD = Option.valueOf("pamOtherPwd");
40+
public static final Option<Duration> SOCKET_TIMEOUT = Option.valueOf("socketTimeout");
41+
public static final Option<Boolean> TCP_KEEP_ALIVE = Option.valueOf("tcpKeepAlive");
42+
public static final Option<Boolean> TCP_ABORTIVE_CLOSE = Option.valueOf("tcpAbortiveClose");
3943

4044
static MariadbConnectionConfiguration createConfiguration(
4145
ConnectionFactoryOptions connectionFactoryOptions) {

src/main/java/org/mariadb/r2dbc/MariadbServerParameterizedQueryStatement.java

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,11 @@ private Flux<org.mariadb.r2dbc.api.MariadbResult> execute(
298298
} else {
299299
flux =
300300
sendPrepare(sql)
301-
.flatMapMany(prepareResult1 -> sendExecuteCmd(factory, parameters, generatedColumns));
301+
.flatMapMany(
302+
prepareResult1 -> {
303+
prepareResult = prepareResult1;
304+
return sendExecuteCmd(factory, parameters, generatedColumns);
305+
});
302306
}
303307
return flux.concatWith(
304308
Flux.create(
@@ -341,13 +345,6 @@ private Mono<ServerPrepareResult> sendPrepare(String sql) {
341345
prepareResult =
342346
new ServerPrepareResult(
343347
packet.getStatementId(), packet.getNumColumns(), packet.getNumParams());
344-
if (client.getPrepareCache() != null) {
345-
ServerPrepareResult res = client.getPrepareCache().get(sql);
346-
if (res != null && !res.equals(prepareResult)) {
347-
prepareResult.close(client);
348-
prepareResult = res;
349-
}
350-
}
351348
sink.next(prepareResult);
352349
}
353350
if (it.ending()) sink.complete();

src/main/java/org/mariadb/r2dbc/client/ClientBase.java

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package org.mariadb.r2dbc.client;
1818

1919
import io.netty.channel.Channel;
20+
import io.netty.channel.ChannelOption;
2021
import io.netty.handler.logging.LogLevel;
2122
import io.netty.handler.logging.LoggingHandler;
2223
import io.netty.handler.ssl.SslHandler;
@@ -43,6 +44,7 @@
4344
import reactor.core.publisher.Flux;
4445
import reactor.core.publisher.Mono;
4546
import reactor.netty.Connection;
47+
import reactor.netty.tcp.TcpClient;
4648
import reactor.util.Logger;
4749
import reactor.util.Loggers;
4850
import reactor.util.concurrent.Queues;
@@ -87,6 +89,32 @@ protected ClientBase(Connection connection, MariadbConnectionConfiguration confi
8789
.subscribe();
8890
}
8991

92+
public static TcpClient setSocketOption(
93+
MariadbConnectionConfiguration configuration, TcpClient tcpClient) {
94+
if (configuration.getConnectTimeout() != null) {
95+
tcpClient =
96+
tcpClient.option(
97+
ChannelOption.CONNECT_TIMEOUT_MILLIS,
98+
Math.toIntExact(configuration.getConnectTimeout().toMillis()));
99+
}
100+
101+
if (configuration.getSocketTimeout() != null) {
102+
tcpClient =
103+
tcpClient.option(
104+
ChannelOption.SO_TIMEOUT,
105+
Math.toIntExact(configuration.getSocketTimeout().toMillis()));
106+
}
107+
108+
if (configuration.isTcpKeepAlive()) {
109+
tcpClient = tcpClient.option(ChannelOption.SO_KEEPALIVE, configuration.isTcpKeepAlive());
110+
}
111+
112+
if (configuration.isTcpAbortiveClose()) {
113+
tcpClient = tcpClient.option(ChannelOption.SO_LINGER, 0);
114+
}
115+
return tcpClient;
116+
}
117+
90118
private void handleConnectionError(Throwable throwable) {
91119
R2dbcNonTransientResourceException err;
92120
if (this.isClosed.compareAndSet(false, true)) {
@@ -104,8 +132,6 @@ private void handleConnectionError(Throwable throwable) {
104132
public Mono<Void> close() {
105133
return Mono.defer(
106134
() -> {
107-
clearWaitingListWithError(
108-
new R2dbcNonTransientResourceException("Connection is closing"));
109135
if (this.isClosed.compareAndSet(false, true)) {
110136

111137
Channel channel = this.connection.channel();

src/main/java/org/mariadb/r2dbc/client/ClientImpl.java

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
package org.mariadb.r2dbc.client;
1818

19-
import io.netty.channel.ChannelOption;
2019
import io.r2dbc.spi.R2dbcNonTransientResourceException;
2120
import java.net.SocketAddress;
2221
import java.util.Queue;
@@ -47,12 +46,7 @@ public static Mono<Client> connect(
4746
MariadbConnectionConfiguration configuration) {
4847

4948
TcpClient tcpClient = TcpClient.create(connectionProvider).remoteAddress(() -> socketAddress);
50-
if (configuration.getConnectTimeout() != null) {
51-
tcpClient =
52-
tcpClient.option(
53-
ChannelOption.CONNECT_TIMEOUT_MILLIS,
54-
Math.toIntExact(configuration.getConnectTimeout().toMillis()));
55-
}
49+
tcpClient = setSocketOption(configuration, tcpClient);
5650
return tcpClient.connect().flatMap(it -> Mono.just(new ClientImpl(it, configuration)));
5751
}
5852

0 commit comments

Comments
 (0)