|
55 | 55 | import com.google.cloud.Tuple; |
56 | 56 | import com.google.cloud.grpc.GrpcTransportOptions; |
57 | 57 | import com.google.cloud.grpc.GrpcTransportOptions.ExecutorFactory; |
| 58 | +import com.google.cloud.spanner.AsyncResultSet.StreamMessageListener; |
58 | 59 | import com.google.cloud.spanner.Options.QueryOption; |
59 | 60 | import com.google.cloud.spanner.Options.ReadOption; |
60 | 61 | import com.google.cloud.spanner.Options.TransactionOption; |
@@ -266,6 +267,55 @@ private ResultSet wrap(final CachedResultSetSupplier resultSetSupplier) { |
266 | 267 | return new ForwardingResultSet(resultSetSupplier) { |
267 | 268 | private boolean beforeFirst = true; |
268 | 269 |
|
| 270 | + @Override |
| 271 | + public boolean initiateStreaming(StreamMessageListener streamMessageListener) { |
| 272 | + while (true) { |
| 273 | + try { |
| 274 | + return internalInitiateStreaming(streamMessageListener); |
| 275 | + } catch (SessionNotFoundException e) { |
| 276 | + while (true) { |
| 277 | + // Keep the replace-if-possible outside the try-block to let the exception bubble up |
| 278 | + // if it's too late to replace the session. |
| 279 | + replaceSessionIfPossible(e); |
| 280 | + try { |
| 281 | + replaceDelegate(resultSetSupplier.reload()); |
| 282 | + break; |
| 283 | + } catch (SessionNotFoundException snfe) { |
| 284 | + e = snfe; |
| 285 | + // retry on yet another session. |
| 286 | + } |
| 287 | + } |
| 288 | + } |
| 289 | + } |
| 290 | + } |
| 291 | + |
| 292 | + private boolean internalInitiateStreaming(final StreamMessageListener streamMessageListener) { |
| 293 | + try { |
| 294 | + boolean ret = super.initiateStreaming(streamMessageListener); |
| 295 | + if (beforeFirst) { |
| 296 | + synchronized (lock) { |
| 297 | + session.get().markUsed(); |
| 298 | + beforeFirst = false; |
| 299 | + sessionUsedForQuery = true; |
| 300 | + } |
| 301 | + } |
| 302 | + if (!ret && isSingleUse) { |
| 303 | + close(); |
| 304 | + } |
| 305 | + return ret; |
| 306 | + } catch (SessionNotFoundException e) { |
| 307 | + throw e; |
| 308 | + } catch (SpannerException e) { |
| 309 | + synchronized (lock) { |
| 310 | + if (!closed && isSingleUse) { |
| 311 | + session.get().setLastException(e); |
| 312 | + AutoClosingReadContext.this.close(); |
| 313 | + } |
| 314 | + } |
| 315 | + throw e; |
| 316 | + } |
| 317 | + } |
| 318 | + |
269 | 319 | @Override |
270 | 320 | public boolean next() throws SpannerException { |
271 | 321 | while (true) { |
|
0 commit comments