Reputation: 13080
I have a webhook service that sends events to different sources (URLs). By design, the request timeout is 10s, if it fails, retries to send 3 times. In case, all retries are failed, a code must be executed to disable that URL in DB.
So far, I managed to retry and with delay of 5 seconds. But, I'm not sure how to execute code after failure.
try{
String body = objectMapper.writeValueAsString(webhookDTO);
webClient.post()
.uri(webhook.getUrl())
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(body)
.exchange()
.timeout(Duration.ofSeconds(5))
.retryWhen(Retry.backoff(3, Duration.ofSeconds(5))
.jitter(0d)
.doAfterRetry(retrySignal -> {
logger.info("Retried " + retrySignal.totalRetries());
})
.onRetryExhaustedThrow((retryBackoffSpec, retrySignal)
-> new WebhookTimeoutException()))
.doOnSuccess(clientResponse -> {
logger.info("Event is received by " + client);
})
.subscribe();
} catch (Exception e) {
logger.error("Error on webhook dispatcher: ", e);
}
Can anyone give some examples of how to do this?
Upvotes: 8
Views: 18387
Reputation: 15370
You are almost there! Just use doOnError
as shown here. The idea here, once after all the attempts failed, you throw WebhookTimeoutException
. The doOnError is called only when the error is thrown & updates the DB. The exception class is optional. You can ignore that.
webClient.post()
.uri(webhook.getUrl())
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(body)
.exchange()
.timeout(Duration.ofSeconds(5))
.retryWhen(Retry.backoff(3, Duration.ofSeconds(5))
.jitter(0d)
.doAfterRetry(retrySignal -> {
logger.info("Retried " + retrySignal.totalRetries());
})
.onRetryExhaustedThrow((retryBackoffSpec, retrySignal)
-> new WebhookTimeoutException()))
.doOnSuccess(clientResponse -> {
logger.info("Event is received by " + client);
})
.doOnError(WebhookTimeoutException.class, (msg) -> {
System.out.println("Message :: " + msg);
// here update the DB
dbRepository.save(...);
})
.subscribe();
Upvotes: 8