Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Elixir 我的任务进程似乎无限期地停滞_Elixir_Otp_Erlang Supervisor - Fatal编程技术网

Elixir 我的任务进程似乎无限期地停滞

Elixir 我的任务进程似乎无限期地停滞,elixir,otp,erlang-supervisor,Elixir,Otp,Erlang Supervisor,我正在用Elixir构建一个应用程序,它有一群工作人员(在任何给定时间可能有100-200人)。这些工作人员相互独立操作,他们不是“池”,他们所做的只是将作业从Redis队列中弹出,做一些工作,然后可能将更多作业弹出到队列中(请参见下面的代码) 这些工作人员只是受监督的任务,他们自己调用一个尾部递归函数,该函数要求执行一个作业,如果有,一切正常,如果没有,它将:timer.sleep一秒钟,然后再次运行 问题是,这些工人在那里做了一段时间后(完全如预期的那样),他们会逐渐停止这样做 我在《观察家

我正在用Elixir构建一个应用程序,它有一群工作人员(在任何给定时间可能有100-200人)。这些工作人员相互独立操作,他们不是“池”,他们所做的只是将作业从Redis队列中弹出,做一些工作,然后可能将更多作业弹出到队列中(请参见下面的代码)

这些工作人员只是受监督的任务,他们自己调用一个尾部递归函数,该函数要求执行一个作业,如果有,一切正常,如果没有,它将
:timer.sleep
一秒钟,然后再次运行

问题是,这些工人在那里做了一段时间后(完全如预期的那样),他们会逐渐停止这样做

我在《观察家》中看到了它们,我看到了一些有趣的事情:

  • 出现错误时,工作人员将按照其
    :一对一
    监督策略中的定义重新启动
  • 已重新启动的工人可以通过其显著较高的PID来识别
  • 无反应/停滞的工人具有最初分配的相同PID
  • 如果我在Observer中手动杀死其中一个工人,它会重新启动并继续工作
我有点困惑于这里发生了什么以及如何补救。我还想知道,如果这样管理大量员工,这是否是一种“糟糕”的方法,如果是,还有更好的方法吗

监督人 工人 “暂停”工作进程的堆栈跟踪(它们看起来都一样)

观察者说这些暂停的进程正在做什么(“当前功能”列)?当观察者停止工作时,他们的MsgQ/Reds/内存值是否增加?@Dogbert当前函数是
gen:do_call/4
(现在我有一个运行状态,所有工作者都处于“停止”状态),所有工作者的函数相同。它们也都有0个红色,并且随着时间的推移似乎保持相同的内存值(要清楚的是,所有的工作进程都没有相同的内存值)。核心是什么?检查\u domain/1,
Utils.insert/3
,和
Store.Domains.pop/0
做什么?他们会打GenServer电话吗?所有这些调用都有超时值吗?
Core.check\u domain/1
向HTTPoison库(hackney)发出一个HTTP请求,并有条件地向Whois库发出另一个HTTP请求(我知道没有GenServer)
Utils.insert/1
使用EXTO向postgres中插入一行,并且
Store.Domains.pop/0
通过自滚池机制使用Redix调用Redis(与我的工作人员的工作方式类似,只是随机将调用传递给10个Redix连接中的一个).我几乎排除了Store.Domains.pop/0,因为我有另一种类型的worker,它从不暂停,因为它也调用使用此Redix worker池的函数,并且以完全相同的方式工作,对返回(或未返回)的项进行压缩,只是一个不同的Redis集合。观察家说这些已经停止的进程正在做什么(“当前函数”列)?当观察者停止工作时,他们的MsgQ/Reds/内存值是否增加?@Dogbert当前函数是
gen:do_call/4
(现在我有一个运行状态,所有工作者都处于“停止”状态),所有工作者的函数相同。它们也都有0个红色,并且随着时间的推移似乎保持相同的内存值(要清楚的是,所有的工作进程都没有相同的内存值)。核心是什么?检查\u domain/1,
Utils.insert/3
,和
Store.Domains.pop/0
做什么?他们会打GenServer电话吗?所有这些调用都有超时值吗?
Core.check\u domain/1
向HTTPoison库(hackney)发出一个HTTP请求,并有条件地向Whois库发出另一个HTTP请求(我知道没有GenServer)
Utils.insert/1
使用EXTO向postgres中插入一行,并且
Store.Domains.pop/0
通过自滚池机制使用Redix调用Redis(与我的工作人员的工作方式类似,只是随机将调用传递给10个Redix连接中的一个).我几乎排除了Store.Domains.pop/0,因为我有另一种类型的worker,它从不暂停,因为它也调用使用此Redix worker池的函数,并且以完全相同的方式工作,在返回(或未返回)项上加上大小写,只是一个不同的Redis集。
defmodule Workers.DomainSupervisor do
  def start_link do
    import Supervisor.Spec, warn: false

    children = 1..50 |> Enum.map(fn (i) -> worker(Task, [&Workers.Domain.worker/0], [id: {Workers.Domain, i}]) end)

    opts = [strategy: :one_for_one, name: Workers.DomainSupervisor]
    Supervisor.start_link(children, opts)
  end
end
defmodule Workers.Domain do
  def worker do
    case Store.Domains.pop do
      :empty ->
        IO.puts "[Domain] none found, waiting..."
        :timer.sleep(1000)
      {crawl_id, domain} ->
        IO.puts "[Domains] found a domain to check: #{domain}"
        case Core.check_domain(domain) do
          :error ->
            Utils.insert(crawl_id, domain, false)
          :registered ->
            Utils.insert(crawl_id, domain, false)
          :available ->
            Utils.insert(crawl_id, domain, true)
        end
    end
    worker()
  end
end