3

I am trying to synchronize a resource with spring webClient:

this.semaphore.acquire()
webClient
    .post()
    .uri("/a")
    .bodyValue(payload)
    .retrieve()
    .bodyToMono(String.class)    
    // release
    .doFinally(st -> this.semaphore.release())
    .switchIfEmpty(Mono.just("a"))
    .onErrorResume(Exception.class, e -> Mono.empty())
    .doOnNext()
    .subscribe();

Is doFinally sufficient to handle the release? If not, what are the "escape" points?

1 Answers1

0

This will clean up your resources if your mono is cancelled, completes, or errors out, which are all the ways in which a mono can end.

However, a Mono does not necessarily have to end and the doFinally hook will not be executed.

So it depends on how your webClient is configured in cases where the external api fails to respond: Normally, there should be a timeout and a maximum number of retries. In that case, your code should be correct.

NOTE: the release may not happen on the same thread as the acquire. Depending on the resource, this might actually be a problem. For example, a ReentrantReadWriteLock has semantics that it is owned by the thread that created it. I do not know if this problem exists with your semaphore.

julaine
  • 382
  • 3
  • 12