17
17
package io .asyncer .r2dbc .mysql ;
18
18
19
19
import io .asyncer .r2dbc .mysql .client .Client ;
20
+ import io .asyncer .r2dbc .mysql .client .ReactorNettyClient ;
20
21
import io .asyncer .r2dbc .mysql .internal .util .StringUtils ;
21
22
import io .netty .channel .ChannelOption ;
22
23
import io .netty .resolver .AddressResolver ;
26
27
import io .netty .util .concurrent .EventExecutor ;
27
28
import io .netty .util .internal .logging .InternalLogger ;
28
29
import io .netty .util .internal .logging .InternalLoggerFactory ;
30
+ import io .r2dbc .spi .R2dbcNonTransientResourceException ;
31
+ import org .jetbrains .annotations .Nullable ;
29
32
import reactor .core .publisher .Mono ;
30
33
import reactor .netty .resources .LoopResources ;
31
34
import reactor .netty .tcp .TcpClient ;
32
35
33
36
import java .net .InetSocketAddress ;
34
37
import java .time .Duration ;
35
38
import java .time .ZoneId ;
39
+ import java .util .function .Function ;
40
+ import java .util .function .Supplier ;
36
41
37
42
/**
38
43
* An interface of a connection strategy that considers how to obtain a MySQL {@link Client} object.
@@ -49,7 +54,7 @@ interface ConnectionStrategy {
49
54
*
50
55
* @return a logged-in {@link Client} object.
51
56
*/
52
- Mono <Client > connect ();
57
+ Mono <? extends Client > connect ();
53
58
54
59
/**
55
60
* Creates a general-purpose {@link TcpClient} with the given {@link SocketClientConfiguration}.
@@ -87,7 +92,7 @@ static TcpClient createTcpClient(SocketClientConfiguration configuration, boolea
87
92
* @param configuration a configuration that affects login behavior.
88
93
* @return a logged-in {@link Client} object.
89
94
*/
90
- static Mono <Client > connectWithInit (
95
+ static Mono <ReactorNettyClient > connectWithInit (
91
96
TcpClient tcpClient ,
92
97
Credential credential ,
93
98
MySqlConnectionConfiguration configuration
@@ -110,7 +115,7 @@ static Mono<Client> connectWithInit(
110
115
configuration .isPreserveInstants (),
111
116
connectionTimeZone
112
117
);
113
- }).flatMap (context -> Client .connect (tcpClient , configuration .getSsl (), context )).flatMap (client -> {
118
+ }).flatMap (ctx -> ReactorNettyClient .connect (tcpClient , configuration .getSsl (), ctx )).flatMap (client -> {
114
119
// Lazy init database after handshake/login
115
120
MySqlSslConfiguration ssl = configuration .getSsl ();
116
121
String loginDb = configuration .isCreateDatabaseIfNotExist () ? "" : configuration .getDatabase ();
@@ -126,30 +131,88 @@ static Mono<Client> connectWithInit(
126
131
).then (Mono .just (client )).onErrorResume (e -> client .forceClose ().then (Mono .error (e )));
127
132
});
128
133
}
129
- }
130
-
131
- /**
132
- * Resolves the {@link InetSocketAddress} to IP address, randomly pick one if it resolves to multiple IP addresses.
133
- *
134
- * @since 1.2.0
135
- */
136
- final class BalancedResolverGroup extends AddressResolverGroup <InetSocketAddress > {
137
134
138
- BalancedResolverGroup () {
135
+ /**
136
+ * Creates an exception that indicates a retry failure.
137
+ *
138
+ * @param message the message of the exception.
139
+ * @param cause the last exception that caused the retry.
140
+ * @return a retry failure exception.
141
+ */
142
+ static R2dbcNonTransientResourceException retryFail (String message , @ Nullable Throwable cause ) {
143
+ return new R2dbcNonTransientResourceException (
144
+ message ,
145
+ "H1000" ,
146
+ 9000 ,
147
+ cause
148
+ );
139
149
}
140
150
141
- public static final BalancedResolverGroup INSTANCE ;
151
+ /**
152
+ * Connect and login to a MySQL server with a specific TCP socket address.
153
+ *
154
+ * @since 1.2.0
155
+ */
156
+ final class InetConnectFunction implements Function <Supplier <InetSocketAddress >, Mono <ReactorNettyClient >> {
157
+
158
+ private final boolean balancedDns ;
159
+
160
+ private final boolean tcpKeepAlive ;
161
+
162
+ private final boolean tcpNoDelay ;
163
+
164
+ private final Credential credential ;
142
165
143
- static {
144
- INSTANCE = new BalancedResolverGroup ();
145
- Runtime .getRuntime ().addShutdownHook (new Thread (
146
- INSTANCE ::close ,
147
- "R2DBC-MySQL-BalancedResolverGroup-ShutdownHook"
148
- ));
166
+ private final MySqlConnectionConfiguration configuration ;
167
+
168
+ InetConnectFunction (
169
+ boolean balancedDns ,
170
+ boolean tcpKeepAlive ,
171
+ boolean tcpNoDelay ,
172
+ Credential credential ,
173
+ MySqlConnectionConfiguration configuration
174
+ ) {
175
+ this .balancedDns = balancedDns ;
176
+ this .tcpKeepAlive = tcpKeepAlive ;
177
+ this .tcpNoDelay = tcpNoDelay ;
178
+ this .credential = credential ;
179
+ this .configuration = configuration ;
180
+ }
181
+
182
+ @ Override
183
+ public Mono <ReactorNettyClient > apply (Supplier <InetSocketAddress > address ) {
184
+ TcpClient client = ConnectionStrategy .createTcpClient (configuration .getClient (), balancedDns )
185
+ .option (ChannelOption .SO_KEEPALIVE , tcpKeepAlive )
186
+ .option (ChannelOption .TCP_NODELAY , tcpNoDelay )
187
+ .remoteAddress (address );
188
+
189
+ return ConnectionStrategy .connectWithInit (client , credential , configuration );
190
+ }
149
191
}
150
192
151
- @ Override
152
- protected AddressResolver <InetSocketAddress > newResolver (EventExecutor executor ) {
153
- return new RoundRobinInetAddressResolver (executor , new DefaultNameResolver (executor )).asAddressResolver ();
193
+ /**
194
+ * Resolves the {@link InetSocketAddress} to IP address, randomly pick one if it resolves to multiple IP addresses.
195
+ *
196
+ * @since 1.2.0
197
+ */
198
+ final class BalancedResolverGroup extends AddressResolverGroup <InetSocketAddress > {
199
+
200
+ BalancedResolverGroup () {
201
+ }
202
+
203
+ public static final BalancedResolverGroup INSTANCE ;
204
+
205
+ static {
206
+ INSTANCE = new BalancedResolverGroup ();
207
+ Runtime .getRuntime ().addShutdownHook (new Thread (
208
+ INSTANCE ::close ,
209
+ "R2DBC-MySQL-BalancedResolverGroup-ShutdownHook"
210
+ ));
211
+ }
212
+
213
+ @ Override
214
+ protected AddressResolver <InetSocketAddress > newResolver (EventExecutor executor ) {
215
+ return new RoundRobinInetAddressResolver (executor , new DefaultNameResolver (executor )).asAddressResolver ();
216
+ }
154
217
}
155
218
}
0 commit comments