У меня есть приложение Erlang, которое становится слишком ресурсоемким, чтобы оставаться на одном узле. Я нахожусь в процессе перемещения gen_servers из одного процесса в другой, что оказывается относительно простым. Я на последнем препятствии: заставить фабричный процесс, который создает эти gen_servers, создавать их на удаленном узле, а не на локальном. По умолчанию start_link явно запускается только локально, но я не вижу возможности изменить это.
Казалось бы, мне придется быть изобретательным с решением, и я хотел посмотреть, реализовал ли кто-нибудь что-то подобное с каким-либо успехом. IOW, какое рекомендуемое решение?
ИЗМЕНИТЬ
Я смотрю на цепочку вызовов, которые запускаются вызовом:
gen_server:start_link(?Module, Args, [])
gen_server:start_link/3:
start_link(Mod, Args, Options) ->
gen:start(?MODULE, link, Mod, Args, Options).
род:старт/5:
start(GenMod, LinkP, Mod, Args, Options) ->
do_spawn(GenMod, LinkP, Mod, Args, Options).
род: do_spawn/5:
do_spawn(GenMod, link, Mod, Args, Options) ->
Time = timeout(Options),
proc_lib:start_link(?MODULE, init_it,
[GenMod, self(), self(), Mod, Args, Options],
Time,
spawn_opts(Options));
proc_lib:start_link/5:
start_link(M,F,A,Timeout,SpawnOpts) when is_atom(M), is_atom(F), is_list(A) ->
Pid = ?MODULE:spawn_opt(M, F, A, ensure_link(SpawnOpts)),
sync_wait(Pid, Timeout).
Что, наконец, подводит нас к самому интересному. Существует spawn_opt/4, который соответствует:
spawn_opt(M, F, A, Opts) when is_atom(M), is_atom(F), is_list(A) ->
...
...
НО, есть один, который действительно был бы мне полезен:
spawn_opt(Node, M, F, A, Opts) when is_atom(M), is_atom(F), is_list(A) ->
...
...
Меня смущает, что это не раскрывается. Я понимаю, что существует риск того, что небрежный программист может попытаться сгенерировать gen_server:start_link процесс на узле erlang, который работает на Марсе, заблокировав вызов на полчаса, но, конечно же, это забота программистов. Я действительно застрял с изменением OTP или написанием какого-то специального решения?