我有一个流,它不能像消耗的数据那样快地产生数据。
所以我有一个这样的生产者定义:
def start_link() do
create_stream
|> GenStage.from_enumerable(name: Producer)
end
然后我的生产者-消费者订阅
def init(:ok) do
{:producer_consumer, :the_state_does_not_matter, subscribe_to: [Producer]}
end
我的消费者订阅了mu生产者-消费者
def init(:ok) do
{:consumer, :the_state_does_not_matter, subscribe_to: [ProducerConsumer]}
end
我遇到的问题是消费者挂起,我认为是因为在某些时候,生产者没有设法获取新数据,并且如文档所述:
当枚举结束或停止时,阶段将退出 :正常原因。这意味着,如果消费者订阅了 可枚举的阶段,并且:取消选项设置为:永久,即 默认情况下,消费者还将退出并返回:正常原因
因此,我阅读了更多内容,并建议添加选项cancel:: transient
以免结束该阶段。我是这样添加的,但是它不起作用,我丢失了什么吗?
|> GenStage.from_enumerable(name: Producer, cancel: :transient)
最初我使用的是Flow.into_stages(flow, [ProducerConsumer])
,但我不能这样做,因为我无法从主管树中引用(或不知道如何)ProducerConsumer
children = [
{Producer, []},
{ProducerConsumer, []},
{Consumer, []}
]
更新
从子定义中更新对Flow.into_stages的传递引用
children = [
{Producer, [name: ProducerConsumer]},
{ProducerConsumer, []},
{Consumer, []}
]
def start_link(producer_consumer) do
create_stream
|> Flow.into_stages(producer_consumer)
end
**(混合)无法启动应用程序测试:Application.start(:normal,[])返回错误:关闭: 无法启动孩子:生产者 **(EXIT)退出:GenServer.call({:name,ProducerConsumer},{:“ $ subscribe”,nil,#PID <0.2031.0>,[cancel::transient]},5000) **(退出)与Elixir.ProducerConsumer没有连接
答案 0 :(得分:0)
错误:
**(混合)无法启动应用程序测试:Application.start(:normal,[])返回错误:关机:无法启动子级:Producer ** (EXIT)在以下位置退出:GenServer.call({:name,ProducerConsumer}, {:“ $ subscribe”,nil,#PID <0.2031.0>,[取消:: transient]},5000)** (退出)与Elixir.ProducerConsumer没有连接
仅仅意味着当Flow.into_stages尝试同步到提供的使用者时,该使用者必须已经在运行。
所以,监督的顺序很重要,如下所示:
children = [
Consumer,
FlowProducerWorker # worker which implements Flow.into_stages(flow, [Consumer])
]