Open Telecom Platform / Open Telecommunication PlatformïŒOTP / OTPïŒã®æŠèŠ
ããã¯ãErlang / OTPã«é©çšããããã¹ãŠã®æŠå¿µã説æããäžé£ã®èšäºã®æåã®èšäºã§ãã å°æ¥ããããã¹ãŠã®èšäºãèŠã€ããããšãã§ããããã«ãç¹å¥ãªã¿ã°ã§ããŒã¯ãããŠããŸãïŒ OtpçŽ¹ä» ïŒ ããã§Habrã¿ã°ãžã®ãªã³ã¯ãäœæããŸãã ïŒã OTPã®æŠèŠã§çŽæããããã«ãErlybankã®äººã ã®åœã®éè¡å£åº§ãæäŸãããµãŒããŒãäœæããŸãïŒãããç§ã¯æããªååã奜ãã§ãïŒã
ã·ããªãªïŒ ErlyBankã¯æŽ»åãéå§ããŸãããããŒãžã£ãŒã¯ãéèŠãªé¡§å®¢ããŒã¹ã®éè¡å£åº§ã管çããããã®ã¹ã±ãŒã©ãã«ãªã·ã¹ãã ãäœæããããšã«ãããé©åã«ç«ã¡äžããå¿ èŠããããŸãã ã¢ãŒã©ã³ã®åã«ã€ããŠèããŠã圌ãã¯ç§ãã¡ãéã£ãŠãã£ãŠãããïŒ ããããç§ãã¡ãäœã®ããã«è¯ãã®ããèŠãããã«ã圌ãã¯ãŸããã¢ã«ãŠã³ããäœæããã³åé€ããå ¥éãè¡ãããéãåŒãåºãããšãã§ããã·ã³ãã«ãªãµãŒããŒãèŠãããšæã£ãŠããŸãã 顧客ãæãã§ããã®ã¯ãããã¿ã€ãã§ãããçç£ã«æå ¥ã§ãããã®ã§ã¯ãããŸããã
ç®çïŒ gen_serverã䜿çšããŠç°¡åãªãµãŒããŒãšã¯ã©ã€ã¢ã³ããäœæããŸãã ããã¯åãªããããã¿ã€ãã§ãããããã¢ã«ãŠã³ãã¯ã¡ã¢ãªã«ä¿åãããååã§èå¥ãããŸãã ã¢ã«ãŠã³ããäœæããããã«ä»ã®æ å ±ã¯å¿ èŠãããŸããã ãããŠãã¡ãããå ¥åºéæäœã®ç¢ºèªãè¡ããŸãã
æ³šïŒ Erlangæ§æã®æåã®ç¥èã¯ãã§ã«ãããšæããŸãã ããã§ãªãå Žåã¯ã åå¿è åãã®ãªãœãŒã¹ã®çãèŠçŽãèªãã§ãErlangãåŠç¿ã§ãããªãœãŒã¹ãèŠã€ããããšããå§ãããŸãã
æºåãã§ãããããç¶ããèªãããã¯ãªãã¯ããŠå§ããŸãããïŒ ïŒãŸã èšäºå šäœãèªãã§ããªãå Žå:)ïŒ
gen_serverã«ã¯äœããããŸããïŒ
gen_serverã¯ãã¯ã©ã€ã¢ã³ããµãŒããŒã¢ãŒããã¯ãã£ãå®è£ ããããã®ã€ã³ã¿ãŒãã§ã€ã¹ã¢ãžã¥ãŒã«ã§ãã ãã®OTPã¢ãžã¥ãŒã«ã䜿çšãããšããç¡æãã§å€ãã®ç¹å žãåŸãããŸãããããã«ã€ããŠã¯åŸã§èª¬æããŸãã ãŸããã·ãªãŒãºã®åŸåã§ã¯ãã¹ãŒããŒãã€ã¶ãŒãšãšã©ãŒã¡ãã»ãŒãžã«ã€ããŠèª¬æããŸãã ãããŠããã®ã¢ãžã¥ãŒã«ã¯ã»ãšãã©å€ãããŸããã
gen_serverã¯ã€ã³ã¿ãŒãã§ãŒã¹ã§ãããããããã€ãã®ã¡ãœãããå®è£ ããããé¢æ°ïŒã³ãŒã«ããã¯ïŒãè¿ãå¿ èŠããããŸãã
- init / 1-ãµãŒããŒã®åæåã
- handle_call / 3-åŒã³åºãèŠæ±ãåŠçããŸãã åŒã³åºãèŠæ±ãéä¿¡ããã¯ã©ã€ã¢ã³ãã¯ãå¿çãåä¿¡ãããŸã§ãããã¯ãããŸãã
- handle_cast / 2-ãã£ã¹ãèŠæ±ãåŠçããŸãã ãã£ã¹ãèŠæ±ã¯ãéåæã§ããããšãé€ããŠãåŒã³åºãèŠæ±ãšåãã§ãã ã¯ã©ã€ã¢ã³ãã¯ãã£ã¹ããªã¯ãšã¹ãäžãåŒãç¶ãåäœããŸãã
- handle_info / 2-äžçš®ã®ããã¹ãŠããã£ãããã¡ãœããã ãµãŒããŒãã¡ãã»ãŒãžãåä¿¡ãããããåŒã³åºãã§ããã£ã¹ãã§ããªãå Žåãããã«æ¥ãŸãã ãã®ãããªã¡ãã»ãŒãžã®äŸã¯ããµãŒããŒãå¥ã®ããã»ã¹ã«æ¥ç¶ïŒãªã³ã¯ïŒãããŠããå Žåã®EXITããã»ã¹ã¡ãã»ãŒãžã§ãã
- terminate / 2-ãµãŒããŒãåæ¢ãããšåŒã³åºãããŸãã ããã§ãåºçºåã«å¿ èŠãªæäœãè¡ãããšãã§ããŸãã
- code_change / 3-ãµãŒããŒããªã¢ã«ã¿ã€ã ã§æŽæ°ããããšãã«åŒã³åºãããŸãã ãã®ã¡ãœããã«ã¹ã¿ããé 眮ããå¿ èŠããããŸãã ãã®æ¹æ³ã«ã€ããŠã¯ãä»åŸã®èšäºã§è©³ãã説æããŸãã
ãµãŒããŒã¹ã±ã«ãã³
ç§ã¯åžžã«äžè¬çãªã¹ã±ã«ãã³ã§æžãå§ããŸãã ãã¡ãã§èŠããŸã ã
泚ïŒã¹ããŒã¹ãä¹±éã«ããªãããã«ãããã«ãã¡ã€ã«ã®å 容ã貌ãä»ããŸãããã§ããã ãæ©ããã¹ãŠããªã³ã¯ããããšããŸãã ããã«éèŠãªã³ãŒãã¹ãããããæçš¿ããŸãã
ã芧ã®ãšãããã¢ãžã¥ãŒã«ã¯eb_serverãšåŒã°ããŸã ã äžèšã§ç€ºãããã¹ãŠã®ã³ãŒã«ããã¯ã¡ãœãããå®è£ ããå¥ã®
start_link/0
è¿œå ããŸããããã¯ãµãŒããŒã®èµ·åã«äœ¿çšãããŸãã ãã®ã³ãŒãã®äžéšãäžã«æ¿å ¥ããŸããïŒ
start_linkïŒïŒ-> gen_serverïŒstart_linkïŒ{local ,? SERVER} ,? MODULEã[]ã[]ïŒã
ããã¯gen_serverã¢ãžã¥ãŒã«ã®start_link / 4ã¡ãœãããåŒã³åºããŸãããã®ã¡ãœããã¯ãµãŒããŒãèµ·åãã
SERVER
ãã¯ãã§å®çŸ©ãããatomã䜿çšããŠããã»ã¹ãç»é²ããŸããããã©ã«ãã¯ã¢ãžã¥ãŒã«ã®ååã§ãã æ®ãã®åŒæ°ã¯gen_serverã¢ãžã¥ãŒã«ã§ãããã®å Žåã¯ããèªäœã§ããããã®ä»ã®åŒæ°ã¯ãªãã·ã§ã³ã®æåŸã«ãããŸãã åŒæ°ã空ã®ãŸãŸã«ããŠïŒå¿ èŠãããŸããïŒããªãã·ã§ã³ãæå®ããŸããã ãã®æ¹æ³ã®è©³çŽ°ã«ã€ããŠã¯ã gen_serverã®ããã¥ã¢ã«ããŒãžãåç §ããŠãã ããã
ErlybankãµãŒããŒã®åæå
ãµãŒããŒã¯ãgen_serverïŒstart_linkã¡ãœããã§éå§ããŸãããã®ã¡ãœããã¯ããµãŒããŒã®initã¡ãœãããåŒã³åºããŸãã ãã®äžã§ããµãŒããŒã®ç¶æ ïŒããŒã¿ïŒãåæåããå¿ èŠããããŸãã ç¶æ ïŒããŒã¿ïŒã¯ãã¢ãã ãå€ã®ãªã¹ããé¢æ°ãªã©ãäœã§ãããŸããŸããïŒ ãã®ç¶æ ïŒããŒã¿ïŒã¯ãåã³ãŒã«ããã¯ã¡ãœããã§ãµãŒããŒã«éä¿¡ãããŸãã ç§ãã¡ã®å Žåããã¹ãŠã®ã¢ã«ãŠã³ããšãã®æ®é«å€ã®ãªã¹ããä¿æããããšæããŸãã ããã«ãååã§ã¢ã«ãŠã³ããæ€çŽ¢ããããšæããŸãã ãã®ããã«ãããŒãšå€ã®ãã¢ãã¡ã¢ãªã«ä¿åããdictã¢ãžã¥ãŒã«ã䜿çšããŸãã
ãªããžã§ã¯ãæåã®å¿ãžã®æ³šæïŒ OOPããæ¥ãå Žåãã€ã³ã¹ã¿ã³ã¹å€æ°ã®ãµãŒããŒç¶æ ãååŸã§ããŸãã åã³ãŒã«ããã¯ã¡ãœããã§ã¯ããããã®å€æ°ã䜿çšã§ããŸãããå€æŽããããšãã§ããŸãã
ãããã£ãŠãinitã¡ãœããã®æçµåœ¢åŒã¯æ¬¡ã®ãšããã§ãã
initïŒ_ArgsïŒ-> {okãdictïŒnewïŒïŒ}ã
æ¬åœã«ç°¡åã§ãïŒ ãããã£ãŠãErlybankãµãŒããŒã®å Žåãinitãè¿ãæåŸ å€ã®1ã€ã¯
{ok, State}
ã§ãã ç¶æ ïŒããŒã¿ïŒãšããŠokãšç©ºã®é£æ³é åãè¿ãã ãã§ãã ãŸããåŒæ°ãinitïŒãŸã 空ã®é åãstart_linkããèŠããŠããŸãïŒã«æž¡ããªããããåŒæ°ã®åã«ã_ããä»ããŠããã瀺ããŸãã
é»è©±ããããã£ã¹ãããŸããïŒ ããã«è³ªåããããŸã
ãµãŒããŒã®ã»ãšãã©ãéçºããåã«ãcallã¡ãœãããšcastã¡ãœããã®éããããäžåºŠç°¡åã«ç¢ºèªããŸãã
åŒã³åºãã¯ãã¯ã©ã€ã¢ã³ãããããã¯ããã¡ãœããã§ãã ããã¯ãã¯ã©ã€ã¢ã³ãããµãŒããŒã«ã¡ãã»ãŒãžãéä¿¡ãããšããç¶è¡ããåã«å¿çãåŸ ã€ããšãæå³ããŸãã ããšãã°ãç¹å®ã®å£åº§ã®æ®é«ãèŠæ±ãããªã©ãçããå¿ èŠãªå Žåã«åŒã³åºãã䜿çšããŸãã
ãã£ã¹ãã¯ã éããããã³ã°ãŸãã¯éåæã¡ãœããã§ãã ããã¯ãã¯ã©ã€ã¢ã³ãããµãŒããŒã«ã¡ãã»ãŒãžãéä¿¡ãããšãããµãŒããŒãå¿çããã®ãåŸ ããã«ãããã«æ©èœãç¶ããããšãæå³ããŸãã Erlangã¯ãããã»ã¹ã«éä¿¡ããããã¹ãŠã®ã¡ãã»ãŒãžãå®å ã«å°éããããšãä¿èšŒããããã«ãªããŸããããããã£ãŠããµãŒããŒå¿çãæããã«å¿ èŠãªãå Žåã¯ããã£ã¹ãã䜿çšããå¿ èŠããããŸãã ã€ãŸããã¡ãã»ãŒãžãå°çããããšã確èªããããã ãã«é»è©±ããããå¿ èŠã¯ãããŸãããErlangã«ããŸãããã ããã
éè¡å£åº§ãäœæãã
æåã®ã¹ã¿ãŒã:) Erlybankã«ã¯æ°ããã¢ã«ãŠã³ããäœæããæ¹æ³ãå¿ èŠã§ãã ããã«èªåèªèº«ã確èªããŠãã ããïŒéè¡å£åº§ãäœæããå¿ èŠãããå Žåã ãã£ã¹ããŸãã¯é»è©±ã䜿çšããŸããïŒ é«å質ã ãšæã...ã©ã®ãããªäŸ¡å€ãè¿ãããã¹ããïŒ é»è©±ãéžæããå Žå-ããªãã¯æ£ããã§ãããããã§ãªãå Žåã¯å€§äžå€«ã§ãã ã¢ã«ãŠã³ãã«äŸåããã ãã§ãªããã¢ã«ãŠã³ããæ£åžžã«äœæãããããšã確èªããå¿ èŠããããŸãã ç§ãã¡ã®ã±ãŒã¹ã§ã¯ãçŸåšãšã©ãŒããã§ãã¯ããŠããªãã®ã§ããã£ã¹ãã§å®è¡ããŸãã
æåã«ãã¢ãžã¥ãŒã«ã®å€éšããåŒã³åºããŠã¢ã«ãŠã³ããäœæããAPIã¡ãœãããäœæããŸãã
%% ------------------------------------------------ -------------------- %%é¢æ°ïŒcreate_accountïŒååïŒ-> ok %%説æïŒååãNameã®äººã®éè¡å£åº§ãäœæããŸã %% ------------------------------------------------ -------------------- create_accountïŒååïŒ-> gen_serverïŒcastïŒïŒSERVERã{createãName}ïŒã
start_linkã§
?SERVER
ãšããŠç»é²ãããµãŒããŒã«ãã£ã¹ãèŠæ±ãéä¿¡ããŸãã èŠæ±ã¯ãããŒããŒ
{create, Name}
ã§ãã ãã£ã¹ãã䜿çšãããšããokããããã«è¿ãããŸããããã¯ãé¢æ°ã«ãã£ãŠãè¿ãããŸãã
次ã«ããã®ãã£ã¹ããåŠçãããµãŒããŒã®ã³ãŒã«ããã¯ã¡ãœãããèšè¿°ããå¿ èŠããããŸãã
handle_castïŒ{äœæãåå}ãç¶æ ïŒ-> {noreplyãdictïŒstoreïŒNameã0ãStateïŒ}; handle_castïŒ_MsgãStateïŒ-> {noreplyãå·}ã
ã芧ã®ãšãããhandle_castã®å¥ã®å®çŸ©ãè¿œå ããŠãå¥ã®ãªã¯ãšã¹ããåŠçããŸããã 次ã«ãçŸåšã®ã¢ã«ãŠã³ãã®æ®é«ã衚瀺ããå€0ã®é åã«ä¿åããŸãã handle_castã¯
{noreply, State}
è¿ããŸã
{noreply, State}
ã¯ãµãŒããŒã®æ°ããç¶æ ïŒããŒã¿ïŒã§ãã ãã®ãããä»åã¯ã¢ã«ãŠã³ããè¿œå ãããæ°ããé åãè¿ããŸãã
ãŸããæåŸã«ããã£ãããªãŒã«ãæ©èœãè¿œå ããããšã«æ³šæããŠãã ããã ããã¯ããã ãã§ãªããäžè¬çãªãã¹ãŠã®æ©èœèšèªã§ãå®è¡ããå¿ èŠããããŸãã ãã®ã¡ãœããã¯ãã¡ãã»ãŒãžãéãã«é£²ã¿èŸŒãããã«ã®ã¿äœ¿çšã§ããŸã:)ããŸãã¯å¿ èŠãªå Žåã¯äŸå€ãã¹ããŒããå¿ èŠããããŸãã ç§ãã¡ã®å Žåãç§ã¯ãããéãã«åŠçããŸãã
ããã«ããæç¹ã§ã®eb_server.erlãã¡ã€ã«ã®å 容ã
çŸéé é
ã¯ã©ã€ã¢ã³ãã®Erlybankã«ãå ¥éçšã®APIãšåºæ¬çãªå°åæãè¿œå ããããšãçŽæããŸããã ãããã£ãŠãå£åº§ã«ãéãå ¥éããåã«ãµãŒããŒãå£åº§ã®ååšã確èªããå¿ èŠãããããã«ãé éAPIã¡ãœãããäœæããå¿ èŠããããŸãã ãããŠããäžåºŠãèªåèªèº«ããã§ãã¯ããŠãã ããïŒ
cast call
ïŒ çãã¯ç°¡åã§ããé»è©±ã§ãã ãéãå±ããããšã確èªãããŠãŒã¶ãŒã«éç¥ããå¿ èŠããããŸãã
åãšåæ§ã«ãæåã«APIã¡ãœãããèšè¿°ããŸãã
%% ------------------------------------------------ -------------------- %%é¢æ°ïŒdepositïŒååãéé¡ïŒ-> {okãBalance} | {ãšã©ãŒãçç±} %%説æïŒName'sã¢ã«ãŠã³ããžã®å ¥éé¡ã ãè¿ããŸã æåããå Žåã¯%% balanceãããã§ãªãå Žåã¯ãšã©ãŒãšçç±ãè¿ããŸãã %% ------------------------------------------------ -------------------- ãããžããïŒååãéé¡ïŒ-> gen_serverïŒåŒã³åºãïŒïŒSERVERã{depositãNameãAmount}ïŒã
ç®ç«ã£ããã®ã¯äœããããŸããããµãŒããŒã«ã¡ãã»ãŒãžãéä¿¡ããã ãã§ãã äžèšã¯ãã£ã¹ããšã»ãŒåããªã®ã§ãããªãã¿ã®ã¯ãã§ãã ãã ãããµãŒããŒåŽã«ã¯éããçŸããŸãã
handle_callïŒ{depositãNameãAmount}ã_FromãStateïŒ-> ã±ãŒã¹èŸæžïŒïŒååãå·ïŒã®æ€çŽ¢ {OKãå€}-> NewBalance =å€+éé¡ã å¿ç= {okãNewBalance}ã NewState = dictïŒstoreïŒNameãNewBalanceãStateïŒã {è¿ä¿¡ãå¿çãNewState}; ãšã©ãŒ-> {è¿ä¿¡ã{ãšã©ãŒãaccount_does_not_exist}ãå·} çµãã; handle_callïŒ_Requestã_FromãStateïŒ-> è¿ä¿¡= OKã {è¿ä¿¡ãè¿ä¿¡ãå·}ã
ããïŒ ããããã®æ°ãããŠãããã«ããïŒ ã¡ãœããå®çŸ©ã¯ã䜿çšããŠããªãæ°ãã
From
åŒæ°ãé€ããŠãhandle_castã®ããã«èŠããŸãã ããã¯åŒã³åºãããã»ã¹ã®pidèå¥åãªã®ã§ãå¿ èŠã«å¿ããŠè¿œå ã®ã¡ãã»ãŒãžãéä¿¡ã§ããŸãã
ã¢ã«ãŠã³ãã®ååšã確èªããããšãã¢ãŒãªãŒãã³ã¯ã«çŽæããŸãããããã¯ã³ãŒãã®æåã®è¡ã§è¡ããŸãã å ¥éããããšããŠãããŠãŒã¶ãŒã«çžåœããç¶æ ïŒããŒã¿ïŒã®é åããå€ãèŠã€ããããšããŠããŸãã dictã¢ãžã¥ãŒã«ã®findã¡ãœããã¯ã
{ok, Value}
ããŸãã¯
error
ã®2ã€ã®å€ã®ãããããè¿ã
error
ã
å£åº§ãååšããå Žåã䟡å€ã¯çŸåšã®å£åº§æ®é«ãšçãããªããŸã-é éé¡ãè¿œå ããŸãã 次ã«ãæ°ããå£åº§æ®é«ãé åã«ä¿åããå€æ°ã«å²ãåœãŠãŸãã ãŸãããµãŒããŒã®å¿çãå€æ°ã«ä¿åããŸããããã¯ãdeposit APIã®ã³ã¡ã³ãã®ããã«èŠããŸãïŒãã¹ãŠã¯
{ok, Balance}
ã§ãã 次ã«ã
{reply, Reply, State}
è¿ããšããµãŒããŒã¯è¿ä¿¡ãéãè¿ããæ°ããç¶æ ïŒããŒã¿ïŒãä¿åããŸãã
äžæ¹ãã¢ã«ãŠã³ããååšããªãå Žåã¯ãç¶æ ïŒããŒã¿ïŒããŸã£ããå€æŽããŸããããããã«å¿ããŠãšã©ãŒ
{error, account_does_not_exist}
account
{error, account_does_not_exist}
ãéä¿¡ããŸããããã¯ãdeposit APIã³ã¡ã³ãã®ä»æ§ã«åŸããŸãã
ç¹°ãè¿ããŸãããããã«eb_server.erlã®æŽæ°ããŒãžã§ã³ããããŸãã
ã¢ã«ãŠã³ãã®åé€ãšåŒãåºã
ããã§ãã¢ã«ãŠã³ããåé€ããŠã¢ã«ãŠã³ããããéãåŒãåºãããã®æŒç¿ãšããŠãèªè ã«APIãæžããŠããããŸãã ãããè¡ãããã«å¿ èŠãªãã¹ãŠã®ç¥èããããŸãã dictã¢ãžã¥ãŒã«ã«é¢ãããã«ããå¿ èŠãªå Žåã¯ã dict APIãªãã¡ã¬ã³ã¹ãåç §ããŠãã ãã ã å£åº§ãããéãåŒãåºããšãã¯ãå£åº§ã«åŒãåºãã«å¿ èŠãªéé¡ãååšãããã©ããã確èªããŠãã ããã è² ã®å€ãåŠçããå¿ èŠã¯ãããŸããã
å®äºãããããŸãã¯å®äºããŠããªãå ŽåïŒããã§ã¯ãããŸããïŒïŒã ããã§çããèŠã€ããããšãã§ããŸãã
çµã³ã®ã¡ã¢
ãã®èšäºã§ã¯ãgen_serverã®åºæ¬ãšãã¯ã©ã€ã¢ã³ããšãµãŒããŒéã®éä¿¡ãäœæããæ¹æ³ã瀺ããŸããã ã¡ãã»ãŒãžã®ã¿ã€ã ã¢ãŠãããµãŒããŒã®ã·ã£ããããŠã³ãªã©ãgen_serverã®ãã¹ãŠã®æ©èœã«ã€ããŠã¯èª¬æããŸããã§ãããããã®ã€ã³ã¿ãŒãã§ã€ã¹ã®åŒ·åºãªéšåã«ã€ããŠèª¬æããŸããã
ã³ãŒã«ããã¯ã¡ãœãããæ»ãå€ãããã³ãã®ä»ã®ããé«åºŠãªgen_serverã«ã€ããŠè©³ããç¥ãããå Žåã¯ãgen_serverã®ããã¥ã¡ã³ããåç §ããŠãã ãã ã æ¬åœã«å šéšèªãã§ãã ããã
ãŸããç§ã¯code_change / 3ã¡ãœããã«ã¯è§Šããªãã£ãããšãç¥ã£ãŠããŸããããã¯äœããã®çç±ã§äººã ã«ãšã£ãŠæãããããæ¹æ³ã§ãã å¿é ããå¿ èŠã¯ãããŸãããäœæ¥äžã®ã·ã¹ãã ïŒãããã¹ã¯ããã³ãŒãïŒã®ã¢ããã°ã¬ãŒãã«é¢ããèšäºïŒã·ãªãŒãºã®çµããè¿ãïŒã®ã¹ã±ãããæ¢ã«ãããŸãããã®æ¹æ³ã¯äž»ãªåœ¹å²ã®1ã€ã§ãã
次ã®èšäºã¯æ°æ¥äžã«ãããŸãã gen_fsmå°çšã«ãªããŸãã ãããã£ãŠããã®èšäºãããªãã®è³ããããã£ããªãããããã¥ã¢ã«ã«é£ã³èŸŒãèªç±ãæããŠã:)ãèªåã§è¡åããŠãã ããã ãã¶ããErlyBankã¹ããŒãªãŒã®ç¶ããæšæž¬ã§ããã§ããããããã¯gen_fsmã§è¡ããŸã;;ïŒ