ããã«ã¡ã¯ãhabrauserïŒ
ããŸããŸãªãµãŒãã¹ãšæ¢åã®ã·ã¹ãã ãå¶åŸ¡ãããããã»ã¹ã«ãªã³ã¯ããã¿ã¹ã¯ããããŸãã é床ã¯å®å®çã§ã¯ãªãå¿
èŠã§ãïŒã€ãŸããæ ªäŸ¡ã«åºã¥ããŠå¿çãäœæããããšã¯ã§ããŸããïŒããå€ãã®ããã»ã¹ãããã䜿çšããå¿
èŠãããã³ã³ããŒãã³ãïŒã·ã¹ãã ïŒãè¿«ã£ãŠããŸãã p2pãã€ã³ãã£ã³ã°ãè¡ããããããŸããã çŸãããŠç®¡çãããããã®ã欲ããã
åžå Žã確èªããåŸãAmazon Simple Workflowã«åºã¥ããŠã¬ããªã«ãäœæããããšã決å®ãããŸãããããã¯ãçŽæ¥äœ¿çšã§ããªãããã§ãã ç§ãã¡ã«åã£ããã¬ãŒã ã¯ãŒã¯ã®ããããã£ïŒ
- äœéå§ãããå€ïŒåªããããã°ã©ããŒã¯ä»æ¥é«äŸ¡ã§ãïŒã ããã§ã®äœãããå€ã¯ããã¹ãŠãé«ã¬ãã«ã§ïŒã»ãŒã€ã³ã¿ãŒãã§ãŒã¹ãšã®å¯Ÿè©±ã¬ãã«ã§ïŒè¡ããããããããã°ã©ãã³ã°ã®éå§ãšããç¹ã§ããéèŠã§ãã ãã ããããã»ã¹ãéåæã§é©åã«å¶åŸ¡ããã«ã¯ããã¡ããçµéšãç©ãå¿
èŠããããŸã
- ã¿ã¹ã¯ã®ãã©ã¡ãŒã¿ãŒãšå®è¡çµæãä¿åãããšããããã»ã¹ã¿ã¹ã¯ãšã°ãŒãã¥ãŒã¿ãŒã®ååž°ãã¹ãã®åæãšããŒã¹ãååŸããŸã
- ç¹å®ã®å ŽæïŒã³ãŒãã£ããŒã¿ãŒå
ïŒã®ããã»ã¹å¶åŸ¡ããžãã¯ã®éäžã ããã¯äžèŠããŠæããã§ã¯ãªããããããŸããããããã¯ãåã¢ã¯ã¿ãŒãç¬èªã®ããžãã¯ãæã£ãŠããå Žåã«èãããã代æ¿æ¡ãšæ¯èŒããŠæ倧ã®å©ç¹ã§ã-ä»ã®ã³ã³ããŒãã³ãã次ã«åŒã³åºãããŸãïŒè»¢éå¶åŸ¡ïŒã å€ãã®å Žåãã·ã¹ãã ãè€éã«ãªããã³ã³ããŒãã³ããåå©çšã§ããªããªããŸã
ããã¯ç§ãæãæå°å€ã§ãããå®è·µã瀺ãããã«ãããå€ãã®ãã©ã¹ããããŸãã ãã®ãããžã§ã¯ãã¯ãã¿ã¹ã¯ãã«æ¬æãè¡šããŠã¿ã¹ã¯
ããã¿ãšåä»ããã
ãŸãããããã¯ã¿ã¹ã¯ã§ããããã£ã³ã©ã³ãèªã§gopherã§ãããéèŠã§ã¯ãããŸããã衚瀺ãããŸããã ãªãŒãã³ãœãŒã¹ã¯
GitHubã§å
¥æã§ã
ãŸã ã ãããžã§ã¯ãã¯Hazelcastã䜿çšããŠå®è£
ããããµãŒããŒéã§å
±éã®ã¡ã¢ãªç©ºéãšã©ã³ã¿ã€ã ãäœæããŸãããRESTãµãŒãã¹ãè¿
éãã€äŸ¿å©ã«å®è£
ããããã®Dropwizardãšãæåã®éçºè
ã§ããAmazonã®å人ãåããŠéçºããŸããã ããã¥ã¡ã³ãã¯é£ããã§ãããããã«ä¿®æ£ããŸãã
çè«ããå®éã®äŸã«ç§»ããŸãããã
ãŠãŒã¶ãŒã«æååã¡ãã»ãŒãžãéä¿¡ããã¢ããªã±ãŒã·ã§ã³ãéçºããå¿
èŠããããšããŸãã å
¥åæã«ããŠãŒã¶ãŒIDãšæåã»ãããååŸããŸãã 圌ã®ãããã¡ã€ã«ïŒIDã«ããïŒãããé»åã¡ãŒã«ãŸãã¯é»è©±çªå·ã§ã¡ãã»ãŒãžãåä¿¡ããããã®èšå®ããŒã¿ãååŸããŸãã é»è©±çªå·ãšã¡ãŒã«ããããã¡ã€ã«ã§å
¥æã§ããŸãã 次ã«ãå¿
èŠãªãã©ã³ã¹ããŒããšãšãã«ã¡ãã»ãŒãžãéä¿¡ããŸãã éä¿¡ã倱æããå ŽåïŒã¢ãã¬ã¹ãŸãã¯çªå·ãæ£ãããªãããïŒãå°æ¥ã®åè©Šè¡ãé²ãããã«ãããã¡ã€ã«ã«èšé²ããå¿
èŠããããŸãã
ããã«ãã¡ãã»ãŒãžãéä¿¡ãããµãŒãã¹ãæ¢ã«ååšããä»ã®ãµããããäžã«ãããåå©çšããå¿
èŠããããšããéæ©èœèŠä»¶ãè¿œå ããŸãã
PSïŒèª¬æãããŠããäŸã®ãã¹ãŠã®ãœãŒã¹ã³ãŒãã¯ãGitHub
taskurotta \ taskurotta-getstartedã§ãå
¥æã§ããŸã
ãTaskurottaã䜿çšãããšãéçºè
ã«ãšã£ãŠéåžžã®æ¹æ³ã§çžäºã«ããåãããã·ã¹ãã ã³ã³ããŒãã³ãïŒã¢ã¯ã¿ãŒïŒãå®è£
ã§ããŸã-äºãã®ã¡ãœãããåŒã³åºããŸãããéåæã§å®è¡ããŸãã ã¢ã¯ã¿ãŒã¯ãããã©ãŒããŒãšã³ãŒãã£ããŒã¿ãŒã®2ã€ã®ã¿ã€ãã«åããããŸãã å®è¡è
ã¯ãå²ãåœãŠãããã¿ã¹ã¯ãæ確ã«éè¡ããå¿
èŠããããŸãã ãããã¯æãç¬ç«ããã¢ãžã¥ãŒã«ã§ãããããã«å¿ããŠ-æãåå©çšå¯èœã§ãã ã¢ãŒãã£ã¹ãã¯ãå€éšã®äžçïŒä»»æã®å
¥å/åºåã¹ããªãŒã ïŒãšå¯Ÿè©±ããå¿
èŠãªéãããã®ãããªæ¹æ³ã§ã¿ã¹ã¯ãå®è¡ã§ããŸãã äžæ¹ãã³ãŒãã£ããŒã¿ãŒã¯å€ã®äžçã«é¢é£ããã¿ã¹ã¯ãå®è¡ããŸããã ããŒã¿ããŒã¹ããããã¯ãŒã¯ããã®ä»ã®äžå®å®ãªå¯èœæ§ã®ããã³ã³ããŒãã³ããšã®çŽæ¥çãªããåãã«ã€ãŸãããªãããã«ãã§ããã ãæ©ã解決ããå¿
èŠããããŸãã å®è¡è
ã«ã¿ã¹ã¯ãèšå®ããã¢ã¯ã·ã§ã³ã調æŽããããã«ãã£ãŠããã»ã¹ã®å®è£
ïŒèª¬æïŒã確å®ã«ãã矩åã ã³ãŒãã£ããŒã¿ãŒã¯ãåå©çšå¯èœãªãµãããã»ã¹ã®ãã©ãã€ã ãå®è£
ããããšã«ãããä»ã®ã³ãŒãã£ããŒã¿ãŒã®ã¿ã¹ã¯ãèšå®ã§ããŸãã
ã³ãŒãã£ããŒã¿ãŒã®ã¿ã¹ã¯ã¯ãçŸåšç¥ãããŠããã¿ã¹ã¯ãé
åžããããšã§ãã ã€ãŸã çµæãåŸ
ã£ãŠãããã¯ããªãã§ãã ããã 圌ã¯ãèªåãç¥ã£ãŠããã¿ã¹ã¯éã®äŸåé¢ä¿ãæ§ç¯ããå¿
èŠã«å¿ããŠããããªãã¢ã¯ã·ã§ã³ã決å®ããããã®éåæãã€ã³ãã圢æããå¿
èŠããããŸãã
ãã®ããã»ã¹ã§ã¯ãã³ãŒãã£ããŒã¿ãŒã¯æ¬¡ã®ããšãè¡ãå¿
èŠããããŸãã
- ãŠãŒã¶ãŒãããã£ãŒã«ããªã¯ãšã¹ããã
- ãããã£ãŒã«ãåŸ
ã€
- ãŠãŒã¶ãŒã«ã¡ãã»ãŒãžãéä¿¡
- çºéã®çµæãåŸ
ã€
ã¹ããŒããã·ã³ãè€æ°ã®ããã©ãŒããŒã«ãã1ã€ã®ã¡ãã»ãŒãžã®å€æŽæ¹æ³ããã®ä»ã®éåžžã®éªšã®æããæ¹æ³ã䜿çšããŠããã®äžé£ã®ã¢ã¯ã·ã§ã³ããšã³ã³ãŒãããŸããã Promiseãšã³ãã£ãã£ãšã³ãŒãã£ããŒã¿ãŒã®ã¢ã¯ã·ã§ã³ãç£èŠããã·ã¹ãã ã䜿çšããŠãç°¡åãã€çŸããè¡ããŸãã
Promise<Profile> profilePromise = userProfileService.get(userId); Promise<Boolean> sendResultPromise = decider.sendToTransport(profilePromise, message);
ãã®äŸã¯ããµãŒãã¹ãåŒã³åºããçµæãå®éã®ãªããžã§ã¯ãã§ã¯ãªããç¹å®ã®çŽæãã€ãŸãã¿ã¹ã¯ã®çµæãžã®ãªã³ã¯ãååŸããããšã瀺ããŠããŸãã ãã®PromiseãåŒæ°ãšããŠä»ã®ãµãŒãã¹ïŒã¿ã¹ã¯ïŒã«æž¡ãããšãã§ããŸãã ä»ã®ãµãŒãã¹ã®åŒã³åºãã¯ã·ã¹ãã ã«ãã£ãŠã€ã³ã¿ãŒã»ããããïŒã€ãŸããå®éã®åæåŒã³åºãã¯çºçããŸããïŒããããã®éã«é¢ä¿ãæ§ç¯ãããŸãã ã¿ã€ãPromiseã®ãã¹ãŠã®åŒæ°ãæºåããããŸã§ãã¿ã¹ã¯ã¯ãµãŒãã¹ã«ãã£ãŠå®è¡ãããŸããã å¿
èŠãªãã¹ãŠã®äºåã¿ã¹ã¯ãå®äºãããŸã§ã
ãããã£ãŠãããã»ã¹å¶åŸ¡ã¯ã³ãŒãã£ããŒã¿ãŒãšã·ã¹ãã ã«ãã£ãŠå
±åã§å®è¡ãããŸãã ã³ãŒãã£ããŒã¿ãŒã¯ã¿ã¹ã¯éã®äŸåé¢ä¿ãæ§ç¯ããã·ã¹ãã ã¯ããšããããäºåã¿ã¹ã¯ã®å®äºãšãããã«äŸåããã¿ã¹ã¯ã®ãã®åŸã®èµ·åãåŸ
ã€æ©èœãåŒãç¶ããŸãã
次ã«ããããªãã¢ã¯ã·ã§ã³ã決å®ããããã®éåæãã€ã³ããæããã«ããŸãã
éç¥ã®éä¿¡ãæåããããšã確èªããå¿
èŠããããããã§ãªãå Žåã¯ããŠãŒã¶ãŒãžã®éç¥ã®éä¿¡ããããã¯ããå¿
èŠããããŸãã
ãã®å Žåãéç¥ãéä¿¡ããåŸãããã«ã¢ã¯ã·ã§ã³ãå®è¡ããåã«ãéä¿¡çµæãåæããå¿
èŠããããŸãã ã€ãŸã ã¿ã¹ã¯ãå®äºãããŸã§åŸ
ã£ãŠåæããçµæã«å¿ããŠãããã¯ãããã©ããã決å®ããŸãã ãã®ãããªåé¡ã解決ããããã«ãã³ãŒãã£ããŒã¿ãŒã¯èªåã§ã¿ã¹ã¯ãäœæããæ©äŒããããŸãã å¿
èŠãªPromiseã®è»¢éå
ãšãªããããªãã¢ã¯ã·ã§ã³ãå®çŸ©ããããã®ãã€ã³ãã 以äžã®ããã«ãªããŸãã
public void start(String userId, String message) { Promise<Profile> profilePromise = userProfileService.get(userId); Promise<Boolean> sendResultPromise = decider.sendToTransport(profilePromise, message); decider.blockOnFail(userId, sendResultPromise); } @Asynchronous public void blockOnFail(String userId, Promise<Boolean> sendResultPromise) { logger.info(".blockOnFail(userId = [{}], sendResultPromise = [{}])", userId, sendResultPromise); if (!sendResultPromise.get()) { userProfileService.blockNotification(userId); } }
startïŒïŒã¡ãœããã¯ããã»ã¹ã®éå§ã§ãã 次ã¯3ã€ã®ã¿ã¹ã¯ã®ã¹ããŒãã¡ã³ãã§ãã æåã«ãããã¡ã€ã«ãåä¿¡ãã2çªç®ãš3çªç®ã«ãã³ãŒãã£ããŒã¿ãŒã¯çµæã®åŸç¶ã®åæïŒsendToTransportã¡ãœãããšblockOnFailã¡ãœããã®åŒã³åºãïŒã®ããã«èªåçšã«èšå®ããŸãã ãããã£ãŠãã³ãŒãã£ããŒã¿ãŒã¯ãæåã®ã¿ã¹ã¯ã®è§£æ±ºãåŸ
ã£ãŠãããã®ããã«ãªããŸããããããã¯ã¯ããŸããã åé¡ã解決ããããšãTaskurottaã·ã¹ãã ã¯sendToTransportã³ãŒãã£ããŒã¿ãŒã¡ãœãããåŒã³åºããŠãæ¢è£œã®Promiseãªããžã§ã¯ããæž¡ããããããgetïŒïŒã¡ãœããã䜿çšããŠå®éã®ããŒã¿ãååŸã§ããŸãã sendToTransportã¿ã¹ã¯ãå®äºããåŸãblockOnFailã¿ã¹ã¯ãèµ·åãããéç¥ã®éä¿¡äžã«ãšã©ãŒãçºçããå Žåã«ãŠãŒã¶ãŒuserIdã®ã¡ãã»ãŒãžããããã¯ããããã«ã¿ã¹ã¯ãuserProfileServiceãµãŒãã¹ã«èšå®ããŸãã
ããã«ã¢ã¯ã·ã§ã³ã決å®ããããã®ãã€ã³ãã䜿çšããŠãããŸããŸãªããã»ã¹åäœãå®è£
ã§ããŸãã
- ããŸããŸãªãã©ã³ãã§ã®äžŠåå
- Promise転éãš@NoWaitã¢ãããŒã·ã§ã³ã䜿çšããŠãç¬ç«ããããã»ã¹ã¹ã¬ããã1ãã€ã³ãã§ããã«ããŒãžãã
- éåæååž°
- åæ§ã®ã¿ã¹ã¯ã®å®è¡ã®äžŠååãããšãã°ããã¹ãŠã®ãã¡ã€ã«ã®ããžã¿ã«çœ²åã確èªãã1ã€ã®æ±ºå®ç¹ã§å®è¡çµæãåŸ
ã€
- ãªã©
PSïŒblockOnFailã¿ã¹ã¯ã¯æ±ºå®ãªããžã§ã¯ããä»ããŠåŒã³åºãããŸãã ããã¯ãåŒã³åºããã€ã³ã¿ãŒã»ãããã人工ãªããžã§ã¯ãã§ãããå®éã«ã¯blockOnFailã¡ãœãããåŒã³åºããŸããã ã¿ã¹ã¯ãèšå®ããå¿
èŠããããåæçã«åŒã³åºããªãã§ãã ããã
ã·ããªãªã«ãããšãé»åã¡ãŒã«ãšSMSãéä¿¡ããããã®è«è² æ¥è
ãæ¢ã«ããããããããã¡ã€ã«ãæäœããè«è² æ¥è
ã®ã¿ãäœæã§ããŸãã ãã®è«è² æ¥è
ã«ã¯2ã€ã®ã¿ã¹ã¯ããããŸãã
- ãŠãŒã¶ãŒIDã§ãããã¡ã€ã«ãè¿ã
- ç¹å®ã®ãŠãŒã¶ãŒã«ã¡ãã»ãŒãžãéä¿¡ã§ããªãããšã«é¢ãããããã¡ã€ã«ããããã¡ã€ã«ã«äœæããŸã
ã€ã³ã¿ãŒãã§ãŒã¹ã宣èšããããšããå§ããŸãã ã³ãŒãã£ããŒã¿ãŒã¯ãã®ã€ã³ã¿ãŒãã§ãŒã¹ã§åäœããŸãã 以äžãç°¡æœã«ããããã«ãã³ãŒãã®ã³ã¡ã³ãããã³ãã®ä»ã®éèŠã§ãªãéšåã¯çç¥ãããŸãã
@Worker public interface UserProfileService { public Profile get(String userId); public void blockNotification(String userId); }
ã¢ãããŒã·ã§ã³
@Worker
ã¯ããã®ã€ã³ã¿ãŒãã§ã€ã¹ãè«è² æ¥è
ãšããŠå®çŸ©ããŸãã 泚éã«ã¯ããã®ååãšïŒå¥çŽã®ïŒããŒãžã§ã³ãå®çŸ©ãããªãã·ã§ã³ã®å±æ§ããããŸãã ããã©ã«ãã§ã¯ãååã¯ã€ã³ã¿ãŒãã§ãŒã¹ã®ãã«ããŒã ã§ãããããŒãžã§ã³ã¯ã1.0ãã§ãã ç°ãªãããŒãžã§ã³ã®ãšã°ãŒãã¥ãŒã¿ã¯ã競åããããšãªãç°ãªãããã»ã¹ã§åæã«åäœã§ããŸãã
ã€ã³ã¿ãŒãã§ãŒã¹ã®å®è£
ã«ç§»ããŸãããã
public class UserProfileServiceImpl implements UserProfileService { private static final Logger logger = LoggerFactory.getLogger(UserProfileServiceImpl.class); @Override public Profile get(String userId) { return ProfileUtil.createRandomProfile(userId); } @Override public void blockNotification(String userId) { logger.info(".blockNotification(userId = [{}]", userId); } }
ããã§ã¯ããããã¡ã€ã«ãããŒãžã£ãŒïŒProfileUtilïŒã®åæåãçç¥ããŸããã ããŒã¿ããŒã¹ãLDAPããŸãã¯ãã®ä»ã®ã¬ãžã¹ããªã§åäœããŸãã ãã®äŸã¯ãè«è² æ¥è
ãã¿ã¹ã¯ïŒåŒã³åºãïŒãåãåããããããå®éã®ã¢ãžã¥ãŒã«ã«å§ä»»ããããšã瀺ããŠããŸãã
ããã§è«è² æ¥è
ã®äœæãå®äºããŸããã
åã«èšå®ããã¿ã¹ã¯ã解決ããã«ã¯ãã³ãŒãã£ããŒã¿ãŒã¯ãŸã åä¿¡ããŠããªããŠãŒã¶ãŒãããã¡ã€ã«ïŒPromiseãªããžã§ã¯ãïŒãžã®ãªã³ã¯ã転éããŠãããã«ã¢ã¯ã·ã§ã³ã決å®ããå¿
èŠããããŸãã ããã§ããã®ãŠãŒã¶ãŒãžã®ã¡ãã»ãŒãžéä¿¡ãæ¢ã«ãããã¯ãããŠããå Žåã圌ã¯ãã©ã³ã¹ããŒããéžæããããäœãéä¿¡ããŸããã
ãã ãããšã°ãŒãã¥ãŒã¿ãŒã®ã€ã³ã¿ãŒãã§ã€ã¹ã¯ããšã°ãŒãã¥ãŒã¿ãŒèªèº«ãšåæ§ã«ãçµæãåæçã«åä¿¡ããŠæäŸãããããå®è¡çµæã宣èšå
ã®Promiseãªããžã§ã¯ããšããŠæãããã¯ãªãŒã³ãªããŒã¿ãªããžã§ã¯ããè¿ããŸãã ããã¯æ£ããã§ãã è«è² æ¥è
ã¯ããã®äœ¿çšæ¹æ³ãç¥ãå¿
èŠã¯ãããŸããã ããšãã°ããããã¡ã€ã«ãååŸããããã®è«è² æ¥è
ã¯ããŠãŒã¶ãŒèå¥åãæ¢ã«ããã£ãŠããå ŽåããŸãã¯ãŠãŒã¶ãŒãäžæã§ããã®èå¥åãã©ããããååŸããå¥ã®ã¿ã¹ã¯ã«ãªã³ã¯ã転éããå¿
èŠãããå Žåã«äœ¿çšã§ããŸãã ãããã£ãŠãè«è² æ¥è
ãšã®ããåãã®ã€ã³ã¿ãŒãã§ã€ã¹ã«ãªããŸãã ãã®ã€ã³ã¿ãŒãã§ãŒã¹ã¯ãã³ãŒãã£ããŒã¿ãŒãå¿
èŠã«å¿ããŠæ±ºå®ããŸãã ã€ãŸã ã³ãŒãã£ããŒã¿ãŒã®ããã±ãŒãžïŒãããžã§ã¯ãïŒã§å®çŸ©ãããŸãã è«è² æ¥è
ãšã®ããåãã®ã€ã³ã¿ãŒãã§ã€ã¹ãè¿œå ããŠããããã¡ã€ã«ãæäœããŸãã
@WorkerClient(worker = UserProfileService.class) public interface UserProfileServiceClient { public Promise<Profile> get(String userId); public void blockNotification(String userId); }
@WorkerClient
ã¢ãããŒã·ã§ã³ã§ããŒã¯ãããã€ã³ã¿ãŒãã§ã€ã¹ã衚瀺ãããŸãã 泚éãã©ã¡ãŒã¿ãŒã¯ãè«è² æ¥è
ã®å®éã®ã€ã³ã¿ãŒãã§ãŒã¹ã®ã¯ã©ã¹ãåç
§ããŸãã ãã®ããã«ããŠãæ¢åã®ã€ã³ã¿ãŒãã§ãŒã¹ãšç¹å®ã®ã³ãŒãã£ããŒã¿ãŒã«å¿
èŠãªã€ã³ã¿ãŒãã§ãŒã¹ãšã®éã«ãªã³ã¯ã確ç«ãããŸãã ãã®ã€ã³ã¿ãŒãã§ãŒã¹ããè«è² æ¥è
ã®ã¯ã©ã€ã¢ã³ãã€ã³ã¿ãŒãã§ãŒã¹ããšåŒã³ãŸãã ãã®ã¯ã©ã€ã¢ã³ãã€ã³ã¿ãŒãã§ã€ã¹ã«ã¯ãã³ãŒãã£ããŒã¿ãŒã«å¿
èŠãªãã¹ãŠã®ã¡ãœããïŒæªäœ¿çšã宣èšããããšã¯ã§ããŸããïŒããã³åŒæ°ã®åäžã®çœ²åãå«ãŸããŠããå¿
èŠããããŸãã ãŸã å®äºããŠããªãã¿ã¹ã¯ã®çµæãåŒæ°ãšããŠæž¡ãããå Žåãä»»æã®åŒæ°ãPromiseã¿ã€ãã«ããããšãã§ããŸãã
ããã§ã¯ãæãèå³æ·±ãéšåãã€ãŸãã³ãŒãã£ããŒã¿ãŒã®äœæã«ç§»ããŸãããã ãŸããã³ãŒãã£ããŒã¿ãŒã€ã³ã¿ãŒãã§ã€ã¹ã以äžã«ç€ºããŸããããã䜿çšããŠãTaskurottaã¯ã©ã€ã¢ã³ããå¿
èŠãªããã»ã¹ãéå§ããŸãã
@Decider public interface NotificationDecider { @Execute public void start(String userId, String message); }
ãã®ã€ã³ã¿ãŒãã§ãŒã¹ã¯
@Decider
ãšããŠå®çŸ©ãããŠã
@Decider
-ã€ãŸã ã³ãŒãã£ããŒã¿ãŒãšããŠã ãã®æ³šéã«ã¯ã
@Worker
泚éãšåãããããã£ïŒååãšããŒãžã§ã³ïŒããããŸãã ããã©ã«ãã§ã¯ãã€ã³ã¿ãŒãã§ãŒã¹ã®ãã«ããŒã ãååãšããŠäœ¿çšãããã1.0ããããŒãžã§ã³ãšããŠäœ¿çšãããŸãã
startã¡ãœããã¯
@Execute
ãšããŠããŒã¯ãã
@Execute
ã ããã¯ããã®æ¹æ³ã§ããã»ã¹ãéå§ã§ããããšãæå³ããŸãã
次ã«ãã³ãŒãã£ããŒã¿ãŒã®å®è£
ã«é²ã¿ãŸã
public class NotificationDeciderImpl implements NotificationDecider { private static final Logger logger = LoggerFactory.getLogger(NotificationDeciderImpl.class); private UserProfileServiceClient userProfileService; private MailServiceClient mailService; private SMSServiceClient smsService; private NotificationDeciderImpl decider; @Override public void start(String userId, String message) { logger.info(".start(userId = [{}], message = [{}])", userId, message); Promise<Profile> profilePromise = userProfileService.get(userId); Promise<Boolean> sendResultPromise = decider.sendToTransport(profilePromise, message); decider.blockOnFail(userId, sendResultPromise); } @Asynchronous public Promise<Boolean> sendToTransport(Promise<Profile> profilePromise, String message) { logger.info(".sendToTransport(profilePromise = [{}], message = [{}])", profilePromise, message); Profile profile = profilePromise.get(); switch (profile.getDeliveryType()) { case SMS: { return smsService.send(profile.getPhone(), message); } case EMAIL: { return mailService.send(profile.getEmail(), message); } } return Promise.asPromise(Boolean.TRUE); } @Asynchronous public void blockOnFail(String userId, Promise<Boolean> sendResultPromise) { logger.info(".blockOnFail(userId = [{}], sendResultPromise = [{}])", userId, sendResultPromise); if (!sendResultPromise.get()) { userProfileService.blockNotification(userId); } } }
ãã®ã³ãŒãã§ã¯ããã©ã€ããŒããªããžã§ã¯ãã®åæåãçç¥ããŸããã å®å
šã§å®çšçãªãµã³ãã«ã³ãŒãã¯
taskurotta-getstartedãããžã§ã¯ãã«ãããŸãã ããã§ããã©ã€ããŒããã£ãŒã«ãã®å€ã¯ãã³ãŒãã£ããŒã¿ãŒã®ãããã·ãªããžã§ã¯ãã®ç¹å¥ãªãã¡ã¯ããªãŒãéããŠååŸãããããšã«æ³šæããŠãã ããã
å®è£
äŸã§ã¯ãã³ãŒãã£ããŒã¿ãŒã«ããæªå®äºã¿ã¹ã¯ã®å®äºçµæã®åŸ
æ©ãã€ã³ãã2ã€ãããŸãã ããã¯ãsendToTransportããã³blockOnFailã¡ãœããã§ãã ãããã®ã¡ãœããã¯ãPromiseåã®ãã¹ãŠã®åŒæ°ã®æºåãã§ãããšãã«ã®ã¿åŒã³åºãããŸãã
ã€ãŸã 察å¿ããã¿ã¹ã¯ãå®äºããŸãã
ã¿ã€ãMailServiceClientããã³SMSServiceClientã®ãã£ãŒã«ããªããžã§ã¯ãã¯ã察å¿ããè«è² æ¥è
ãžã®ã¯ã©ã€ã¢ã³ãã€ã³ã¿ãŒãã§ã€ã¹ã§ããããŸãã taskurotta-getstartedãããžã§ã¯ãã§åæåã確èªããããšãã§ããŸãã
çŸæç¹ã§ã¯ããã¹ãŠã®è«è² æ¥è
ãšã³ãŒãã£ããŒã¿ãŒãå®è£
ããŠããŸãã ã¢ã¯ã¿ãŒïŒãšã°ãŒãã¥ãŒã¿ãŒãšã³ãŒãã£ããŒã¿ãŒïŒã®ç«ã¡äžãã«çŽæ¥é²ã¿ãŸãã
ã¿ã¹ã¯ã¯ãã¢ããªã±ãŒã·ã§ã³ãµãŒããŒå
ã§å®è¡ããããšããåå¥ã®Javaã¢ããªã±ãŒã·ã§ã³ãšããŠå®è¡ããããšãã§ããŸãïŒãã®äŸã§ã¯ãtaskurotta \ bootstrapã¢ãžã¥ãŒã«ãšã¯å¥ã®ã¢ããªã±ãŒã·ã§ã³ã®ããªã¢ã³ãã䜿çšããŸãïŒã å¥ã®ã¢ããªã±ãŒã·ã§ã³ã¯äœãããŸããïŒ
- TaskurottaãµãŒããŒã«ç»é²æžã¿
- Nã¹ã¬ããã®ããŒã«ãéå§ããŠã¿ã¹ã¯ãå®è¡ããŸã
- TaskurottaãµãŒããŒããã¿ã¹ã¯ãåä¿¡ããŸã
- å®è¡ãéå§ããŸã
- çµæãTaskurottaãµãŒããŒã«è»¢éããŸã
å¥ã®Javaã¢ããªã±ãŒã·ã§ã³ãå®è¡ããã«ã¯ãããŒãã¹ãã©ããããã±ãŒãžãããå
·äœçã«ã¯ru.taskurotta.bootstrap.Mainã¯ã©ã¹ã䜿çšãããŸãã YAML圢åŒã®èšå®ãã¡ã€ã«ã®å ŽæãåŒæ°ãšããŠæž¡ãå¿
èŠããããŸãã
ã©ã®ããã«éå§ããããšããŸããïŒ ãšãŠãç°¡åã§ãã 以äžã¯ããµãŒããŒãã¢ã¯ã¿ãŒãããã³ãœãŒã¹ã³ãŒãããã®èµ·åã®æ®µéçãªã¢ã»ã³ããªã§ãã Linuxããæã¡ã§ãªãå Žåã¯æ³šæããŠãã ããããã€ããŒãªå€æŽãå¿
èŠã§ãã
ããªãã¯ãã§ã«æã£ãŠãããšä»®å®ããŸãïŒ
ãµãŒããŒTaskurottaãçµã¿ç«ãŠã
git clone https://github.com/taskurotta/taskurotta.git cd taskurotta/
ã¢ã»ã³ããªãå®è¡ããŸãã ã¹ããŒãã¢ããããã«ã¯ããã¹ããç¡å¹ã«ããŸãã
mvn clean install -DskipTests
次ã«ã2ã€ã®ããŒãã®ã¯ã©ã¹ã¿ãŒãå®è¡ããŸãïŒãã¢ã®ç®çã§1å°ã®ãã·ã³ã䜿çšããŠãããããèµ·åãªãã·ã§ã³ã§ç°ãªãããŒãã䜿çšããŠããŸãïŒã å®éã®ç°å¢ã§ã¯ãå¿
èŠãªæ°ã®ãã·ã³ãåãæ§æã§å®è¡ã§ããŸãã
æåã®ã¯ã©ã¹ã¿ãŒããŒããèµ·åããŸãã
java -Xmx64m -Ddw.http.port=8081 -Ddw.http.adminPort=9081 -Ddw.logging.file.currentLogFilename="assemble/target/server1.log" -jar assemble/target/assemble-0.4.0-SNAPSHOT.jar server assemble/src/main/resources/hz.yml
2çªç®ã®ããŒããèµ·åããŸãïŒåæ段éã§æå³çã«ã¡ã¢ãªãå¶éããŠãªãŒã¯ã®å¯èœæ§ãç¹å®ããŸãããã®äŸã®æ§æã§ã¯ãããŒã¿ããŒã¹ã¯äœ¿çšãããªããããããå€ãã®ã¡ã¢ãªãè¿œå ããå¿
èŠããããŸãïŒã
java -Xmx64m -Ddw.http.port=8082 -Ddw.http.adminPort=9082 -Ddw.logging.file.currentLogFilename="assemble/target/server2.log" -jar assemble/target/assemble-0.4.0-SNAPSHOT.jar server assemble/src/main/resources/hz.yml
äž¡æ¹ã®ãµãŒããŒãçžäºã«æ¥ç¶ãããšããã°ã¯æ¬¡ã®ã¡ãã»ãŒãžã®ããã«ãªããŸãã
Members [2] { Member [192.168.1.2]:7777 Member [192.168.1.2]:7778 this }
ãã©ãŠã¶ãŒã§ã³ã³ãœãŒã«ãéããŸãã
httpïŒ// localhostïŒ8081 / index.html-æåã®ããŒããŸãã¯
httpïŒ// localhostïŒ8082 / index.html -2çªç®ã®ããŒãã
ä»»æã®ããŒãã䜿çšããŠãã³ã³ãœãŒã«ãæäœã§ããŸãã äž»ã«åãæ
å ±ã衚瀺ãããŸãã çŸåšããã¹ãŠã®ã³ã³ãœãŒã«æ©èœããã®æ§æã§åäœããããã§ã¯ãããŸããïŒããŒã¿ããŒã¹ãªãïŒã ãã¹ãŠãoracleããã³mongodb dbã®æ§æã§æ©èœããŸãã
ããã¥ã¡ã³ãã®å±éãªãã·ã§ã³ãåç
§ããŠãã ããã
ããã§ã¯ãããã»ã¹ãå®è¡ããŸãããã ãã®ããã«taskurotta-getstartedãªããžããªãè€è£œããŸã
git clone https://github.com/taskurotta/taskurotta-getstarted.git cd taskurotta-getstarted/ mvn clean install
ã¢ã¯ã¿ãŒãäœæ¥ãéå§ããã«ã¯ãããã»ã¹ãéå§ããå¿
èŠããããŸãã ããšãã°91åãå®è¡ããŸãã
java -cp target/getstarted-process-1.0-SNAPSHOT.jar ru.taskurotta.example.starter.NotificationModule http://localhost:8081 91
ã³ã³ãœãŒã«
httpïŒ// localhostïŒ8081 / index.htmlã確èªããŸãã [ãã¥ãŒ]ã¿ããéžæããŸãã ã³ãŒãã£ããŒã¿ãŒ91ã«ã¯ã91çªç®ã®å®è¡ããã»ã¹ã«å¯Ÿå¿ããã¿ã¹ã¯ãããããšãããããŸãã

