gpt4 book ai didi

elixir - 构建重复性任务的正确 Elixir OTP 方式

转载 作者:行者123 更新时间:2023-12-03 21:09:56 24 4
gpt4 key购买 nike

我有一个工作流程,它涉及每 30 秒左右醒来一次并轮询数据库以获取更新,对此采取行动,然后重新进入休眠状态。撇开数据库轮询无法扩展和其他类似问题,使用主管、工作人员、任务等构建此工作流的最佳方法是什么?

我将列出我的一些想法以及我支持/反对的想法。请帮我找出最 Elixir 的方法。 (顺便说一句,我对 Elixir 还是很陌生。)

1. 无限循环函数调用

只需在其中放置一个简单的递归循环,如下所示:

def do_work() do
# Check database
# Do something with result
# Sleep for a while
do_work()
end

我在跟随 tutorial on building a web crawler 时看到了类似的东西.

我在这里担心的一个问题是由于递归而导致的无限堆栈深度。由于我们在每个循环结束时递归,这最终不会导致堆栈溢出吗?此结构用于 the standard Elixir guide for Tasks ,所以我可能对堆栈溢出问题有误。

更新 - 正如答案中提到的, tail call recursion在 Elixir 中意味着堆栈溢出在这里不是问题。最后调用自己的循环是一种可以接受的无限循环方式。

2.使用一个任务,每次重启

这里的基本思想是使用一个运行一次然后退出的任务,但将它与一个带有 one-to-one 的主管配对。重新启动策略,因此每次完成后都会重新启动。任务检查数据库,休眠,然后退出。主管看到导出并开始新的导出。

这有住在主管里面的好处,但这似乎是对主管的滥用。除了错误捕获和重新启动之外,它还用于循环。

(注意:Task.Supervisor 可能还有其他功能可以完成,而不是常规主管,我只是不明白。)

3.任务+无限递归循环

基本上,结合 1 和 2 所以它是一个使用无限递归循环的任务。现在它由主管管理,如果崩溃将重新启动,但不会作为工作流程的正常部分一遍又一遍地重新启动。这是目前我最喜欢的方法。

4. 其他?

我担心的是我缺少一些基本的 OTP 结构。例如,我熟悉 Agent 和 GenServer,但我最近偶然发现了 Task。也许有某种 Looper 正是针对这种情况的,或者有一些涵盖它的 Task.Supervisor 用例。

最佳答案

我在这里有点晚了,但是对于那些仍在寻找正确方法的人来说,我认为值得一提的是 GenServer documentation本身:

handle_info/2 can be used in many situations, such as handling monitor DOWN messages sent by Process.monitor/1. Another use case for handle_info/2 is to perform periodic work, with the help of Process.send_after/4:


defmodule MyApp.Periodically do
use GenServer

def start_link do
GenServer.start_link(__MODULE__, %{})
end

def init(state) do
schedule_work() # Schedule work to be performed on start
{:ok, state}
end

def handle_info(:work, state) do
# Do the desired work here
schedule_work() # Reschedule once more
{:noreply, state}
end

defp schedule_work() do
Process.send_after(self(), :work, 2 * 60 * 60 * 1000) # In 2 hours
end
end

关于elixir - 构建重复性任务的正确 Elixir OTP 方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35364511/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com