Java get request unable to retry indefinitely

I’m trying to indefinitely retry a get request using a custom RetryStrategy like this:

	Flux.just(1, 2, 3)
			.flatMap(i -> bucket.reactive().defaultCollection().get(String.valueOf(i), GetOptions.getOptions().retryStrategy((request, reason) -> {
				System.out.println("Retry");
				return CompletableFuture.completedFuture(RetryAction.withDuration(Duration.ZERO));
			})))
			.collectList()
			.block();

I see a bunch of “Retry” messages printed out but then after a while I get error

Exception in thread "main" com.couchbase.client.core.error.UnambiguousTimeoutException: GetRequest, Reason: TIMEOUT {"cancelled":true,"completed":true,"coreId":"0xd35b95e100000001","idempotent":true,"reason":"TIMEOUT","requestId":2,"requestType":"GetRequest","retried":224,"retryReasons":["BUCKET_OPEN_IN_PROGRESS"],"service":{"bucket":"test","collection":"_default","documentId":"2","opaque":"0x1","scope":"_default","type":"kv","vbucket":0},"timeoutMs":2500,"timings":{"totalMicros":2515363}}
	at com.couchbase.client.core.msg.BaseRequest.cancel(BaseRequest.java:184)
	at com.couchbase.client.core.msg.Request.cancel(Request.java:70)
	at com.couchbase.client.core.Timer.lambda$register$2(Timer.java:157)
	at com.couchbase.client.core.deps.io.netty.util.HashedWheelTimer$HashedWheelTimeout.run(HashedWheelTimer.java:715)
	at com.couchbase.client.core.deps.io.netty.util.concurrent.ImmediateExecutor.execute(ImmediateExecutor.java:34)
	at com.couchbase.client.core.deps.io.netty.util.HashedWheelTimer$HashedWheelTimeout.expire(HashedWheelTimer.java:703)
	at com.couchbase.client.core.deps.io.netty.util.HashedWheelTimer$HashedWheelBucket.expireTimeouts(HashedWheelTimer.java:790)
	at com.couchbase.client.core.deps.io.netty.util.HashedWheelTimer$Worker.run(HashedWheelTimer.java:503)
	at com.couchbase.client.core.deps.io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
	at java.base/java.lang.Thread.run(Thread.java:829)
	Suppressed: java.lang.Exception: #block terminated with an error
		at reactor.core.publisher.BlockingSingleSubscriber.blockingGet(BlockingSingleSubscriber.java:99)
		at reactor.core.publisher.Mono.block(Mono.java:1707)

Shouldn’t the RetryStrategy prevent this from happening?

@mico.piira I think you are mixing up two things: the operation timeout and the retry strategy. The operation timeout tells how long an operation should be allowed to take (including retries), and the retry strategy defines if and how the request should be retried.

Note that this only accounts for retries BEFORE the operation is complete. Once the operation is complete (and it failed), you want to use reactors reactive retry operators to retry the whole thing.

If you let me know what you are trying to achieve maybe I can help you with a proper solution.

Alright, I just saw some get requests timeouting in logs and the errors said “retries: 0”.

I thought the Java SDK would by default retry in such situations. I guess I will then have to use the reactor retry operator everywhere in my codebase or increase my timeouts.

Correct - the SDK will only retry what it can to drive an individual operation to completion with the best effort strategy. Once the op is complete, then it’s up to you to decide what to do (retry, fail, do something else), since every app has different needs.