diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Options.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Options.java index 9771e2173f1..27ff846f67b 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Options.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/Options.java @@ -1088,12 +1088,20 @@ void appendToOptions(Options options) { @Override public int hashCode() { - return RequestIdOption.class.hashCode(); + return this.reqId.hashCode(); } @Override public boolean equals(Object o) { - return o instanceof RequestIdOption; + // instanceof for a null object returns false. + if (!(o instanceof RequestIdOption)) { + return false; + } + RequestIdOption other = (RequestIdOption) o; + if (this.reqId == null || other.reqId == null) { + return this.reqId == null && other.reqId == null; + } + return this.reqId.equals(other.reqId); } } } diff --git a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SessionImpl.java b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SessionImpl.java index c78cfaeea3f..e206eaa4250 100644 --- a/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SessionImpl.java +++ b/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SessionImpl.java @@ -319,7 +319,7 @@ public CommitResponse writeAtLeastOnceWithOptions( private XGoogSpannerRequestId reqIdOrFresh(Options options) { XGoogSpannerRequestId reqId = options.reqId(); if (reqId == null) { - reqId = this.getRequestIdCreator().nextRequestId(1 /* TODO: channelId */, 1); + reqId = this.getRequestIdCreator().nextRequestId(this.getChannel(), 1); } return reqId; } @@ -464,8 +464,7 @@ public AsyncTransactionManagerImpl transactionManagerAsync(TransactionOption... @Override public ApiFuture asyncClose() { - XGoogSpannerRequestId reqId = - this.getRequestIdCreator().nextRequestId(1 /* TODO: channelId */, 0); + XGoogSpannerRequestId reqId = this.getRequestIdCreator().nextRequestId(this.getChannel(), 0); return spanner.getRpc().asyncDeleteSession(getName(), reqId.withOptions(getOptions())); } @@ -473,8 +472,7 @@ public ApiFuture asyncClose() { public void close() { ISpan span = tracer.spanBuilder(SpannerImpl.DELETE_SESSION); try (IScope s = tracer.withSpan(span)) { - XGoogSpannerRequestId reqId = - this.getRequestIdCreator().nextRequestId(1 /* TODO: channelId */, 0); + XGoogSpannerRequestId reqId = this.getRequestIdCreator().nextRequestId(this.getChannel(), 0); spanner.getRpc().deleteSession(getName(), reqId.withOptions(getOptions())); } catch (RuntimeException e) { span.setStatus(e); @@ -505,8 +503,7 @@ ApiFuture beginTransactionAsync( } final BeginTransactionRequest request = requestBuilder.build(); final ApiFuture requestFuture; - XGoogSpannerRequestId reqId = - this.getRequestIdCreator().nextRequestId(1 /* TODO: channelId */, 1); + XGoogSpannerRequestId reqId = this.getRequestIdCreator().nextRequestId(this.getChannel(), 1); try (IScope ignore = tracer.withSpan(span)) { requestFuture = spanner @@ -597,4 +594,12 @@ public void setRequestIdCreator(XGoogSpannerRequestId.RequestIdCreator creator) public XGoogSpannerRequestId.RequestIdCreator getRequestIdCreator() { return this.requestIdCreator; } + + int getChannel() { + if (getIsMultiplexed()) { + return 0; + } + Long channelHint = (Long) this.getOptions().get(SpannerRpc.Option.CHANNEL_HINT); + return (int) (channelHint % this.spanner.getOptions().getNumChannels()); + } } diff --git a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/OptionsTest.java b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/OptionsTest.java index f8b5304a706..67a2adf1231 100644 --- a/google-cloud-spanner/src/test/java/com/google/cloud/spanner/OptionsTest.java +++ b/google-cloud-spanner/src/test/java/com/google/cloud/spanner/OptionsTest.java @@ -900,6 +900,22 @@ public void testRequestId() { assertThat(option3.toString()).doesNotContain("requestId"); } + @Test + public void testRequestIdOptionEqualsAndHashCode() { + XGoogSpannerRequestId reqId1 = XGoogSpannerRequestId.of(1, 2, 3, 4); + XGoogSpannerRequestId reqId2 = XGoogSpannerRequestId.of(2, 3, 4, 5); + Options.RequestIdOption opt1 = Options.requestId(reqId1); + Options.RequestIdOption opt1Prime = Options.requestId(reqId1); + Options.RequestIdOption opt2 = Options.requestId(reqId2); + + assertTrue(opt1.equals(opt1)); + assertTrue(opt1.equals(opt1Prime)); + assertEquals(opt1.hashCode(), opt1Prime.hashCode()); + assertFalse(opt1.equals(opt2)); + assertNotEquals(opt1, opt2); + assertNotEquals(opt1.hashCode(), opt2.hashCode()); + } + @Test public void testOptions_WithMultipleDifferentRequestIds() { XGoogSpannerRequestId reqId1 = XGoogSpannerRequestId.of(1, 1, 1, 1);