|
45 | 45 | /** |
46 | 46 | * ManagedChannel that routes eligible requests using location-aware routing hints. |
47 | 47 | * |
48 | | - * <p>Routing is applied only to streaming read and streaming query methods. |
| 48 | + * <p>Routing hints are applied to streaming read/query and unary ExecuteSql. Commit/Rollback use |
| 49 | + * transaction affinity when available. BeginTransaction is routed only when a mutation key is |
| 50 | + * provided. |
49 | 51 | */ |
50 | 52 | @InternalApi |
51 | 53 | final class KeyAwareChannel extends ManagedChannel { |
@@ -80,11 +82,6 @@ private KeyAwareChannel( |
80 | 82 | this.authority = this.defaultChannel.authority(); |
81 | 83 | } |
82 | 84 |
|
83 | | - static KeyAwareChannel create(InstantiatingGrpcChannelProvider channelProvider) |
84 | | - throws IOException { |
85 | | - return new KeyAwareChannel(channelProvider, null); |
86 | | - } |
87 | | - |
88 | 85 | static KeyAwareChannel create( |
89 | 86 | InstantiatingGrpcChannelProvider channelProvider, |
90 | 87 | @Nullable ChannelEndpointCacheFactory endpointCacheFactory) |
@@ -281,29 +278,15 @@ public void sendMessage(RequestT message) { |
281 | 278 |
|
282 | 279 | if (message instanceof ReadRequest) { |
283 | 280 | ReadRequest.Builder reqBuilder = ((ReadRequest) message).toBuilder(); |
284 | | - String databaseId = parentChannel.extractDatabaseIdFromSession(reqBuilder.getSession()); |
285 | | - ByteString transactionId = transactionIdFromSelector(reqBuilder.getTransaction()); |
286 | | - endpoint = parentChannel.affinityEndpoint(transactionId); |
287 | | - if (databaseId != null) { |
288 | | - finder = parentChannel.getOrCreateChannelFinder(databaseId); |
289 | | - ChannelEndpoint routed = finder.findServer(reqBuilder); |
290 | | - if (endpoint == null) { |
291 | | - endpoint = routed; |
292 | | - } |
293 | | - } |
| 281 | + RoutingDecision routing = routeFromRequest(reqBuilder); |
| 282 | + finder = routing.finder; |
| 283 | + endpoint = routing.endpoint; |
294 | 284 | message = (RequestT) reqBuilder.build(); |
295 | 285 | } else if (message instanceof ExecuteSqlRequest) { |
296 | 286 | ExecuteSqlRequest.Builder reqBuilder = ((ExecuteSqlRequest) message).toBuilder(); |
297 | | - String databaseId = parentChannel.extractDatabaseIdFromSession(reqBuilder.getSession()); |
298 | | - ByteString transactionId = transactionIdFromSelector(reqBuilder.getTransaction()); |
299 | | - endpoint = parentChannel.affinityEndpoint(transactionId); |
300 | | - if (databaseId != null) { |
301 | | - finder = parentChannel.getOrCreateChannelFinder(databaseId); |
302 | | - ChannelEndpoint routed = finder.findServer(reqBuilder); |
303 | | - if (endpoint == null) { |
304 | | - endpoint = routed; |
305 | | - } |
306 | | - } |
| 287 | + RoutingDecision routing = routeFromRequest(reqBuilder); |
| 288 | + finder = routing.finder; |
| 289 | + endpoint = routing.endpoint; |
307 | 290 | message = (RequestT) reqBuilder.build(); |
308 | 291 | } else if (message instanceof BeginTransactionRequest) { |
309 | 292 | BeginTransactionRequest.Builder reqBuilder = |
@@ -373,6 +356,46 @@ void maybeRecordAffinity(ByteString transactionId) { |
373 | 356 | void maybeClearAffinity() { |
374 | 357 | parentChannel.clearAffinity(transactionIdToClear); |
375 | 358 | } |
| 359 | + |
| 360 | + private RoutingDecision routeFromRequest(ReadRequest.Builder reqBuilder) { |
| 361 | + String databaseId = parentChannel.extractDatabaseIdFromSession(reqBuilder.getSession()); |
| 362 | + ByteString transactionId = transactionIdFromSelector(reqBuilder.getTransaction()); |
| 363 | + ChannelEndpoint endpoint = parentChannel.affinityEndpoint(transactionId); |
| 364 | + ChannelFinder finder = null; |
| 365 | + if (databaseId != null) { |
| 366 | + finder = parentChannel.getOrCreateChannelFinder(databaseId); |
| 367 | + ChannelEndpoint routed = finder.findServer(reqBuilder); |
| 368 | + if (endpoint == null) { |
| 369 | + endpoint = routed; |
| 370 | + } |
| 371 | + } |
| 372 | + return new RoutingDecision(finder, endpoint); |
| 373 | + } |
| 374 | + |
| 375 | + private RoutingDecision routeFromRequest(ExecuteSqlRequest.Builder reqBuilder) { |
| 376 | + String databaseId = parentChannel.extractDatabaseIdFromSession(reqBuilder.getSession()); |
| 377 | + ByteString transactionId = transactionIdFromSelector(reqBuilder.getTransaction()); |
| 378 | + ChannelEndpoint endpoint = parentChannel.affinityEndpoint(transactionId); |
| 379 | + ChannelFinder finder = null; |
| 380 | + if (databaseId != null) { |
| 381 | + finder = parentChannel.getOrCreateChannelFinder(databaseId); |
| 382 | + ChannelEndpoint routed = finder.findServer(reqBuilder); |
| 383 | + if (endpoint == null) { |
| 384 | + endpoint = routed; |
| 385 | + } |
| 386 | + } |
| 387 | + return new RoutingDecision(finder, endpoint); |
| 388 | + } |
| 389 | + } |
| 390 | + |
| 391 | + private static final class RoutingDecision { |
| 392 | + @Nullable private final ChannelFinder finder; |
| 393 | + @Nullable private final ChannelEndpoint endpoint; |
| 394 | + |
| 395 | + private RoutingDecision(@Nullable ChannelFinder finder, @Nullable ChannelEndpoint endpoint) { |
| 396 | + this.finder = finder; |
| 397 | + this.endpoint = endpoint; |
| 398 | + } |
376 | 399 | } |
377 | 400 |
|
378 | 401 | static final class KeyAwareClientCallListener<ResponseT> |
|
0 commit comments