2017-09-28 70 views
0

如果我GenStage的handle_demand/2方法是这样的:GenStage:重试handle_demand时GenServer更新

def handle_demand(demand, _state) when demand > 0 do 
    case Queue.dequeue do 
    nil -> 
     Logger.debug("Queue empty.") 
     {:noreply, [], []} 
    {job, updated_queue} -> {:noreply, job, updated_queue} 
    end 
end 

我如何得到它“重新运行”当我Queue(一GenServer)改变/更新?

我的队列模块看起来就像这样:

defmodule Queue do 
    use GenServer 

    ### client 

    def start_link(state \\ []) do 
    GenServer.start_link(__MODULE__, state, name: __MODULE__) 
    end 

    def queue, do: GenServer.call(__MODULE__, :queue) 

    def enqueue(value), do: GenServer.cast(__MODULE__, {:enqueue, value}) 

    def dequeue, do: GenServer.call(__MODULE__, :dequeue) 

    ### server 

    def init(state), do: {:ok, state} 

    def handle_call(:dequeue, _from, [value | state]) do 
    {:reply, value, state} 
    end 

    def handle_call(:dequeue, _from, []), do: {:reply, nil, []} 

    def handle_call(:queue, _from, state), do: {:reply, state, state} 

    def handle_cast({:enqueue, value}, state) do 
    {:noreply, state ++ [value]} 
    end 
end 

回答

1

你为什么要“重新运行”它的时候Queue变化?这是一个严重滥用GenStage。它被发明允许打背压,来自Queue,而不是反之亦然。在现实生活中,您根本不需要GenStage,或者当Queue得到更新时,您不希望“重新运行”需求,因为它迟早会通过超时/消息框杀死它。

当处理队列中的上一次加载时,您可能有点“消费者”调用handle_demandGenStage的回购有four incredibly clear examples使用不同的模式与GenStage一起使用。除此之外,Elixir blog有一个很好的介绍GenStage

只需拿起你需要的模式,并采用它从上面链接的来源。