Как кэшировать реактивного издателя, такого как Observable?

Я пытаюсь понять, что произойдет, если я кеширую результат метода, возвращающего холодный Observable? Поток еще не материализовался, так что же на самом деле содержит кеш? Я пытался выяснить это с помощью Hazelcast и Spring Boot, но не смог заставить кеш работать.

Изменить: когда я говорю, что кеш не работает, я говорю о том, что вижу в Центре управления Hazelcast. В зависимости от конфигурации кеша (я пробовал много вещей), либо кеш отображается, но нет записей, либо кеш не отображается вообще.

Пример:

@javax.cache.annotation.CacheResult
Observable<Integer> random() {
    // Do I get a new number every time?
    return Observable.just(new Random().nextInt());
}

person Abhijit Sarkar    schedule 21.02.2017    source источник
comment
Что значит не удалось заставить работать кеш?   -  person Enigmativity    schedule 21.02.2017
comment
@Enigmativity См. редактирование.   -  person Abhijit Sarkar    schedule 22.02.2017


Ответы (1)


Из вики rx-java (источник здесь):

Холодный Observable испускает определенную последовательность элементов, но может начать испускать эту последовательность, когда его наблюдатель сочтет это удобным, и с любой скоростью, которую желает наблюдатель, не нарушая целостность последовательности. Например, если вы преобразуете статический Iterable в Observable, этот Observable будет выдавать одну и ту же последовательность элементов независимо от того, когда он позже подписывается или как часто эти элементы наблюдаются. Примеры элементов, испускаемых холодным Observable, могут включать результаты запроса к базе данных, поиска файлов или веб-запроса.

С холодным Observable, как и в вашем примере, запрос выполняется во время подписки для каждого подписчика. Даже без кеша, если вы дважды подпишитесь на один и тот же Observable, запрос будет выполнен дважды. Observable не привязан к конкретному потоку. Observable — это просто контракт, описывающий, как получить доступ к данным.

Кэширование результата метода, возвращающего Observable, я думаю, несколько похоже на сохранение результата в локальном свойстве; вы просто избегаете повторного создания объекта Observable позже. Но только «геттер», а не данные.

rx-java предоставляет некоторые инструменты для самостоятельного кэширования. Вы можете посмотреть Subject или ConnectableObservable.

person Geoffrey Marizy    schedule 21.02.2017
comment
Итак, суть вашего ответа в том, что Observable нельзя кэшировать традиционными методами. Я правильно понял? - person Abhijit Sarkar; 22.02.2017
comment
Я не знаю всех этих методов, но большинство из них будут кэшировать Observable, но не поток, проходящий через него, да. - person Geoffrey Marizy; 22.02.2017
comment
@AbhijitSarkar - наблюдаемое может быть кэшировано обычным образом, но наблюдаемое не совпадает со значениями, создаваемыми наблюдаемым. Это происходит только тогда, когда у вас есть наблюдатель и подписка. - person Enigmativity; 22.02.2017
comment
Я ценю ответ и, следовательно, проголосовал за него, но он не дал мне ничего, чего я еще не знал. Различные методы cache* в Observable в основном воспроизводят последовательность, а в RxJava 1.x даже нет TTL (реактор проекта есть). Также нет понятия ключа; как я уже сказал, это, по сути, воспроизведение последовательности, а не то, что делает традиционное кэширование на основе ключей и TTL. - person Abhijit Sarkar; 23.02.2017