programming erlang ch10 - andstudy/forge GitHub Wiki

Chapt 10. ๋ถ„์‚ฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ

๋ถ„์‚ฐ ๋ชจ๋ธ

  1. ๋ถ„์‚ฐ ์–ผ๋žญ : LANํ™˜๊ฒฝ
  2. ์†Œ์ผ“-๊ธฐ๋ฐ˜ ๋ถ„์‚ฐ : WANํ™˜๊ฒฝ

์ €์ž์˜ ์ž‘์—… ์ ˆ์ฐจ

  1. ๋น„๋ถ„์‚ฐ ์–ผ๋žญ ์„ธ์…˜์—์„œ ์ž‘์—…
  2. ๋™์ผํ•œ PC์—์„œ ํ…Œ์ŠคํŠธ
  3. ๋ฌผ๋ฆฌ์ ์œผ๋กœ ๋ถ„๋ฆฌ๋œ ๋‘ PC์—์„œ ํ…Œ์ŠคํŠธ

์ด๋ฆ„์„œ๋ฒ„

  • ์ž‘์—…์ ˆ์ฐจ

    • ๋‹จ๊ณ„1: ๋น„๋ถ„์‚ฐ ์–ผ๋žญ ์‹œ์Šคํ…œ์—์„œ ์ด๋ฆ„ ์„œ๋ฒ„ ์ž‘์„ฑ, ํ…Œ์ŠคํŠธ

      -module(kvs).
      -export([start/0, store/2, lookup/1]). 
      % compile(export_all)์€ ์ž‘๋™ํ•˜์ง€ ์•Š์Œ -> rpc๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋•Œ๋ฌธ..
      
      start() -> register(kvs, spawn(fun() -> loop() end)). 
      
      store(Key, Value) -> 
      	rpc({store, Key, Value}). 
      
      lookup(Key) -> rpc({lookup, Key}). 
      
      rpc(Q) ->  kvs ! {self(), Q},  
      	receive
      	    {kvs, Reply} -> Reply  
      	end. 
      
      loop() ->  
      	receive
      	    {From, {store, Key, Value}} ->
      		put(Key, {ok, Value}), %ํ”„๋กœ์„ธ์Šค์‚ฌ์ „์˜ put์ด์šฉ
      		From ! {kvs, true},
      		loop();
      	    {From, {lookup, Key}} ->
      		From ! {kvs, get(Key)}, %ํ”„๋กœ์„ธ์Šค์‚ฌ์ „์˜ get์ด์šฉ
      		loop()
      	end.
      
  • ๋‹จ๊ณ„2: ๋™์ผ๋จธ์‹ ์˜ ๋‘ ๋…ธ๋“œ์—์„œ ํ…Œ์ŠคํŠธ

    • gandalf๋…ธ๋“œ ์ƒ์„ฑ

      $ erl -sname gandalf
      (gandalf@localhost) 1> kvs:start().
      true
      
    • bilbo๋…ธ๋“œ ์ƒ์„ฑ ๋ฐ ๊ธฐ๋Šฅ ํ…Œ์ŠคํŠธ

      $ erl -sname bilbo
      (bilbo@localhost) 1> kvs:start().
      true
      (bilbo@localhost) 2> rpc:call('gandalf@localhost', kvs, store, [weather, fine]).
      true
      (bilbo@localhost) 3> rpc:call('gandalf@localhost', kvs, lookup, [weather]).
      {ok,fine}
      
  • ๋‹จ๊ณ„3: ๋™์ผ ๋กœ์ปฌ ์˜์—ญ ๋„คํŠธ์›Œํฌ ์ƒ์— ์„œ๋กœ ๋‹ค๋ฅธ PC์—์„œ ํ…Œ์ŠคํŠธ

    • ์ฝ”๋“œ

      %์ฒซ๋ฒˆ์งธ pc
      PC1> erl -sname foo -setcookie abc
      
      %๋‘๋ฒˆ์งธ pc
      PC2> erl -sname bar -setcookie abc
      
    • ์„ค๋ช…

      • sname : short name -> DNS์„œ๋น„์Šค ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์„๋•Œ ์œ ์ผํ•œ ๋ฐฉ๋ฒ•
      • ๋‘ ๋…ธ๋“œ๋Š” ๊ฐ™์€ ์ฟ ํ‚ค๋ฅผ ๊ฐ–์•„์•ผ ํ•œ๋‹ค.
      • ์‹คํ–‰ํ•˜๋ ค๋Š” ์ฝ”๋“œ ๋ฒ„์ „์ด ๊ฐ™์•„์•ผ ํ•œ๋‹ค.
  • ๋‹จ๊ณ„4: ๋‹ค๋ฅธ ๋„๋ฉ”์ธ์— ์†ํ•ด์žˆ๋Š” ๋‘๋Œ€์˜ ๋จธ์‹ ์—์„œ ์ด๋ฆ„ ์„œ๋ฒ„ ํ…Œ์ŠคํŠธ

    • epmd๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ 4369ํฌํŠธ๊ฐ€ ์—ด๋ ค์žˆ๋Š”์ง€ ํ™•์ธ.

    • ๋ถ„์‚ฐ ์–ผ๋žญ์ด ์‚ฌ์šฉํ•  ํฌํŠธ ๋ฒ”์œ„๋ฅผ ์ •ํ•˜๊ณ  ํฌํŠธ๊ฐ€ ์—ด๋ ค์žˆ๋Š”์ง€ ํ™•์ธ

      $ erl -name ... -setcookie ,,, -kernel inet_dist_listen_min Min inet_dist_listen_max Max
      

