ã·ããªãª ïŒéè¡ãšATMã§ç§ãã¡ã奜ããªç¬éã¯ã圌ããåžžã«åãå Žæã«ãããšããããšã§ãã ATMã䜿çšãããšã24æéãã€ã§ããéãåŒãåºãããé ãããã§ããŸãã ãŸãã¯ãéè¡ãå¶æ¥ããŠãããšãã«éè¡ã®æ¯åºã«è¡ãã財åãžã®å®å šãªã¢ã¯ã»ã¹æš©ãããããšã確èªããŸãã ãããä¿èšŒããã«ã¯ãErlyBankãªãŒãã¡ãŒã·ã§ã³ã·ã¹ãã ãåžžã«çšŒåããŠããããšã確èªããå¿ èŠããããŸããããã»ã¹ã¯åžžã«å®è¡ãããŠããå¿ èŠããããŸãã ErlyBankã¯ããã®ç®æšãå®çŸããããã«æ瀺ããŸããã 皌åç100ïŒ ïŒ ïŒãŸãã¯æäŸã§ããéãè¿ãïŒ
çµæ ïŒOTP ã¹ãŒããŒãã€ã¶ãŒã䜿çšããŠãå®è¡äžã®ããã»ã¹ãç£èŠããããããã¢ã¯ãã£ãã§ããããšã確èªãã責任ãæã€ããã»ã¹ãäœæããŸãã
ã³ã³ãããŒã©ãŒãšã¯ïŒ
ã³ã³ãããŒã©ãŒã¯ãåããã»ã¹ãšåŒã°ãããã®ã远跡ããããã»ã¹ã§ãã åããã»ã¹ããå¹ãé£ã°ããããå Žåãã³ã³ãããŒã©ãŒã¯ãã®åã®åèµ·åæŠç¥ã䜿çšããŠåèµ·åããŸãã ãã®æ¹æ³ã«ãããErlangã·ã¹ãã ã®æ°žç¶çãªå¯çšæ§ã確ä¿ã§ããŸãã
ã³ã³ãããŒã©ã¯ã ç£èŠããªãŒãšåŒã°ãããã®ã®äžéšã§ã ã é©åã«äœæãããErlang / OTPã¢ããªã±ãŒã·ã§ã³ãèµ·åããã«ãŒãã³ã³ãããŒã©ãŒããéå§ããŸããã«ãŒãã³ã³ãããŒã©ãŒã¯ãåã³ã³ãããŒã©ãŒãç£èŠããè¿œå ã®ã³ã³ãããŒã©ãŒãŸãã¯ããã»ã¹ã远跡ããŸãã èãã¯ãã³ã³ãããŒã©ãŒãã¯ã©ãã·ã¥ããå Žåã芪ã³ã³ãããŒã©ãŒããããåèµ·åãããšããããšã§ãã«ãŒãã³ã³ãããŒã©ãŒãŸã§ç¶ããŸãã Erlangã©ã³ã¿ã€ã ã«ã¯ãã·ã¹ãã å šäœãç£èŠãããã«ãŒãã³ã³ãããŒã©ãŒãåæ¢ããå Žåã«åèµ·åããåªããã¢ãŒãããããŸãã ãããã£ãŠãã³ã³ãããŒã«ããªãŒã¯åžžã«åäœå¯èœã§ãã
ã³ã³ãããŒã©ãŒã«ã¯ã init / 1ã®ã¿ã®ãã£ãŒãããã¯ã¡ãœããããããŸãã ãã®ã¿ã¹ã¯ã¯ãåããã»ã¹ã®ãªã¹ããè¿ããåããã»ã¹ã®æŠç¥ãåèµ·åããããšã§ããããã«ãããã³ã³ãããŒã©ãŒã¯ãç£èŠãã察象ãšäœãåé¡ãçºçããå Žåã®å¯ŸåŠæ¹æ³ãèªèããŸãã
eb_serverãšã€ãã³ããããŒãžã£ãŒãåé¢
gen_eventsã«é¢ãã以åã®èšäºã§å®è£ ããããšã®1ã€ã¯ãeb_serverã¢ãžã¥ãŒã«ã®åæåã¡ãœããã§ã€ãã³ããããŒãžã£ãŒããã»ã¹ãæ瀺çã«éå§ããããšã§ããã ãã®ãããªäŸåé¢ä¿ãæã€ãµãŒããŒãç°¡åã«èµ·åãããå Žåããããå¯äžã®æ©äŒã§ããã ããããä»ã§ã¯ãã³ã³ãããŒã©ãŒã®äœ¿çšãéå§ããã³åæ¢ãããããã³ã³ãããŒã«ããªãŒã§ã€ãã³ããããŒãžã£ãŒãéå§ããããšãã§ããŸãã ãµãŒããŒã³ãŒãããeb_event_managerã®éå§ãåé€ããŸãããã
ãããè¡ãã«ã¯ãã€ãã³ããããŒãžã£ãŒãèµ·åããè¡84ãeb_serverã¢ãžã¥ãŒã«ããåé€ããŸãã ãŸãããã®å Žæã«add_handleråŒã³åºããè¿œå ããŠã eb_withdrawal_handlerãã³ãã©ãŒãã€ãã³ããããŒãžã£ãŒã«æ¥ç¶ããŸã ïŒ åã®èšäºãžã®è¿œå ãå«ãããã®ç¿»èš³ãµã€ã¯ã«ã§èª¬æãããŠãã翻蚳ãé£ç¶ããŠèªãã§å®è£ ããå Žåãäœãè¿œå ããå¿ èŠã¯ãããŸããã ;ã€ãã³ããããŒãžã£ãŒã®éå§ãé€å€ããåŸãåæåã¡ãœããã®ã³ãŒãã¯æ¬¡ã®ããã«ãªããŸã-ãã©ã³ã¹ã¬ãŒã¿ãŒã³ã¡ã³ã ïŒã ããã§ãeb_serverã¢ãžã¥ãŒã«ã®initã¡ãœããã¯æ¬¡ã®ããã«ãªããŸãã
init([]) ->
eb_event_manager:add_handler(eb_withdrawal_handler),
{ok, dict:new()}.
å€æŽåŸãeb_server.erlãèŠãã«ã¯ãããã¯ãªãã¯ããŠãã ããã
ã³ã³ãããŒã©ãŒãã¬ãŒã
ã³ã³ãããŒã©ãèšè¿°ããããã®åºæ¬çãªãã¬ãŒã ã¯ãŒã¯ã¯ã ããã§èŠãããšãã§ããŸã ã ã芧ã®ãšãããstartã¡ãœãããšåºæ¬çãªåæåã¡ãœããããããçŸæç¹ã§ã¯åèµ·åæŠç¥ãšåå«ã®ååšããªãä»æ§ãè¿ããŸãã åèµ·åã®ç¶æ ãšåã®ä»æ§ ã«ã€ããŠã¯ããã®èšäºã®ä»¥äžã®ã»ã¯ã·ã§ã³ã§èª¬æããŸãã
ã¯ã€ã€ãŒãã¬ãŒã ãeb_sup.erlãšããŠä¿åããŸãã ãã®ãã¡ã€ã«ã®åœåã¯å¥ã®èŠåã§ãã ç¹å®ã®ã°ã«ãŒãã®ã³ã³ãããŒã©ãŒã«ã¯ãåžžã«æ¥å°Ÿéšã _sup ããä»ããŸãã ããã¯å¿ é ã§ã¯ãããŸããããæšæºçãªæ¹æ³ã§ãã
åèµ·åæŠç¥
ã³ã³ãããŒã©ã«ã¯åäžã®åèµ·åæŠç¥ããããåå«ã®ä»æ§ãšçµã¿åãããŠäœ¿çšââããŠãåå«ã®1ã€ãæ»ã¬ãã©ãããå€æããŸãã 次ã®ãªã¹ãã«ã¯ãå¯èœãªåèµ·åæŠç¥ãå«ãŸããŠããŸãã
- one_for_one-åããã»ã¹ã®1ã€ãåæ¢ãããšãã³ã³ãããŒã©ãŒã¯ãããåèµ·åããŸãã ä»ã®åå«ã¯è§ŠããŸããã
- one_for_all-åããã»ã¹ã®1ã€ãåæ¢ãããšãä»ã®ãã¹ãŠã®åãåæ¢ãããã¹ãŠãåèµ·åããŸãã
- rest_for_one-åããã»ã¹ã®1ã€ãåæ¢ãããšãæ 人ãå®äºããåŸã«åå«ã®ä»æ§ã®ãªã¹ãã«å®çŸ©ãããåå«ã®ãæ®ãããããã®åŸãã¹ãŠãåéããŸãã
åèµ·åæŠç¥ã¯ã次ã®åœ¢åŒã§ç€ºãããŸãã
{RestartStrategy, MaxRetries, MaxTime}
ãã·ã¢èªã§ç解ããã®ã¯éåžžã«ç°¡åã§ãïŒ MaxTimeç§ã«1åMaxRetriesãããé »ç¹ã«åãåèµ·åããããšãã³ã³ãããŒã©ãŒã¯ãã¹ãŠã®åããã»ã¹ãçµäºããããèªäœã§åäœãåæ¢ããŸãã ããã¯ãåã®åèµ·åã®ç¡éã«ãŒããé²ãããã«è¡ãããŸãã
åå«ä»æ§ã®æ§æãšåºæ¬æŠå¿µ
ã³ã³ãããŒã©ãŒã®initã¡ãœããã¯ãåå«ä»æ§ã®ãªã¹ããè¿ã圹å²ãæãããŸãã ãããã®ä»æ§ã¯ãéå§ããããã»ã¹ãšãããè¡ãæ¹æ³ãã³ã³ãããŒã©ãŒã«äŒããŸãã ã³ã³ãããŒã©ãŒã¯ããå·Šããå³ãžãã®é åºïŒãªã¹ãã®æåããæåŸãŸã§ïŒã§ããã»ã¹ãéå§ããŸãã åèµ·åæŠç¥ã¯ã次ã®åœ¢åŒã®ã¿ãã«ã§ãã
{Id, StartFunc, Restart, Shutdown, Type, Modules}
:
Id = term()
StartFunc = {M,F,A}
M = F = atom()
A = [term()]
Restart = permanent | transient | temporary
Shutdown = brutal_kill | int()>=0 | infinity
Type = worker | supervisor
Modules = [Module] | dynamic
Module = atom()
Id㯠ãåå«ã®ä»æ§ãæ ŒçŽããããã«ã³ã³ãããŒã©å ã§ã®ã¿äœ¿çšãããŸãããäžè¬çãªèŠåã§ã¯ãã¢ãžã¥ãŒã«ã®è€æ°ã®ã€ã³ã¹ã¿ã³ã¹ãå®è¡ããŠããå Žåãé€ããã¢ãžã¥ãŒã«åãIDãšããŠäœ¿çšããŸãã åŸè ã®å ŽåãIDã«çªå·ãè¿œå ããŸãã
StartFuncã¯{ModuleãFunctionãArgs}圢åŒã®ã¿ãã«ã§ãããåŒã³åºããããã»ã¹ãéå§ããé¢æ°ã瀺ããŸãã éåžžã«éèŠ ïŒéå§é¢æ°ã¯ããã»ã¹ãéå§ããŠãªã³ã¯ããå¿ èŠããã ã {okãPid} ã {okãPidãOther}ãŸãã¯{errorãReason}ãè¿ãå¿ èŠããããŸã ã åŸæ¥ã®OTP start_linkã¡ãœããã¯ãã®ã«ãŒã«ã«åŸããŸãã ãã ããç¬èªã®ããã»ã¹ãéå§ããã¢ãžã¥ãŒã«ãå®è£ ããå Žåã¯ã spawn_linkã䜿çšããŠããããéå§ããŠãã ãã ã
åèµ·åã¯ãäžèšã®ã³ãŒããããã¯ã§èª¬æãã3ã€ã®ã¢ãã ã®ãã¡ã®1ã€ã§ãã ã¢ãã ãrestartãšããŠäœ¿çšãããå Žåãããã»ã¹ã¯åžžã«åã³éå§ãããŸãã å€ãã temporary ãã®å Žåãããã»ã¹ã¯äºåºŠãšéå§ãããŸããã ãŸãããã®å€ãã transient ãã®å Žåãããã»ã¹ã¯äºæããçµäºããå Žåã«ã®ã¿åèµ·åãããŸãã
ã·ã£ããããŠã³ã¯ãåããã»ã¹ãçµäºããæ¹æ³ãã³ã³ãããŒã©ãŒã«èª¬æããŸãã brutal_kullã¢ãã ã¯ãçµäºã¡ãœãããåŒã³åºããã«åãçµäºããŸãã ãŒããã倧ããæŽæ°ã¯ãæ£ããå®äºã®ã¿ã€ã ã¢ãŠããæå³ããŸãã ã¢ãã ã ç¡é ãã¯ããã»ã¹ãäžå¯§ã«å®äºããæ°žä¹ ã«åæ¢ããã®ãåŸ ã¡ãŸãã
Typeã¯ãåå«ãäœã§ããããã³ã³ãããŒã©ãŒã«äŒããŸãïŒå¥ã®ã³ã³ãããŒã©ãŒãŸãã¯ä»ã®ããã»ã¹ã ãããã³ã³ãããŒã©ãŒã®å Žåãã¹ãŒããŒãã€ã¶ãŒã¢ãã ã䜿çšããããã§ãªãå Žåã¯ã¯ãŒã«ãŒã¢ãã ã䜿çšããŸãã
ã¢ãžã¥ãŒã«ã¯ããã®ããã»ã¹ã圱é¿ããã¢ãžã¥ãŒã«ã®ãªã¹ãããŸãã¯ãåçãã¢ãã ã§ãã ãã®å€ã®ãªã¹ãã«ããã±ãŒã¹ã®95ïŒ ã§ã¯ãåäžã®OTPãã£ãŒãããã¯ã¢ãžã¥ãŒã«ã䜿çšããŸãã ããã»ã¹ãgen_eventã§ããå Žåããåçãã䜿çšãããŸããããã¯ãã¢ãžã¥ãŒã«ãžã®åœ±é¿ãåçã§ããããã§ãïŒããã«å®çŸ©ã§ããªãããŸããŸãªãã³ãã©ãŒïŒã ãã®ãªã¹ãã¯ãªãªãŒã¹ç®¡çã«ã®ã¿äœ¿çšããããã®èšäºã®æèã§ã¯éèŠã§ã¯ãããŸãããããªãªãŒã¹ç®¡çã«é¢ããä»åŸã®èšäºã§äœ¿çšãããŸãã
ãã㌠ãããªã«çãæéã§åŠã¶ã¹ãå€ãã®æ å ±ã åå«ä»æ§ã®åœ¢åŒãšããŸããŸãªåèµ·åæŠç¥ãèŠããã®ã«ããªãæéãããã£ãã®ã§ãããã«ãããè¡ãããšãã§ããªããŠãå¿é ããªãã§ãã ããã ã³ã³ãããŒã©ããã¥ã¢ã«ã®æ å ±ã¯ãã€ã§ãæŽæ°ã§ããŸã ã
ã€ãã³ããããŒãžã£ãŒã®åå«ä»æ§
ãµãŒããŒãããã«äŸåããŠãããããæåã«éå§ããã®ã¯ã€ãã³ããããŒãžã£ãŒã§ãã åå«ã®ä»æ§ã¯æ¬¡ã®ããã«ãªããŸãã
EventManager = {eb_event_manager,{eb_event_manager, start_link,[]},
permanent,2000,worker,dynamic}.
åå«ä»æ§ã®æ§æã«é¢ããã»ã¯ã·ã§ã³ãèªãã åŸããã®ã³ãŒãã¯éåžžã«ç°¡åãªã¯ãã§ãã åãã©ã¡ãŒã¿ãŒã®å¹æãç解ããã«ã¯ãæ»ã£ãŠèª¬æã確èªããå¿ èŠããããŸãããããã¯ãŸã£ããæ£åžžã§ãïŒ æ°åã§ãã¹ãŠãããªãããå¿ããããããã³ãŒããé·åŒãããŠç解ããæ¹ãé©åã§ãã ä»æ§ã®èª¬æã§ãå¥åŠãªãããšã®1ã€ã¯ãã¢ãžã¥ãŒã«ã®ãªã¹ãããåçãïŒ åçããã®å Žåãããã¯ã¢ãã -çŽTranslator ïŒãšããŠç€ºãããšã ãšæããŸãã ããã¯ãgen_eventã«ã€ããŠè©±ããŠããããã«è¡ãããããã§äœ¿çšãããã¢ãžã¥ãŒã«ã®ãªã¹ãã¯åçã§ãã ãã³ãã©ãŒãæ¥ç¶ãããŠããŸãïŒ äœæ¥äžã«å€æŽã§ããæ°-çŽç¿»èš³è ïŒã ãã以å€ã®å Žåã¯ãããã»ã¹ã䜿çšãããã¹ãŠã®ã¢ãžã¥ãŒã«ããªã¹ãããå¿ èŠããããŸãã
åå«ä»æ§ãå«ããåŸã®åæåã¡ãœããã¯æ¬¡ã®ãšããã§ãã
init([]) ->
EventManager = {eb_event_manager,{eb_event_manager, start_link,[]},
permanent,2000,worker,dynamic},
{ok,{{one_for_one,5,10}, [EventManager]}}.
ååå«ä»æ§ãå€æ°ã«å²ãåœãŠãŠãããæ»ãå€ã«çŽæ¥ä»æ§ãå ¥ããã®ã§ã¯ãªãããããã®å€æ°ã®å 容ã䜿çšããŠè¿ãããšã奜ã¿ãŸãã Erlangã®æ倧ã®ããŠã¢ãã³ã·ã®1ã€ã¯ãããã°ã©ããŒããªã¹ããšã¿ãã«ãæ·±ãåã蟌ãã§ãã©ãããçµãããã©ãããå§ãŸãããããããªããšãã«è¡šç€ºãããã®ã§ããããããå€æ°ã«å²ãåœãŠãããšããå§ãããŸãã
ã³ã³ãããŒã©ãŒãã³ã³ãã€ã«ããŠå®è¡ãããšïŒäŸ¡å€ããããšæããŸãïŒïŒãã³ã³ãããŒã©ãŒã«å±ããstart_linkã¡ãœãããéå§ããåŸã whereisïŒeb_event_managerïŒãå ¥åãããšãã³ãã³ãã¯ã€ãã³ããããŒãžã£ãŒããã»ã¹ã®èå¥åïŒ pid ïŒãè¿ããŸãã 次ã«ã exitïŒwhereisïŒeb_supïŒãkillïŒãå®è¡ããŠã³ã³ãããŒã©ãŒã匷å¶çµäºã ãeb_event_managerèå¥åãå床ååŸããããšãããšãããã»ã¹ã匷å¶çµäºããããããå®çŸ©ãããŠããªããšããã¡ãã»ãŒãžã衚瀺ãããŸãã
ãŸãã楜ãã¿ã®ããã«ãã³ã³ãããŒã©ãŒã®å¶åŸ¡äžã§äœæ¥äžã«eb_event_managerã匷å¶çµäºããŸãã æ°ç§åŸ ã£ãŠããããã»ã¹ã確èªããŠãã ããã 圌ã¯å埩ããªããã°ãªããŸããïŒ
ãµãŒããŒãšATM
åå«ã®æå®ãšäžèšã®äŸã®å©ããåããŠããµãŒããŒãšéè¡ãèµ·åããã®ã«ååãªç¥èãå¿ èŠã§ãã ææŠãé åçã ãšæããããä»ãããã£ãŠã¿ãŠãã ããã ããã§ãªãå Žåã¯ã以äžã®äž¡æ¹ã®ä»æ§ãåŒçšããŸããã
Server = {eb_server, {eb_server, start_link, []},
permanent,2000,worker,[eb_server]},
ATM = {eb_atm, {eb_atm, start_link, []},
permanent,2000,worker,[eb_atm]},
ãããã®ä»æ§ãäœæããããåæåã¡ãœããã«ãã£ãŠè¿ããããªã¹ãã«ããããè¿œå ããŸãã ã€ãã³ããããŒãžã£ãŒã®åŸã«é 眮ããŠãã ããã
ãããã¯ãªãã¯ãããš ãå®æããeb_sup.erlã確èªã§ããŸã ã
å®è¡æã«åãè¿œå ããã³åé€ãã
æ®å¿µãªããããã®ã¡ã«ããºã ãErlyBankã«æ¿å ¥ããããã®æ©ç¥ã«å¯ãã ã¹ã¯ãªãããæãä»ãããšãã§ããŸããã§ãããã start_childããã³delete_childã¡ãœããã䜿çšããŠãæ¢ã«å®è¡äžã®ã³ã³ãããŒã©ãŒããã»ã¹ã«åä»æ§ãåçã«è¿œå ããã³åé€ããæ©èœã«æ³šæããããšãéèŠã ãšæããŸããã
ãããã¯éåžžã«åçŽãªã®ã§ãããã§èšåããã¬ã€ãã¯ç¹°ãè¿ããŸããã çŽæ¥ã¢ã¯ã»ã¹ããŠããããã®æ¹æ³ã«æ £ããããšãã§ããŸãã
ãããã«
ã³ã³ãããŒã©ãŒã«é¢ãããã®èšäºã§ã¯ãã³ã³ãããŒã«ããªãŒãåèµ·åæŠç¥ãåå«ã®ä»æ§ãåå«ã®åçãªè¿œå ãšåé€ãªã©ã®æŠå¿µã玹ä»ããŸããã
ããã§ãErlang / OTPã·ãªãŒãºã®æŠèŠã®4çªç®ã®èšäºãçµãããŸãã 5çªç®ã®èšäºã¯æºåãã§ããŠãããæ°æ¥äžã«å ¬éãäºå®ãããŠããã ã¢ããªã±ãŒã·ã§ã³ãæäŸãããŸã ã
ã·ãªãŒãºã®èšäº
4. ã³ã³ãããŒã©ãŒã䜿çšããŠErlyBankããããŒãç¶æ ã«ä¿ã€ïŒçŸåšã®èšäºïŒ
3. gen_eventã®æŠèŠïŒè«æ±æžå€æŽã®éç¥
翻蚳ã®èè ã¯é¢ä¿è ã§ãïŒ
2. gen_fsmã®æŠèŠïŒErlyBank ATM
1. gen_serverã®æŠèŠïŒErlyBank
0. Open Telecom Platform / Open Telecommunication PlatformïŒOTP / OTPïŒã®æŠèŠ
-1ã èæ¯