Как синхронно обновить токен доступа с проектным реактором - PullRequest
0 голосов
/ 29 мая 2019

Я получаю доступ к внешнему API для отдыха, который защищен с помощью OpenID connect.Я должен запустить работу, которая вызывает API несколько раз, прежде чем он завершится.Это задание может выполняться параллельно с использованием нескольких параллельных потоков.Таким образом, я использую сервис для доступа к API, который создается для каждого задания:

private AccessAndRefresTokens tokens; // I initially get that from somewhere else

public Mono<Result> callTheApi(){
  return createWebClientWith(tokens.accessToken).executeRequest();
}

public Mono<Result> callOtherApiFunction(){
  return createWebClientWith(tokens.accessToken).executeRequest();
}

public Mono<Result> callYetAnotherApiFunction(){
  return createWebClientWith(tokens.accessToken).executeRequest();
}

Когда мое задание выполняется, может случиться, что токен доступа истекает между двумя вызовами API.Чтобы этого не происходило, я хотел бы проверять действительность токена доступа перед каждым запросом и обновлять его при необходимости.

Моя первая идея состояла в том, чтобы проверить правильность внутри оператора flatMap:

Mono.just(tokens).flatMap(tokens -> {
  if(accessTokenExpired){
    return refreshAccessToken().doOnNext(refreshedTokens -> tokens = refreshedTokens);
  }else{
    return Mono.just(tokens.accessToken);
  }
}).flatMap(accessToken -> createWebClientWith(accessToken));

Однако мне кажется, что это вызовет обновление несколько раз, если несколько потоков обращаются к службе, и обновление еще не завершено.Как следствие, я бы закончил тем, что обновил токен доступа несколько раз за очень короткое время, которое могло бы потерпеть неудачу из-за ограничений скорости.не желаемый вариант.Поэтому я попытался что-то выяснить, используя реактор Processor, но я не смог найти удовлетворительное решение.

Так есть ли способ гарантировать, что маркер доступа передается только один раз?И как мне добиться этого без использования кода блокировки?

...