我有一个elixir/OTP应用程序由于内存不足问题而在生产中崩溃.导致崩溃的功能在专用进程中每6小时调用一次.运行需要几分钟(~30),看起来像这样:
def entry_point do
get_jobs_to_scrape()
|> Task.async_stream(&scrape/1)
|> Stream.map(&persist/1)
|> Stream.run()
end
Run Code Online (Sandbox Code Playgroud)
在我的本地机器上,当函数运行时,我看到大型二进制文件内存消耗不断增长:
请注意,当我在运行该函数的进程上手动触发垃圾收集时,内存消耗会显着下降,因此对于无法使用GC的几个不同进程来说肯定不是问题,而只有一个不能正常运行GC.此外,它说,每隔几分钟的过程中是非常重要的并设法GC,但有时还不够.生产服务器只有1GB内存,在GC启动之前就崩溃了.
试图解决我在愤怒中遇到Erlang的问题(参见第66-67页).一个建议是将所有大型二进制文件操作放在一次性过程中.scrape函数的返回值是包含大二进制文件的映射.因此,它们在Task.async_stream"worker"和运行该函数的进程之间共享.因此,从理论上讲,我可以把persist与一起scrape内Task.async_stream.我不想这样做,并persist通过这个过程保持呼叫同步.
另一个建议是:erlang.garbage_collect定期打电话.看起来它解决了这个问题,但感觉太过于hacky.作者也不建议这样做.这是我目前的解决方案:
def entry_point do
my_pid = self()
Task.async(fn -> periodically_gc(my_pid) end)
# The rest of the function as before...
end
defp periodically_gc(pid) do
Process.sleep(30_000)
if Process.alive?(pid) do
:erlang.garbage_collect(pid)
periodically_gc(pid)
end
end
Run Code Online (Sandbox Code Playgroud)
结果内存负载:
我不太明白书中的其他建议如何适应这个问题.
那个案子你会推荐什么?保持hacky解决方案或有更好的选择.
我正在用硒写测试.在那些测试中,我需要在表单中的字段中输入数字.
这是html:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<form>
<input type="number" id="field_id">
</form>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
和代码:
browser = webdriver.Firefox()
browser.get('file:///home/my_username/test.html')
field = browser.find_element_by_id('field_id')
field.send_keys('12') # NOTHING HAPPEN!
Run Code Online (Sandbox Code Playgroud)
顺便说一句,如果我将字段的类型更改为"文本",例如根本没有问题.另外,field.send_keys(Keys.UP)工作得很好(但是当我使用bootstrap时不起作用)并且一直field.clear()工作,以及field.click().
Selenium版本:2.41.0 Firefox版本:29.0
我有一个elixir/OTP应用程序在生产中运行,它开始于mix phoenix.server.它有几个持有状态的进程.其中一个是作为代理实现的存储,当前有一个我想手动更改的状态,而不会停止整个应用程序.一旦我在应用程序内部进行iex会话,这将是微不足道的,但我不知道在elixir中是否甚至可以使用这样的选项?
我正在解决一个大于内存的数据集的问题。原始数据集是一个.csv文件。列之一是来自musicbrainz服务的曲目ID。
我用dask读取了.csv文件,并将其转换为磁盘上的castra格式以获得更高的性能。我还查询了musicbrainz API,并使用peewee填充了一个sqlite数据库,并得到了一些相关结果。我选择使用数据库而不是另一个dask.dataframe,因为该过程花了几天的时间,而且我不想在发生任何故障时丢失数据。
我还没有真正开始分析数据。重新整理数据时,我设法弄得一团糟。
我很难将SQL DB的列连接到dask / castra数据框。实际上,我不确定这是否可行。
在为任务选择最佳工具时,我似乎犯了一些错误。Castra可能还不够成熟,我认为这是问题的一部分。另外,最好选择SQLAlchemy来支持peewee,因为pandas和peewee都不使用它。
Blaze + HDF5可能是dask + castra的不错选择,主要是因为HDF5比castra更稳定/更成熟/更完整,并且blaze在数据存储方面的看法较少。例如,它可以简化将SQL DB连接到主数据集中的过程。
另一方面,我对大熊猫很熟悉,还可以公开“相同”的API。借助dask,我还将获得并行性。
我要比内存数据集+ sqlite DB大,需要加入主数据集。我不确定是否要使用dask + castra(不知道dask.dataframe的其他相关数据存储),并使用SQLAlchemy通过pandas一次将部分SQL DB加载到数据框中。我认为最好的替代方法是改用blaze + HDF5。在这种情况下,您有什么建议?
任何其他选项/意见都值得欢迎。我希望这对于SO来说足够具体。
我试图理解之间的差异spawn和spawn_link,但不能完全把握时会发生什么功能的进程执行结束.
defmodule SendAndDie do
def send_and_die(target) do
send(target, "Goodbye")
# Process.exit(self, :boom)
end
end
dying_process = spawn_link(SendAndDie, :send_and_die, [self])
:timer.sleep(500)
IO.puts("Dying process is alive: #{Process.alive?(dying_process)}")
receive do
msg -> IO.puts(msg)
end
Run Code Online (Sandbox Code Playgroud)
我预计主要过程会失败,因为它与在程序结束前明显死亡的过程相关联.但是,打印"Goodbye"消息,然后程序正常退出.更改spawn_link到spawn没有任何效果.
当我取消注释第Process.exit4行时,我确实看到了spawn和之间的区别spawn_link(后者在整个程序中停止而前者没有).但是,这Process.exit是send_and_die函数中的最后一次执行.当函数结束时,进程是否会退出?
我写了一个很棒的印记:
defmodule Sigiltest do
@doc """
An awesome sigil!
### Usage
iex> ~a{I love elixir}
"I love elixir, awesome!"
"""
def sigil_a(content, _flags) do
"#{content}, awesome!"
end
end
Run Code Online (Sandbox Code Playgroud)
这是测试模块:
defmodule SigiltestTest do
use ExUnit.Case
doctest Sigiltest
end
Run Code Online (Sandbox Code Playgroud)
当我运行时,mix test我得到以下输出:
Compiled lib/sigiltest.ex
** (CompileError) (for doctest at) lib/sigiltest.ex:7: undefined function sigil_a/2
(stdlib) lists.erl:1337: :lists.foreach/2
(stdlib) erl_eval.erl:670: :erl_eval.do_apply/6
Run Code Online (Sandbox Code Playgroud)
有没有办法在印记上运行 doctests?如果是这样,如何?