๋ถ„์‚ฐ ํ”„๋ฆฌ๋ฏธํ‹ฐ๋ธŒ

  • ๋ถ„์‚ฐ ํ”„๋กœ๊ทธ๋žจ์˜ BIF

       @spec spawn(Node, Fun) -> Pid
       @spec spawn(Node, Mod, Func, ArgList) -> Pid    % apply์— ์˜ํ•ด ์ˆ˜ํ–‰๋˜๋Š” ํ”„๋กœ์„ธ์Šค ์ƒ์„ฑ
       @spec spawn_link(Node, Fun) -> Pid
       @spec spawn_link(Node, Mod, Func, ArgList) -> Pid    % ์ƒˆ ํ”„๋กœ์„ธ์Šค๊ฐ€ ํ˜„์žฌ ํ”„๋กœ์„ธ์Šค์™€ ์—ฐ๊ฒฐ
       @spec disconnect_node(Node) -> bool() | ignore  % ๊ฐ•์ œ ๋…ธ๋“œ ๋Š๊ธฐ
       @spec moniter_node(Node, Flag) -> true % Flag๊ฐ€ true๋ฉด ๋ชจ๋‹ˆํ„ฐ๋ง ์ผœ์ง, false๋ฉด ๋ชจ๋‹ˆํ„ฐ๋ง ๊บผ์ง, {nodeup, Node}์™€ {nodedown, Node}๋ฅผ ๋ฐ›์Œ
       @spec node() -> Node
       @spec node(Arg) -> Node
       @spec nodes() -> [Node]
       @spec is_alive() -> bool()
       {RegName, Node} ! Msg   %๋“ฑ๋ก๋œ ๋…ธ๋“œ์— ๋ฉ”์‹œ์ง€ ์ „์†ก
    
  • ์›๊ฒฉ ๋„์šฐ๊ธฐ

      -module(dist_demo).
      -export([rpc/4, start/1]).
      
      start(Node) ->
      	spawn(Node, fun() -> loop() end).
      
      rpc(Pid, M, F, A) ->
      	Pid ! {rpc, self(), M, F, A},
      	receive
      		{Pid, Response} ->
      			Response
      	end.
      
      loop() -> receive
      		{rpc, Pid, M, F, A} ->
      			Pid ! {self(), (catch apply(M, F, A))},
      			loop()
      	end.
    
  • ์›๊ฒฉ ๋…ธ๋“œ ์‹คํ–‰

      (foo@localhost) Pid = dist_demo:start( bar@localhost ).
      <0.49.0>j
      (bar@localhost)5> dist_demo:rpc( Pid, os, cmd, [notepad]).
    

๋ถ„์‚ฐํ”„๋กœ๊ทธ๋ž˜๋ฐ์šฉ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

  • ์›๊ฒฉ๋…ธ๋“œ ์‹คํ–‰์˜ ํ‘œ์ค€๋ฐฐํฌํŒ

      call(Node, Mod, Function, Args) -> Result | {badrpc, Reason}
    

์ฟ ํ‚ค ๋ณดํ˜ธ ์‹œ์Šคํ…œ

  • ์ฟ ํ‚ค ์„ค์ • ๋ฐฉ๋ฒ•
    1. $HOME/.erlang.cookieํŒŒ์ผ์— ๋™์ผํ•œ ์ฟ ํ‚ค ์ €์žฅ
    2. ๋ช…๋ นํ–‰ ์ธ์ˆ˜ -setcookie๋กœ ๋งค์ง ์ฟ ํ‚ค ์„ค์ •
    3. BIF erlang:set_cookie(node(), Cookie)์‚ฌ์šฉ

์†Œ์ผ“-๊ธฐ๋ฐ˜ ๋ถ„์‚ฐ

  • ๋ถ„์‚ฐ์–ผ๋žญ ๋ฌธ์ œ์  : ๋ณด์•ˆ์ด ์ทจ์•ฝํ•˜๋‹ค.

  • ๋ถ€๋ก D -> lib_chan ์‚ฌ์šฉํ•œ ์†Œ์ผ“ ๊ธฐ๋ฐ˜ ๋ถ„์‚ฐ

  • ๊ตฌ์„ฑ ์„ค์ • ํŒŒ์ผ

      {port, 2223}.
      {service, chat, password,"AsDT67aQ",mfa,mod_chat_controller,start,[]}.
    
  • ์„œ๋ฒ„ ์ฝ”๋“œ

      -module(mod_name_server).
      -export([start_me_up/3]).
      
      start_me_up(MM, _ArgsC, _ArgS) ->
          loop(MM).
      
      loop(MM) ->
          receive
      	{chan, MM, {store, K, V}} ->
      	    kvs:store(K, V),
      	    loop(MM);
      	{chan, MM, {lookup, K}} ->
      	    MM ! {send, kvs:lookup(K)},
      	    loop(MM);
      	{chan_closed, MM} ->
      	    true
          end.
    
  • ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ

      {ok, Pid} = lib_chan:connect( "localhost", 1234, nameServer, "ABXy45", "").
      lib_chan:cast(Pid, {store, joe, "write a book"}).
      lib_chan:rpc(Pid, {lookup, joe}).
      lib_chan:rpc(Pid, {lookup, jim}).
    
โš ๏ธ **GitHub.com Fallback** โš ๏ธ