我有一个被VIA Cronjob触发的功能。这个cronjob在晚上10点触发该功能,但是假设该功能没有正确处理所需的数据。我想失败,但然后让功能重试1小时。我该如何处理这个问题?
def check_question do
case question = Repo.get_by(Question, active: true, closed: true) do
question when not(is_nil(question)) ->
case ActiveQuestion.ready_for_answer_status(conn, question) do
end
_ ->
# RETRY CODE HERE
end
end
所以你可以从这段代码中看出来。如果查询没有找到问题我将case语句发送到失败但在失败的情况下我想在1小时内返回该函数。如何使用Elixir / Phoenix实现这一目标?谢谢你的帮助!
答案 0 :(得分:2)
您可以使用genserver在1小时后发送消息以执行check_question
。
如果服务器关闭,计时器将不会继续倒计时。
如果给定的dest是PID,则计时器将自动取消 它不存在或当给定的PID退出时。
在这种情况下,self
返回调用进程的PID(进程标识符)。
defmodule Periodically do
use GenServer
def start_link do
GenServer.start_link(__MODULE__, %{})
end
def init(state) do
# DingDing.Helper.update_all_company_users()
# One.Dingding.Auth.update_app_access_token()
check_question()
{:ok, state}
end
def handle_info(:update, state) do
check_question()
{:noreply, state}
end
def check_question do
case question = Repo.get_by(Question, active: true, closed: true) do
question when not(is_nil(question)) ->
case ActiveQuestion.ready_for_answer_status(conn, question) do
end
_ ->
Process.send_after(self(), :update, 60*60*1000)
end
end
end
答案 1 :(得分:2)
使用GenServer
的解决方案在这里对我来说太过分了。我会选择一个非监控任务Task.start/1
。此解决方案的缺点是,如果任务失败,则无人知晓,请求的操作不会生效。如果您必须确保任务成功完成,请使用@ yonghao-hu提供的解决方案。
@task fn ->
case question = Repo.get_by(Question, ...) do
question when not(is_nil(question)) ->
...
_ ->
Process.sleep(5_000) # delay
Task.start(@task)
end
end
在你的cron托管代码中的某个地方:
Task.start @task
答案 2 :(得分:1)