次ã«ãã³ãŒãã£ããŒã¿ãŒãå®è¡ããŸãã YAMLæ§æãã¡ã€ã«ã§å®çŸ©ãããŠããã®ã¯ããšã°ãŒãã¥ãŒã¿ãŒãªãã§ãã ãããã£ãŠãèµ·ååŸãããã»ã¹ã®ãã¹ãŠã®ã¿ã¹ã¯ãæ©èœããªããªããå®è¡è
ã®ã¿ã¹ã¯ã䞊ãã§è¡šç€ºãããŸãã
java -Xmx64m -jar target/getstarted-process-1.0-SNAPSHOT.jar -f src/main/resources/config-decider.yml
ã¯ã©ã¹ã¿ãŒã®æåã®ããŒãã¯ãæ§æãã¡ã€ã«ã§ã³ãŒãã£ããŒã¿ãŒã®TaskurottaãµãŒããŒãšããŠå®çŸ©ãããŠããŸã
spreader: - Spreader: class: ru.taskurotta.example.bootstrap.SimpleSpreaderConfig instance: endpoint: "http://localhost:8081" threadPoolSize: 10 readTimeout: 0 connectTimeout: 3000
ã³ã³ãœãŒã«ã§ãã¥ãŒãªã¹ããæŽæ°ãããšã°ãŒãã¥ãŒã¿ãŒãåŸ
ã£ãŠããã¿ã¹ã¯ãããããšã確èªã§ããŸãã
ããã§ããšã°ãŒãã¥ãŒã¿ãå®è¡ãïŒã³ãŒãã£ããŒã¿ãåäœãããŸãïŒããããã2çªç®ã®ã¯ã©ã¹ã¿ããŒãã«åããŠãã¢ã³ã¹ãã¬ãŒã·ã§ã³ããŸãã ã¯ã©ã¹ã¿ãŒããŒãã¯å
±æã¡ã¢ãªãšå
éšã¿ã¹ã¯ãå®è¡ããããã®ç°å¢ã圢æããããããšã°ãŒãã¥ãŒã¿ãŒããã®èŠæ±ãã©ã®ãµãŒããŒããã®ãã®ã§ãããã¯é¢ä¿ãããŸããã
java -Xmx64m -jar target/getstarted-process-1.0-SNAPSHOT.jar -f src/main/resources/config-workers.yml
ããã©ãŒããŒã«ã¯ãçžäºäœçšã®ããã®2çªç®ã®ã¯ã©ã¹ã¿ãŒããŒãããããŸãã
spreader: - Spreader: class: ru.taskurotta.example.bootstrap.SimpleSpreaderConfig instance: endpoint: "http://localhost:8082" threadPoolSize: 10 readTimeout: 0 connectTimeout: 3000
ãã®çµæããã¹ãŠã®ããã»ã¹ãå®å
šã«æ©èœãã管çã³ã³ãœãŒã«ã§é çªã«ç¢ºèªã§ããŸãã

ãããŸã§ã®ãšãããç§ãçŸæç¹ã§å
±æããããã¹ãŠã®ããšã ææ¡ã建èšçãªæ¹å€ãæè¿ããŸãã