无法打开文件...precomp/7EEC5BEFD...F29E8EA4F:打开的文件太多

无法打开文件...precomp/7EEC5BEFD...F29E8EA4F:打开的文件太多

我在 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

相关内容