我应该使用哪种 OTP 行为来重复 "endless" 个任务?
Which OTP behavior should I use for an "endless" repetition of tasks?
我想在 Phoenix 应用程序旁边一遍又一遍地重复 运行 相同的操作序列(当然,如果 worker 发生故障,不会导致整个 web 应用程序崩溃)并且真的不想知道我是否应该使用 GenServer、Elixir 的任务、代理或完全不同的东西,我到目前为止还没有想过。
当我启动我的 Phoenix 应用程序时,worker 也应该启动,它会定期提取串行连接的一些值,通过 Phoenix 通道广播它们,收集它们直到达到 @save_interval
,然后计算中位数,通过不同的频道广播中位数并将其写入 InfluxDB。现在我有这样的东西(有点工作):
def do_your_thing(serial_pid) do
Stream.interval(@interval_live)
|> get_new_values_from_serial(serial_pid)
|> broadcast!("live-channel:#{@name}")
|> Enum.take(div(@interval_save, @interval_live))
|> calculate_medians()
|> broadcast!("update-channel:#{@name}")
|> write_to_database()
do_your_thing(serial_pid) # repeat
end
我才刚刚开始弄清楚 OTP 的所有内容,希望你们中的某个人能帮助我找到正确的方向。
您应该使用在 x 秒后(在下面的示例中为 60 秒)向自己发送消息的 GenServer:
defmodule MyApp.Worker do
use GenServer
def start_link() do
GenServer.start_link(__MODULE__, [])
end
def init([]) do
schedule_work()
{:ok, []}
end
def handle_info(:work, state) do
state = do_work(state)
schedule_work()
{:noreply, state}
end
defp do_work(state) do
# Do your work here and return state
end
defp schedule_work do
Process.send_after(self(), :work, 60_000)
end
end
我想在 Phoenix 应用程序旁边一遍又一遍地重复 运行 相同的操作序列(当然,如果 worker 发生故障,不会导致整个 web 应用程序崩溃)并且真的不想知道我是否应该使用 GenServer、Elixir 的任务、代理或完全不同的东西,我到目前为止还没有想过。
当我启动我的 Phoenix 应用程序时,worker 也应该启动,它会定期提取串行连接的一些值,通过 Phoenix 通道广播它们,收集它们直到达到 @save_interval
,然后计算中位数,通过不同的频道广播中位数并将其写入 InfluxDB。现在我有这样的东西(有点工作):
def do_your_thing(serial_pid) do
Stream.interval(@interval_live)
|> get_new_values_from_serial(serial_pid)
|> broadcast!("live-channel:#{@name}")
|> Enum.take(div(@interval_save, @interval_live))
|> calculate_medians()
|> broadcast!("update-channel:#{@name}")
|> write_to_database()
do_your_thing(serial_pid) # repeat
end
我才刚刚开始弄清楚 OTP 的所有内容,希望你们中的某个人能帮助我找到正确的方向。
您应该使用在 x 秒后(在下面的示例中为 60 秒)向自己发送消息的 GenServer:
defmodule MyApp.Worker do
use GenServer
def start_link() do
GenServer.start_link(__MODULE__, [])
end
def init([]) do
schedule_work()
{:ok, []}
end
def handle_info(:work, state) do
state = do_work(state)
schedule_work()
{:noreply, state}
end
defp do_work(state) do
# Do your work here and return state
end
defp schedule_work do
Process.send_after(self(), :work, 60_000)
end
end