Как отправить данные из обратного вызова в сопрограмму Kotlin? - PullRequest
0 голосов
/ 12 ноября 2018

Предположим, я хочу использовать кеш в DownloadQueue подобном примере.Радость сопрограмм заключается в том, что простая структура данных (например, HashMap) может использоваться в однопоточном алгоритме.

Однако я хочу использовать ограниченный кэш и исключать дополнительные записи в более медленное постоянное хранилище.,Например, я могу взять Guava + CacheBuilder + RemovalListener: https://github.com/google/guava/wiki/CachesExplained#removal-listeners

Вот проблема: RemovalListener - это не приостановленный обратный вызов, поэтому нет способа отправить данные в Channels или что-то еще из обратного вызова.

// This is placed in a suspend context (e.g. within `actor`)
val cache = CacheBuilder.newBuilder().maximumSize(1000)
    .expireAfterWrite(10, TimeUnit.SECONDS)
    .removalListener<Key, Value> { n ->
        expireChannel.sendBlocking(n.value!!) // <-- could sendBlocking be used here???
    }.build<Key, Value>()

Насколько я понимаю, runBlocking блокирует выполнение текущего потока, таким образом, он блокирует текущую сопрограмму и не сможет получить /обрабатывать данные.

Есть ли способ сделать RemovalListener -подобные обратные вызовы дружественными к сопрограммам?

Я могу представить себе обходной путь использования неограниченной очереди, заполненной RemovalListenerв то время как рассматриваемая сопрограмма в конечном итоге проверяет очередь.

1 Ответ

0 голосов
/ 12 ноября 2018

Единственный способ не блокировать прослушиватель удаления (и, следовательно, сломать кеш) - это иметь буферизованный канал.Это означает два изменения:

  1. Создайте SendChannel с ненулевой емкостью, см. Channel(capacity), чтобы рассмотреть различные варианты поведения.В основном это зависит от того, каким должно быть поведение, если истекает больше элементов, чем может обработать потребитель.
  2. Используйте SendChannel.offer() вместо SendChannel.sendBlocking().Если он возвращает false, вы можете реализовать поведение резервного копирования, такое как регистрация ошибки, чтобы вы могли выяснить, каков наилучший баланс между памятью и потерянными событиями.
...