Файл vm.args
заканчивается передачей Эрлангу с помощью аргумента -args_file
.Я посмотрел на документацию для -args_file
и обнаружил, что она на самом деле не очень хорошо документирована.Оказывается, что vm.args
похоже на лук в том смысле, что в нем много слоев, и документация, похоже, полностью в исходном коде.
Давайте начнем с того, что нам нужно в итоге.Мы хотим, чтобы sync_nodes_mandatory
был списком атомов, и нам нужно написать его в синтаксисе Эрланга.Если бы мы использовали короткие имена узлов, например my_app@myhost
, мы могли бы не заключать в кавычки атомы, но атомы с точками в них нужно заключать в кавычки, используя одинарные кавычки:
['my_app@10.10.10.100','my_app@10.10.10.200']
Мы хотим, чтобы этобыть выводом функции build_args_from_string
в erlexec.c
.Эта функция имеет четыре правила:
- Символ обратной косой черты экранирует любой один символ
- Двойная кавычка экранирует все символы (включая обратную косую черту) до следующей двойной кавычки
- Aодинарная кавычка экранирует все символы (включая обратную косую черту) до следующей одинарной кавычки
- Пробел отмечает конец аргумента
Так как мы хотим передать одинарные кавычки допарсер, у нас есть две альтернативы.Мы можем избежать одинарных кавычек:
[\'my_app@10.10.10.100\',\'my_app@10.10.10.200\']
Или мы можем заключить одинарные кавычки в двойные кавычки:
["'my_app@10.10.10.100','my_app@10.10.10.200'"]
(На самом деле, неважно, сколько и где мыставьте двойные кавычки, если каждое вхождение одинарной кавычки находится внутри пары двойных кавычек. Это всего лишь один из возможных способов сделать это.)
НО , если мы решимизбегая одинарных кавычек с обратной косой чертой, мы сталкиваемся с другим слоем! Функция read_args_file
- это функция, которая на самом деле читает файл vm.args
с диска перед передачей его в build_args_from_string
, и сначала она устанавливает свои собственные правила!А именно:
- Символ обратной косой черты экранирует любой один символ
- A
#
Символ игнорирует все символы до следующей новой строки - Любой символ пробела заменяется однимпробел, если не избежать обратной косой черты
Так что, если бы мы написали [\'my_app@10.10.10.100\',\'my_app@10.10.10.200\']
в vm.args
, read_args_file
съел бы обратную косую черту, а build_args_from_string
съел бы одиночные кавычки, оставив насс недопустимым термином и ошибкой:
$ iex --erl '-args_file /tmp/vm.args'
2019-04-25 17:00:02.966277 application_controller: ~ts: ~ts~n
["syntax error before: ","'.'"]
"[my_app@10.10.10.100,my_app@10.10.10.200]"
{"could not start kernel pid",application_controller,"{bad_environment_value,\"[my_app@10.10.10.100,my_app@10.10.10.200]\"}"}
could not start kernel pid (application_controller) ({bad_environment_value,"[my_app@10.10.10.100,my_app@10.10.10.200]"})
Crash dump is being written to: erl_crash.dump...done
Таким образом, мы можем либо использовать двойные обратные косые черты:
-kernel sync_nodes_mandatory [\\'my_app@10.10.10.100\\',\\'my_app@10.10.10.200\\']
, либо просто придерживаться двойных кавычек (на этот раз другой, одинаково действительный вариант)):
-kernel sync_nodes_mandatory "['my_app@10.10.10.100','my_app@10.10.10.200']"
Как указано в документации для kernel
приложения , вам также необходимо установить sync_nodes_timeout
для времени в миллисекундах или infinity
:
Указывает время (в миллисекундах), в течение которого этот узел ожидает запуска обязательных и необязательных узлов.Если этот параметр не определен, синхронизация узлов не выполняется.
Добавить что-то вроде:
-kernel sync_nodes_timeout 10000