我在 Fedora Linux 上。我有一个中等规模的 Raku 项目,在启动时突然出现以下错误:
===SORRY!=== Error while compiling /home/patrickb/repos/RakudoCIBot/service.raku
===SORRY!=== Error while compiling /home/patrickb/repos/RakudoCIBot/lib/RakudoCIBot.rakumod (RakudoCIBot)
Now hiting the error and sleeping
===SORRY!=== Error while compiling /home/patrickb/repos/RakudoCIBot/lib/Routes.rakumod (Routes)
Earlier failure:
Failed to open file /home/patrickb/.raku/precomp/F494CC98E40B399BDACD0E2436C176FDE8706DE8/28/287E340591A8C5DE2625947EEC5BEFDF29E8EA4F: Too many open files
in any statement_control at /home/patrickb/rrepos/install/share/perl6/lib/Perl6/Grammar.moarvm line 1
Final error:
Type check failed in binding; expected IO::Handle but got Failure (Failure.new(exceptio...)
at /home/patrickb/repos/RakudoCIBot/lib/Routes.rakumod (Routes):10
at /home/patrickb/repos/RakudoCIBot/lib/RakudoCIBot.rakumod (RakudoCIBot):15
at /home/patrickb/repos/RakudoCIBot/service.raku:3
删除/home/patrickb/repos/RakudoCIBot/.precomp/
文件夹可使其再次成功启动一次. 但这既不是一个解决方案,也不是一个可接受的解决办法。
发生了什么事?我该如何解决?
答案1
#raku IRC 频道中的人们在解决这个问题上提供了很大的帮助。
在出错的地方停止进程(我编译了自己的 Rakudo,并sleep
在打印错误消息之前放置了一个)。查看/proc/$PID/fd
其中一个 rakudo 编译器进程显示它正好打开了 1024 个文件(ls -1 /proc/$PID/fd | wc -l
)。大多数文件如下所示:
lr-x------. 1 patrickb patrickb 64 Jun 13 17:20 965 -> /home/patrickb/.raku/precomp/F494CC98E40B399BDACD0E2436C176FDE8706DE8/EA/EA68508E655FD3F22D1AE0A8666B86469073473
因此,编译器打开了大量预编译文件。这实际上非常合理,因为依赖关系树很容易包含 1000 多个文件,这些文件位于非平凡项目中,且具有一两个较大的依赖关系。(在我的例子中,有红色的和克罗在 deps.)
ulimit -Sn
打印1024
。所以我设置了一个相当低的限制。ulimit -n 4096
在运行我的应用程序之前调用可以使其工作。
考虑到以上所有因素,干净的解决方案似乎是将以下内容添加到/etc/security/limits.conf
:
# Increase nofile soft from the default of 1024.
# The Rakudo compiler sometimes hits the limit.
* soft nofile 4096