GenStage.from_enumerable会与间歇流挂起

时间:2018-06-27 15:21:04

标签: elixir genstage

我有一个流,它不能像消耗的数据那样快地产生数据。

所以我有一个这样的生产者定义:

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(:n​​ormal,[])返回错误:关闭:   无法启动孩子:生产者       **(EXIT)退出:GenServer.call({:name,ProducerConsumer},{:“ $ subscribe”,nil,#PID <0.2031.0>,[cancel::transient]},5000)           **(退出)与Elixir.ProducerConsumer没有连接

1 个答案:

答案 0 :(得分:0)

错误:

  

**(混合)无法启动应用程序测试:Application.start(:n​​ormal,[])返回错误:关机:无法启动子级: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])
]