Передача fun на удалённые ноды

36 просмотров
Перейти к первому непрочитанному сообщению

Еремихин Алексей

не прочитано,
11 февр. 2011 г., 10:15:4611.02.2011
– erlang-...@googlegroups.com
О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫лёО©╫О©╫О©╫О©╫
О©╫О©╫О©╫О©╫О©╫. О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫ О©╫О©╫О©╫
> rpc:multicall(erlang, apply, [fun()->[node()] end, []]).
{[[ejabberd@node1],
[ejabberd@node2],
[ejabberd@node3],
[zzz@node1]],
[]}

О©╫ О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫
ejabberd. О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫, О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫.
О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫ О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫. О©╫О©╫О©╫О©╫О©╫ О©╫
О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫.

{[ejabberd@node1,
{badrpc,{'EXIT',{{badfun,#Fun},
[{erlang,apply,2},{rpc,'-handle_call/3-fun-0-',5}]}}},
{badrpc,{'EXIT',{{badfun,#Fun},
[{erlang,apply,2},{rpc,'-handle_call/3-fun-0-',5}]}}},
[]}


О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫, О©╫О©╫О©╫ О©╫ О©╫О©╫О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫? О©╫О©╫О©╫О©╫О©╫О©╫ fun О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫
О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫ О©╫О©╫О©╫О©╫, О©╫О©╫О©╫ О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫?

О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫, О©╫О©╫О©╫ fun О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫,
О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫, О©╫О©╫
О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫, О©╫ О©╫О©╫О©╫
О©╫О©╫О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫.

Kirill Zaborsky

не прочитано,
11 февр. 2011 г., 10:22:3011.02.2011
– erlang-...@googlegroups.com
Насколько я помню, фуны в консоли они "хитрые" и отличаются от
скомпилированных. Последние по сути обычные функции, только с хитрыми
именами. Естественно, что вызов их на нодах, где кода нет, не прошёл.

С уважением,
Кирилл Заборский.

11 февраля 2011 г. 18:15 пользователь Еремихин Алексей <ale...@mail.ru> написал:
> Захотелось мне иметь возможность выполнить произвольный код на удалённых
> нодах. Взял консоль и написал в ней


>> rpc:multicall(erlang, apply, [fun()->[node()] end, []]).
> {[[ejabberd@node1],
>  [ejabberd@node2],
>  [ejabberd@node3],
>  [zzz@node1]],
>  []}
>

> А после этого захотелось мне сделать эту же операцию из админки ejabberd.
> Исправил на одной ноде модуль, добавил реквест хендлер.
> Скомпилил модуль и проапдейтил код только на этой ноде. Дёрнул в браузере и
> получил удивительный результат.


>
> {[ejabberd@node1,
>  {badrpc,{'EXIT',{{badfun,#Fun},
>                   [{erlang,apply,2},{rpc,'-handle_call/3-fun-0-',5}]}}},
>  {badrpc,{'EXIT',{{badfun,#Fun},
>                   [{erlang,apply,2},{rpc,'-handle_call/3-fun-0-',5}]}}},
>  []}
>
>

> Объясните мне пожалуйста, что я делаю не так? Почему fun выполнился только
> на той ноде, где я изменил код?
>
> Сначала мне показалось, что fun как таковой не передаётся между нодами, а
> передаётся некий индентификатор, но
> это не объясняет почему вызов из консоли дал ожидаемый результат, а вот
> вызов из модуля вернул весьма неожиданные данные.
>
> --
> Страница рассылки: http://groups.google.com/group/erlang-russian
> Jabber-конференция: erl...@conference.jabber.ru
> Новости: http://erlanger.ru
> Написать письмо: erlang-...@googlegroups.com
> Отписаться: erlang-russia...@googlegroups.com
>

Mikl Kurkov

не прочитано,
11 февр. 2011 г., 11:14:0111.02.2011
– erlang-...@googlegroups.com, Еремихин Алексей

Проблема в том что Erlang передает версию модуля в котором функция была определена.
И хотя функция не изменилась, версия модуля (MD5) другая и возникает ошибка.
Обойти это можно поддерживая одинаковые версии на нодах или используя eval для определения функции,
чтобы она в своем определении содержала версию модуля eval, который меняется не так часто :)
Вот хорошая статья об этом:
http://www.javalimit.com/2010/05/passing-funs-to-other-erlang-nodes.html

--
Mikl

2011/2/11 Еремихин Алексей <ale...@mail.ru>
Захотелось мне иметь возможность выполнить произвольный код на удалённых нодах. Взял консоль и написал в ней
> rpc:multicall(erlang, apply, [fun()->[node()] end, []]).
{[[ejabberd@node1],
 [ejabberd@node2],
 [ejabberd@node3],
 [zzz@node1]],
 []}

А после этого захотелось мне сделать эту же операцию из админки ejabberd. Исправил на одной ноде модуль, добавил реквест хендлер.
Скомпилил модуль и проапдейтил код только на этой ноде. Дёрнул в браузере и получил удивительный результат.

{[ejabberd@node1,
 {badrpc,{'EXIT',{{badfun,#Fun},
                  [{erlang,apply,2},{rpc,'-handle_call/3-fun-0-',5}]}}},
 {badrpc,{'EXIT',{{badfun,#Fun},
                  [{erlang,apply,2},{rpc,'-handle_call/3-fun-0-',5}]}}},
 []}


Alexxz

не прочитано,
11 февр. 2011 г., 14:57:2111.02.2011
– Erlang в России
Огромное спасибо за подробную и весьма интересную статью. Но я только
не понял как
получается у erl_eval в консоли передавать код фуна на другие ноды.
Или он делает тот
же небезопасный фокус с отправкой кода модуля целиком? Вобщем, хочу
понять, что
происходит при вызове кода из консоли, что он работает. Вообще в мане
по erl_eval есть
что-то на тему вызова apply на удалённых нодах, но я как-то не смог
понять, что там написано.
Объясните пожалуйста.
Ответить всем
Отправить сообщение автору
Переслать
0 новых сообщений