Как использовать Spring Boot Webflux + Localization (MessageSource) + Caffeine cache? - PullRequest
0 голосов
/ 05 мая 2020

У меня есть внешняя служба, которая возвращает значения локализации для ключа сообщения локализации. Я использую Spring webflux Webclient для получения результата. Результат сохраняется в кеш-памяти кофеина. Затем этот результат помещается в Spring Message Source, который используется во всем проекте для выполнения разрешения локализации.

Я вызываю внешнюю службу с помощью WebClient, и у нее есть подпись метода ниже:

interface Requestor {

    Mono<Map<Locale, String>> execute(final String key);

}

Затем я использую Caffeine AsyncLoadingCache, который возвращает CompletableFuture

public class MyCacheLoader<K, V> implements AsyncCacheLoader<K, V> {

    private final Requestor<K, V> requestor;

    public MyCacheLoader(Requestor<K, V> requestor) {
        this.requestor = requestor;
    }

    @Override
    public CompletableFuture<V> asyncLoad(K cacheKey, Executor executor) {
        return requestor.execute(cacheKey).toFuture();
    }

    @Override
    public CompletableFuture<Map<K, V>> asyncLoadAll(Iterable<? extends K> keys, Executor executor) {
        // similar implementation as above method
    }
}

. Я хочу использовать MessageSource из Spring для нестандартной обработки локализации. Итак, я использую, как показано ниже:

public class MyMessageSource extends AbstractMessageSource {

    @Override
    protected MessageFormat resolveCode(String messageKey, Locale locale) {
        var message = adapter.getMessage(messageKey, locale);
        return new MessageFormat(message == null ? messageKey : message, locale);
    }
}

Чтобы использовать MessageSource, я должен сделать блокировку Mono, как показано ниже:

public class Adapter {
     public String getMessage(String messageKey, Locale locale) {
           return localizationClient.getMessage(messageKey, locale)
                    .subscribeOn(Schedulers.boundedElastic())
                    .toProcessor()
                    .log()
                    .block();
         }
}

Это возвращается в исключении ниже:

java.lang.IllegalStateException: block()/blockFirst()/blockLast() are blocking, which is not supported in thread reactor-http-nio-1
    at reactor.core.publisher.BlockingSingleSubscriber.blockingGet(BlockingSingleSubscriber.java:83)
    at reactor.core.publisher.Mono.block(Mono.java:1666)

Кроме того, мне пришлось разрешить ключи локализации во многих местах проекта, поэтому возвращение Mono повсюду и сжатие ответов загромождают код. Есть идеи, как я могу использовать MessageSource без блокировки Mono?

...