Изменить лимит дескриптора файла Erlang?

У меня возникли проблемы с приложением Erlang OTP + Cowboy, которое не позволяет мне одновременно открывать достаточно файлов.

Как изменить количество дескрипторов открытых файлов, разрешенных в BEAM?

Потенциально мне потребуется одновременно открыть около 500 небольших текстовых файлов, но, похоже, ограничение на количество файлов составляет 224. Я получил значение 224 из этой небольшой тестовой программы:

-module(test_fds).
-export([count/0]).

count() -> count(1, []).

count(N, Fds) ->
  case file:open(integer_to_list(N), [write]) of
    {ok, F} ->
      count(N+1, [F| Fds]);

    {error, Err} ->
      [ file:close(F) || F <- Fds ],
      delete(N-1),
      {Err, N}
  end.

delete(0) -> ok;
delete(N) -> 
  case file:delete(integer_to_list(N)) of
    ok         -> ok;
    {error, _} -> meh
  end,

delete(N-1).

Это дает

$ erl
Erlang/OTP 20 [erts-9.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:10] [kernel-poll:false]

Eshell V9.2  (abort with ^G)
1> c(test_fds).     
{ok,test_fds}
2> test_fds:count().
{emfile,224}
3> 

Кажется, это проблема Erlang, а не проблема Mac OSX, поскольку из командной строки я получаю:

$ sysctl -h kern.maxfiles
kern.maxfiles: 49,152
$ sysctl -h kern.maxfilesperproc
kern.maxfilesperproc: 24,576

person Chris W    schedule 01.03.2018    source источник
comment
Что выводит ulimit -n в вашей оболочке?   -  person Dogbert    schedule 01.03.2018
comment
в моей оболочке ulimit возвращает unlimited, но это явно не так!   -  person Chris W    schedule 01.03.2018


Ответы (1)


Количество дескрипторов открытых файлов, скорее всего, ограничено вашей оболочкой. Вы можете увеличить его, запустив ulimit -n 1000 (или больше) в своей оболочке перед вызовом erl. В моей системе значение по умолчанию было 7168, и ваш скрипт мог открыть 7135 файлов, прежде чем вернуть emfile. Вот результат моего запуска вашего скрипта с разными значениями ulimit:

$ ulimit -n 64; erl -noshell -eval 'io:format("~p~n", [test_fds:count()]), erlang:halt()'
{emfile,32}
$ ulimit -n 128; erl -noshell -eval 'io:format("~p~n", [test_fds:count()]), erlang:halt()'
{emfile,96}
$ ulimit -n 256; erl -noshell -eval 'io:format("~p~n", [test_fds:count()]), erlang:halt()'
{emfile,224}
$ ulimit -n 512; erl -noshell -eval 'io:format("~p~n", [test_fds:count()]), erlang:halt()'
{emfile,480}

erl, скорее всего, открывает 32 файловых дескриптора, прежде чем начнет оценивать наш код, что объясняет постоянную разницу 32 в ulimit и выводе.

person Dogbert    schedule 01.03.2018
comment
Спасибо. Это исправлено! Однако на моей машине ulimit возвращает unlimited, что явно неверно! - person Chris W; 01.03.2018
comment
Что печатает ulimit -n? Мой обычный вывод ulimit также unlimited. -n - это то, как вы печатаете лимит дескрипторов открытых файлов. - person Dogbert; 01.03.2018
comment
ulimit -n было установлено на 256. Спасибо. - person Chris W; 01.03.2018