Мне известно несколько подходов к этой проблеме, подозреваю, что неизвестно больше:
1) Корутины. И producer и consumer живут в одном потоке, а значит реализовать, скажем, неблокирующий прелоад или гц ресурсов нельзя.
2) Iteratees, pipes и ещё десяток подобных библиотек. Более примитивны во всех смыслах, за исключением, может, pipes с его "клиент-серверной" моделью под капотом.
3) Некоторые эстеты используют продолжения. Мой бедный опыт использования продолжений подсказывает, что здесь опять проблема с взаимной блокировкой, prove me wrong.
4) Акторы, с помощью которых можно реализовать всамделишный клиент-сервер. Оверкилл.
Поскольку мне важно, чтобы consumer мог игнорировать недогруженные данные по своему усмотрению, а producer тоже был бы умным в плане использования различных эвристик, пока склоняюсь к 4, но это решение кажется слишком жирным во всех смыслах.
Можно ли дополнить этот список?