ããã«ã¡ã¯ãHabrïŒ
ITMOã®GoToãã©ãŒã«ã¹ã¯ãŒã«ã®çµããããããã11577635ç§ããããããŸããã§ããã Distributed Systems Weekã¯ãCloud Haskellã§ã®åæ£ã·ã¹ãã ã®ãããã¿ã€ãã³ã°ããå§ãŸããŸããã ç§ãã¡ã¯ç²Ÿåçã«å§ãããããå士å·ãªãã§æ¢åã®ããã¥ã¡ã³ããç解ããããšã¯é£ããããšãããã«çºèŠãããã¬ãŒãã³ã°ããã¥ã¢ã«ãäœæããããšã«ããŸããã
ã«ããã®äžã§ãp2pã¯ã©ãŠãhaskellã®çŽ¹ä»ãPCã®ãããã¿ã€ãã³ã°ãããæ°ããããŠããªããã®ãããã«æ©èœçãªã¹ã¿ãã¯ã
ããªããããåæ£ããäœããããããšããŸã
ïŒ%% sCoinïŒ æ¢åã®ã·ã¹ãã ã§ã¯ã«ããŒãããŠããŸããïŒYARNã¯ãã¹ãŠã®è³ªåã«å¯Ÿããçãã§ã¯ãããŸããïŒã æäœæ¥ã§ãã¹ãŠãå§ãããšãç¹ã«ç®æšãæçµè£œåãŸãã¯çŸããå Žåã¯ãå€éåæ¥ç¶ãæå·åãããNATããã¢ã«ãŒãã£ã³ã°ã®çªç ŽãŸã§ïŒäººé¡å²äžåããŠã§ã¯ãªãïŒæ¬åœã«å€ãã®åé¡ããã°ããçºèŠã§ããŸãã
äœæ¥ãããã¿ã€ãã
ãã®ãããªåé¡ã®å£°æããé©çšãããããã°ã©ãã¯ãããã«ãã©ã€ãã©ãªããšããåèªãæãã€ããŸãã ãããŠæ¬åœã«ã ããšãã°ãæšæºã®NATãã³ãã¡ã«ããºã ïŒSTUNãTURNãICEïŒãäžè¬çã«ç¥ãããŠããKademliaããçºèŠãšã«ãŒãã£ã³ã°ã®ããŒã¹ãååŸã§ããŸãããªã©
ããããããã§ãå€ãã®æéãšå°éç¥èãå¿
èŠã«ãªããŸãã æè³å®¶ã«ã¯å¿èããªããããããŸããã
ããã§ã¯ãããçµéšè±å¯ãªååãããã¬ãŒã ã¯ãŒã¯ãå¿
èŠã§ãïŒããšããèããæãã€ããŸãã ãããŠæ¬åœã«ã åæ£ã·ã¹ãã ããã³ã¢ããªã±ãŒã·ã§ã³ã®ãããã¿ã€ãã³ã°çšã
ãããŠèª°ããèšãããšãããããŸãïŒ
ç¥ ãããã¯
libp2pã§ãïŒ ãããŠåœŒã¯æ£ããã§ãããã éšåçã«ã
libp2pã¯ããã©ã³ã¹ããŒãããã®å€éåãšæå·åãæ€åºããã¢ã«ãŒãã£ã³ã°ãNATãã¬ãŒã¯ããŠã³ãæ¥ç¶ã¢ããã°ã¬ãŒããªã©ã®åé¡ã解決ããŸãã -äžè¬çã«ãåæ£ã¢ããªã±ãŒã·ã§ã³ã®å€ãã®ãããã¯ãŒã¯ããã³æå·åã®ããŒãºã On GoãšJSã
ããã¯çŽ æŽããããã¬ãŒã ã¯ãŒã¯ã§ãããããã€ãã®åé¡ããããŸãã ãããGoãšJSã§ãã ããã«ãã¬ããªã±ãŒã·ã§ã³ã®ãã¬ãŒã ã¯ãŒã¯ã«äœãããããšäŸ¿å©ã§ãã
ãã¥ãŒããªã¢ã«ã®æççãªæ§è³ªïŒäžéšã¯ãŸã£ããæ©èœããŸããã§ããïŒã«ãããCloud Haskellã䜿çšããªãããã«èª¬åŸãããŸãã
http://www.scs.stanford.edu/14sp-cs240h/projects/joshi.pdf ãèšãæãç§ãã¡ã®ãããžã§ã¯ãã¯ãHaskellã§ãããã¯ãã§ãŒã³ïŒç³ãèš³ãããŸããããã€ãããŒã·ã§ã³ïŒãäœæãããšããéå¿ããå§ãŸããŸããããããã£ãŠãlibp2pã¯ãããŸããã§ããã ç§ãã¡ã¯ãããã¯ãŒã¯ïŒãã©ã³ã¹ããŒãããã£ã¹ã«ããªãŒãã·ãªã¢ã«åïŒãäœããã®ãæ¢ãå§ããŸããã
Cloud HaskellãèŠã€ãããŸããã ããã¥ã¡ã³ããè€éã§ããããšãããããŸããã ç§ã®çŽ¹ä»ãæžãããšã«ããŸããã ã ããïŒ
Cloud Haskellã§Sky Beesãæžã
ãã®äŸã§ã¯ãããããã®ã·ã¹ãã ãäœæããŸãããã€ãïŒãã·ã³ã®ã¯ã©ã¹ã¿ãŒïŒãšããããïŒããŒãïŒããããŸãã ããããã¯è±ãæ¢ãããã«ã¹ã«ãŠãã«éãããããããè±ã®åº§æšãšãšãã«å·£ã«æ»ããŸããä»ã®ãã¹ãŠã®èã¯ãããã®åº§æšãç¥ã£ãŠããå¿
èŠããããŸãã
ããã°ã©ã ãè€æ°ã®ã³ã³ãã¥ãŒã¿ãŒã§å®è¡ããå¿
èŠã¯ãŸã£ãããããŸãããããã°ã©ã ã䞊è¡ããŠå®è¡ããã©ãããããã ãã§ãã
å®å
šãªã³ãŒãã¯
ãªããžããªã«ãã
ãŸã ã
Cloud Haskellã¯ãããŒããå
±éã®ãªãœãŒã¹ã¹ããŒã¹ïŒRAMãªã©ïŒãå
±æããªããããããŒãéã§ã¡ãã»ãŒãžã亀æãããšããååã«åºã¥ããŠåäœããŸãïŒãã®ãããªã¢ãã«ã¯
ã¡ãã»ãŒãžããã·ã³ã°ãšåŒã°ã
ãŸã ïŒã
ã¢ã¯ã¿ãŒã¢ãã«ã¯ã
ã¢ã¯ã¿ãŒãä»ã®ã¢ã¯ã¿ãŒã«ã¡ãã»ãŒãžãéä¿¡ãã
ã¡ãŒã«ããã¯ã¹ã§ã¡ãã»ãŒãžãåä¿¡ããå Žåã®
ã¡ãã»ãŒãžããã·ã³ã°ã¢ãã«ã®ãã©ã€ããŒããªäŸã§ããããããCloud Haskellã§ã®ã¡ãã»ãŒãžããã·ã³ã°ã®æ§åã§ãã
1.æåã«ãããããã代衚ããããŒã¿ã®ã¿ã€ããå®çŸ©ããŸãïŒ
src / Types.hstype Flower = (Int, Int)
- ããããã¯ããã€ãå
ã®å°ãªããšã1ã€ã®ãããããç¥ã£ãŠãããã¹ãŠã®è±ã«ã€ããŠç¥ã£ãŠããå¿
èŠããããŸãããããã£ãŠãããããã¯ãããããã®è³ã§è±ã®ãããŒã¿ããŒã¹ãã®åäžã®ç¶æ
ãç¶æããå¿
èŠããããŸã- ããŒã¿è€è£œã®åé¡ã解決ããããã«ã ã³ã³ã»ã³ãµã¹ã«å°éããå¿
èŠãããïŒç°ãªãèã®ããŒã¿ããŒã¹éã®ç«¶åã解決ã ãããè¡ãããã«ã GSet ïŒGrow-only SetïŒããŒã¿æ§é ã䜿çšããŸã-èŠçŽ ãè¿œå ããããšã¯ã§ããŸãããåé€ããããšã¯ã§ããŸãã ã ããã¯ã CRDTããŒã¿æ§é ã®1ã€ã§ãã Haskellã§GSetã䜿çšããããã«ãYuri Syrovetskyã®åªããcrdtã©ã€ãã©ãªïŒ @cblp ïŒã䜿çšããŸããã
Log A Log B | | logA.append("one") logA.append("two") | | vv +-----+ +-------+ |"one"| |"hello"| +-----+ +-------+ | | logA.append("two") logA.append("world") | | vv +-----------+ +---------------+ |"one","two"| |"hello","world"| +-----------+ +---------------+ | | | | logA.join(logB) <----------+ | v +---------------------------+ |"one","hello","two","world"| +---------------------------+
CRDTã䜿çšããã³ã³ã»ã³ãµã¹æ§ç¯ã¹ããŒã ïŒ https://github.com/haadcode/ipfs-logããïŒ - èã®å容äœãšããŠæ©èœããã€ã³ã¿ãŒãã§ãŒã¹ãå¿
èŠã§ããGSetã«èŠçŽ ãè¿œå ãããã€ããç¥ã£ãŠããããããè±ã衚瀺ããŸãããããREPLïŒã€ã³ã¿ã©ã¯ãã£ãã·ã§ã«ïŒã®åœ¢åŒã§å®è£
ããŸãã
2.ããŒãã®å®è£
ãéå§ããŸããã
ãå°æ¥ãã³ãã³ãã©ã€ã³ããå®è¡ããŸãïŒ
app / Main.hs main = do
- æåã«ãããŒãã¯äœããã®æ¹æ³ã§ãäºãã«ã€ããŠåŠç¿ããå¿
èŠããããŸããã€ãŸãã ãã¢çºèŠãè¡ããŸãã Cloud Haskellã«ã¯ããã«äœ¿çšã§ãããœãªã¥ãŒã·ã§ã³ããããŸããããŒããåæåãããšãã«ãå°ãªããšã1ã€ã®ä»ã®ããŒãã¹ãã©ããããŒããæå®ããã ãã§ååã§ããããŒãã¯ã Peer ExchangeããŒããããŒãã¹ãã©ããã§äœæããŸã-ç¥ã£ãŠããããŒãïŒå¥åã ã㢠ïŒã®ã¢ãã¬ã¹ã亀æããŸãã
- ãªã¢ãŒãããŒãã«ã¯ããã¢ãã·ãªã¢ã«åããµããŒãããŠããå Žåããã¢ãhaskellã¿ã€ãã亀æã§ããããã«ãããã®ã§ããã€ãŸãããããã¯ãŒã¯ãä»ããŠéä¿¡ããHaskellãªããžã§ã¯ãã«åŸ©å
ã§ãã圢åŒã§è¡šãããšãã§ããŸãã åã¯
class (Binary a, Typeable) => Serializable a
å®è£
ããå ŽåãçŽååããµããŒãããŸãclass (Binary a, Typeable) => Serializable a
ã Serializable
ã Binary
ã Typeable
å®è£
ãTypeable
ã§çºæããå¿
èŠã¯ãããŸãã-haskellã¯ãããããªãã®ããã«è¡ããŸãïŒéæ³ã®èªåå°åºã¡ã«ããºã ã䜿çšïŒïŒ
{-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE DeriveGeneric #-}
次ã«ãç°¡æœã«ããããã«instance Binary
deriving ...
ã instance Binary
ããã³ãã©ã°ããçç¥ãinstance Binary
ã
3.次ã«ãããŒããèµ·åããããã®ããžãã¯ãèšè¿°ããŸãã
spawnNode :: Process ()
- Cloud Haskellã§ã¯ãäž»ãªæ©èœåäœã¯
Process
ïŒOSããã»ã¹ãšæ··åããªãã§ãã ããïŒã ãããã¯è»œéã®ç·ã®ã¹ã¬ããã«åºã¥ããŠãããä»ã®ããã»ã¹ã«ã¡ãã»ãŒãžãéä¿¡ã§ããŸãïŒç¹å®ã®ããã»ã¹ã«éä¿¡ããsend
æ©èœãŸãã¯ãã¹ãŠã®äœ¿ãæ
£ããããŒãã«éä¿¡ããP2P.nsendPeers
ïŒã ã¡ãŒã«ããã¯ã¹ã§ã¡ãã»ãŒãžãåä¿¡ããŸãïŒ expect
ãŸãã¯receive*
æ©èœïŒãä»ã®ããã»ã¹ãéå§ããŸãïŒããšãã°ãããŒã«ã«ã§spawnLocal
ã䜿çšãããªã©ïŒ - REPLãå¥ã®ã¹ã¬ããã«å®è£
ããå¿
èŠããããŸããããããªããšãã¡ã€ã³ã¹ã¬ããïŒããŒãïŒããããã¯ããããããREPLãšããŒãã®äž¡æ¹ã§å€æŽã§ããããã«GSetã®ã¹ã¬ããã»ãŒãã€ã³ã¿ãŒãã§ã€ã¹ãäœæããå¿
èŠããããŸãã ã·ã¹ãã ã¯ã¢ã¯ã¿ãŒã«åºã¥ããŠãããããã»ãããå€æŽããã¡ãã»ãŒãžãéä¿¡ããã¡ã€ã³ã¹ã¬ããã§ã¡ãã»ãŒãžãåŠçããç¡éã®ãµã€ã¯ã«ã§é 次åŠçããŸãã
- REPLãåå¥ã®ã¯ã©ãŠããã¹ã±ã«ããã»ã¹ãšããŠïŒã€ãŸããç·è²ã®ã¹ã¬ãããšããŠïŒå®è¡ããã¡ã€ã³ããã»ã¹ã®PidïŒäžæã®ããã»ã¹èå¥åïŒãæž¡ããŠãREPLããŠãŒã¶ãŒãå
¥åããã³ãã³ããã¡ãã»ãŒãžã®åœ¢åŒã§éä¿¡ããå Žæãèªèã§ããããã«ããŸãã 次ã«ãPID REPLïŒspawnLocalãè¿ãïŒãååŸããŠãã³ãã³ããžã®å¿çãéä¿¡ããŸãã REPLã³ãŒãã¯ãã¡ãã§ãã
- è±ã®è€è£œã¯ã©ã®ããã«æ©èœããŸããïŒ
- åããŒãã¯ãã®ç¶æ
ãå®æçã«ãã¹ãŠã®ãã¢ã«éä¿¡ãïŒ ãããŒããã£ã¹ã ïŒãCRDTãšãšãã«ããã«ããè€è£œã®åé¡ã解決ããŸãã
ããŒãA
ãšB
ããããšããŸãB
A
ã¯èŠçŽ xããªãã B
xããããšããŸãã B
ããããŒããã£ã¹ããè¡ã£ãåŸã A
ã¯xãè¿œå ããŸã-ã³ã³ã»ã³ãµã¹ã«éããŸããããªã©ã
GSetã§ã¯ãªãéåžžã®ã»ãããããã°ãäœãèµ·ãããŸããã§ããA
ãšB
èŠçŽ yããããšããŸãã A
yãåé€ãããŸãã B
ããããŒããã£ã¹ããè¡ã£ãåŸã A
ã¯yãè¿ããŸãã - ãã¹ãŠã®ããŒãã«ã¡ãã»ãŒãžãéä¿¡ããå Žåã ãµãŒãã¹ã®ååãæå®ããå¿
èŠããããŸããå®éããã®ãµãŒãã¹ããµããŒããããã®ãšããŠã¬ãžã¹ã¿ã«ç»é²ãããŠããããŒãã«ã®ã¿ã¡ãã»ãŒãžãéä¿¡ããŸãã ããã§ã¯ãããŒãããbeesããµãŒãã¹ããµããŒããããã®ãšããŠç»é²ããŸãã
register "bees" self
ãŸãã - éç°ã¯ãä»ã®äººã«ãã€å¹žéãéãã¹ãããç¥ããªããã°ãªããŸããã æãç°¡åãªè§£æ±ºçã¯ãã¿ã€ããŒã§ãããè¡ãããšã§ãã1ç§åŸ
ã£ãŠããè¡åããŸããããã®åŸãã¡ã€ã³ã®ã¡ãã»ãŒãžåŠçãããŒããããã¯ããŸãã ããã§ã¯ã
spawnLocal
ãspawnLocal
ãŠããã»ã¹ãéå§ããŸããæåã«Tickã¡ãã»ãŒãžãã¡ã€ã³ããã»ã¹ã«éä¿¡ãïŒã¡ã€ã³ããã»ã¹ãTickãæ€åºãããšããã®ç¶æ
ãããŒãã«éä¿¡ããŸãïŒã1ç§åŸ
æ©ããŠç¹°ãè¿ããŸãã
4. OKãä»ïŒæçµçã«ïŒïŒã¡ã€ã³ããã»ã¹ã®ããžãã¯ïŒããŒãå®è¡ã³ãŒãïŒãéå§ã§ããŸãã
runNode :: NodeConfig -> Flowers -> Process ()
- ã·ã°ããã£ãèŠãŠã¿ãŸããã
runNode
ã¯ãã¿ã€ãNodeConfig
ããŒãã®æ§æãåãå
¥ããŸã-å®è¡æã«å€æŽãããªãæ
å ±ã ç§ãã¡ã®å Žåãããã¯åãªãPID REPLã§ãã 圌女ã¯çŸåšã®ç¶æ
ã§ããè±ã®GSetãåãå
¥ããŸãã ããããGSetã¯äžå€ã®ããŒã¿åãªã®ã§ãè±ãè¿œå ããæ¹æ³ã¯ïŒ éåžžã«ç°¡åïŒé¢æ°ãååž°çã«ããç¶æ
ãå€åãããã³ã«é¢æ°ãåèµ·åããŸãã receiveWait
ã¯ã1ã€ã®åŒæ°ïŒçä¿¡ã¡ãã»ãŒãžïŒãæã€é¢æ°ã®ãªã¹ããåãåããã¡ãã»ãŒãžãåŒãåºããŠãã¡ãã»ãŒãžã®ã¿ã€ãã«é©ããé¢æ°ãåŒã³åºããŸãã- ãã®ã¿ã€ãã®ã¡ãã»ãŒãžãåä¿¡ããå ŽåïŒ
data Command = Add Flower | Show
data Command = Add Flower | Show
ãããã¯REPLããã®ã³ãã³ãã§ãã handleReplCommmand
ã³ãã³ããåŠçããããã®é¢æ°ïŒ
handleReplCommand :: NodeConfig -> Flowers -> Command -> Process Flowers handleReplCommand (NodeConfig repl) flowers (Add flower) = do
- ãã£ãã¯ããã£ãã«ãŒããæ¥ãå Žåãã¹ããŒã¿ã¹ãéä¿¡ããå¿
èŠããããŸãïŒ
P2P.nsendPeers "bees" flowers
ã ããã§ããbeesãã¯ãµãŒãã¹ã®ååã§ããã€ãŸãããbeesããšããŠç»é²ãããŠããããŒãã«ã®ã¿è±ã転éããŸãã - ä»ã®ããããããè±ãåãåã£ãå Žåã銎æã¿ã®ãªãè±ããã¹ãŠèªåèªèº«ã«è¿œå ããå¿
èŠããããŸããã€ãŸããå€ãã®æ°ããè±ãšå€ãã®æ¢åã®è±ãåçŽã«çµã¿åãããŸãã
5.以äžã§ãïŒ å®å
šãªãœãŒã¹ã³ãŒããããŠã³ããŒãããŠã³ã³ãã€ã«ããŸãã
git clone https://github.com/SenchoPens/cloud-bees.git cd cloud-bees stack setup
1ã€ã®ã¿ãŒããã«ã§æ¬¡ã®è¡ãå®è¡ããŸãã
stack exec cloud-bees-exe 9000 9001 2>/dev/null
ãããŠå¥ã®ããã§ïŒ
stack exec cloud-bees-exe 9001 9000 2>/dev/null
REPLãããã³ãããåºããŸãã 1ã€ã®ç«¯æ«ã«
Add (1, 2)
ãè¿œå ããŠã¿ãŠãã ããã 座æšïŒ1ã2ïŒãæã€è±ãè¿œå ããå¥ã®-Showã§ã2çªç®ã®ããŒãã«ããã®ãããªè±ãããããšãããããŸãã
- ããŒã
2>/dev/null
ãCloud Haskellããã°ã€ã³ããstderrãé ãããã«å¿
èŠã§ãã ãããè¡ããªããšãREPLãæ£åžžã«äœ¿çšã§ããªããªããŸãã /dev/null
ãlog.txt
眮ãæããŠã衚瀺å
容ã確èªã§ããŸãã
Haskellã§åæ£ã·ã¹ãã ãäœæããããšã¯ããã»ã©æããªãããšãããªãã«çŽåŸãããŠããã ããã°å¹žãã§ã:)
åæ§ã®ã·ã¹ãã ã®å€ãã®å®éã®ãŠãŒã¶ãŒã±ãŒã¹ãèãåºãããšãã§ããŸãïŒããšãã°ãå
Œ
±äº€éæ©é¢ã§éãŠãµã®ã®åé¡ã解決ããïŒã«ãŒãäžã®äº€éæ©é¢ã«éè¡ãã人ã¯ãã°ã€ã³æžã¿ãšããŠããŒã¯ããïŒæåã®GSetã«èªåã®IDãè¿œå ïŒãåºåæã«-ãã°ã¢ãŠãæžã¿ãšããŠïŒIDãè¿œå ããŸãïŒ 2çªç®ã®GSetïŒã å€ïŒèŒžéãæ©èœããªããšãïŒã«ããã§ãã¯ãè¡ãããŸã-人ãåºå
¥ãããå Žåã圌ã¯éãŠãµã®ã§ã¯ãããŸããã
èå³ã®ããæ¹ã¯
ãã·ããäžã«è¡ã£ãæå·åã䜿çšãããã倧ããªãããžã§ã¯ããã芧ãã ããã
æã蟌ããŠãã¢ãŒã»ããŒãšä»²éã9幎çã wldhxã®ç©ãããªæå°ã®äžã§