Подключение к узлам из скриптов? - PullRequest
2 голосов
/ 12 марта 2012

Я пытаюсь протестировать систему, вызвав написанную мной функцию, которая находится в скрипте и скомпилирована в оболочке Erlang (в Windows).

Функция подключается к другим узлам (которые работают).

Я получаю сообщение о том, что «Не могу запустить erlang: apply, [......», и я думаю, что это потому, что я не запустил оболочку, чтобы действовать как распределенный узел.

Может ли кто-нибудь сообщить, что мне нужно сделать, чтобы иметь возможность запускать скрипт из оболочки, который отправляет сообщения другим узлам?

Ответы [ 2 ]

3 голосов
/ 14 марта 2012

Чтобы начать рассылку erlang из сценария, вам нужно либо передать аргумент -name Name в виде горячего комментария %%! -name Name в своем сценарии, либо запустить его вручную. Я написал пример для Erlang Factory 2011 (поговорим здесь - http://www.erlang -factory.com / conference / SFBay2011 / speaker / GeoffCant ).

У меня также есть ссылка на пример кода для запуска рассылки erlang в escript из github repo , который я использовал в разговоре.

Это сводится к:

net_kernel:start([Name, longnames]),
erlang:set_cookie(Name, list_to_atom(Cookie)).
1 голос
/ 14 марта 2012

Есть две вещи, потенциально неправильные,

Во-первых, вы просто не настроены как узел.В Windows это можно исправить, передав " -node NodeName " в werl аналогично Unix, например:

$ erl -name zephmatic
(zephmatic@kerneltrap)1> node().
'zephmatic@kerneltrap'

Если вы уже настроили имя узла(просто чтобы убедиться, что запустите node () и erlang: get_cookie () в Erl!), я предполагаю, что это фактическая семантика обмена сообщениями узлов в erlang, с которой у вас возникают проблемы - это понятная широкая темаВесь язык Erlang почти полностью сосредоточен на решении загадки правильных примитивов обмена сообщениями.Каноническая ссылка на OTP: Распределенный Erlang , но юмористическое и (на мой взгляд) отличное введение в тему: Learn You Some Erlang For Great Good * .это полезно для ваших насущных потребностей, вот несколько примеров кода для манипулирования поведением gen_server, которое я протестировал, вы можете свободно вызывать его, подключаться к нему и получать высококачественное распределенное программирование за меньшие деньги (только на неограниченное время)!

Желаем удачи, и не захватывайте мир слишком быстро, когда в вашем распоряжении миллиард машин!

-module(communicate).
-author('Zephyr Pellerin').

-behavior(gen_server).

-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).

-export([start/0, grab/2, lookup/1, return/1]).

%%% The reason I declare all of these is to make calling
%%% namespaced functions easier, i.e, simply calling start(). 
%%% rather than gen_server:start_link()
start() ->
  gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
grab(Which, Element) ->
  gen_server:call(?MODULE, {grab, Which, Element}). 
lookup(Element) ->
  gen_server:call(?MODULE, {lookup, Element}).
return(Element) -> 
  gen_server:call(?MODULE, {return, Element}).

% The init method is a "callback" (Whatever that designation may imply)
% that occurs when another client connects
init([]) ->
    Resource = dict:new(),
    {ok, Resource}.

%%% The Generic server specifies that handling calls happens
%%% through handle_call, which would have thought!
%%% If you're not very experienced with Erlang, this below might seem
%%% strange to you -- it's just different ways to handle 
%%% input given differing "types" (Not a real thing in Erl). 

% This function simply looks to see if an element from
% a "Resource" is in use, if not it tells the other node
% that it is locked, or returns it if not.
handle_call({grab, Which, Element}, _From, Resource) ->
    Response = case dict:is_key(Element, Resource) of
        true ->
            NewResource = Resource,
            {locked, Element};
        false ->
            NewResource = dict:append(Element, Which, Resource),
            ok
    end,
    {reply, Response, NewResource};

% This function checks for the existence of an element 
handle_call({lookup, Element}, _From, Resource) ->
    Response = case dict:is_key(Element, Resource) of
        true ->
            {which, lists:nth(1, dict:fetch(Element, Resource))};
        false ->
            {not_locked, Element}
    end,
    {reply, Response, Resource};

% This uses scary language to annihilate an element! 
handle_call({annihilate, Element}, _From, Resource) ->
    NewResource = dict:erase(Element, Resource),
    {reply, ok, NewResource};

% These are simply functions that must be defined according to gen_server
% its not so special.
handle_call(_Message, _From, Resource) ->
    {reply, error, Resource}.
handle_cast(_Message, Resource) -> 
    {noreply, Resource}.
handle_info(_Message, Resource) ->
    {noreply, Resource}.

% You need to have a method that knows when to fold em' if someone requests termination

terminate(_Reason, _Resource) ->
    ok.

% While not *strictly* nessasary, this is a cool method that allows you to inject code
code_change(_OldVersion, Resource, _Extra) -> 
    {ok, Resource}.
...