FilesystemStore
ã«ã¯ãä¿®æ£ããäºå®ã®ç«¶åç¶æ
ããããŸãããå
ã«é²ãã§å®è¡ããåã«ãå
¥åããé¡ãããŸãã åºæ¬çã«åé¡ã¯ãåããŠãŒã¶ãŒïŒåãã»ãã·ã§ã³ïŒããã®åæãªã¯ãšã¹ããããå Žåã次ã®å¯èœæ§ãããããšã§ãã
ãã®æ¬ é¥ã®ãã¹ãã±ãŒã¹ãcless / sessions @ f84abeda17de0b4fcd72d277412f3d3192f206f2ã«è¿œå ããŸããã
ãããä¿®æ£ããæãç°¡åãªæ¹æ³ã¯ããã¡ã€ã«ã·ã¹ãã ã¬ãã«ã§ããã¯ãå°å
¥ããããšã§ãã ãã ããgolangã«ã¯ãã¡ã€ã«ããã¯ãè¡ãããã®ã¯ãã¹ãã©ãããã©ãŒã ã®æ¹æ³ããããŸããã syscall
flock
ãå
¬ââéããŸãããOSããµããŒãããŠããå Žåã«ã®ã¿æ©èœããŸãã 矀ãã®æ¯ãèãã¯ãUNIXã«ãã£ãŠãç°ãªãå¯èœæ§ããããšæããŸãããããã§ãããã©ããã¯ããããŸããã flockã®ãã1ã€ã®åé¡ã¯ãNFSã§ã¯æ©èœããªãå¯èœæ§ãããããšã§ãã
ãŸã£ããç°ãªã解決çã¯ã FilesystemStore
ãªããžã§ã¯ãèªäœã«ããã¯ã®ããããä¿æããããšã§ãã ããã«ã¯å¥ã®æ¬ ç¹ããããŸããè€æ°ã®ããã»ã¹ãåããã¡ã€ã«ã·ã¹ãã ã»ãã·ã§ã³ã«ã¢ã¯ã»ã¹ããããšã¯ã§ãããåäžã®ã¢ããªã±ãŒã·ã§ã³å
ã§åããã¡ã€ã«ã·ã¹ãã ã»ãã·ã§ã³ã«å¯ŸããŠè€æ°ã®ã¹ãã¢ãäœæããããšã¯ã§ããŸããã ãã ãããããã®äž¡æ¹ãåé¡ãªãå®è¡ããããšã¯ãã§ã«äžå¯èœã§ãã
çµå±ã®ãšãããæåã®è§£æ±ºçã¯ãã¹ãã¢ãªããžã§ã¯ãã«ããã¯ã®ããããä¿æããããšã ãšæããŸããããã¯ããã®ã·ããªãªã®ãã¹ãŠã®æ¬ ç¹ãé©åã«ææžåã§ããç°ãªãã·ã¹ãã éã§åãåäœã§ãããšè¿ä¿¡ã§ããããã§ãã
FilesystemStoreã«åºã¥ãä»ã®ã¹ãã¬ãŒãžããã¯ãšã³ãããã®æ¬ é¥ãã³ããŒããå¯èœæ§ããããŸãïŒç§ã®boj / redistoreïŒ2ã®ãããžã§ã¯ãã®Redistoreã³ãŒãã確èªãããšãã«ãã®åé¡ã«æ°ã¥ããŸããïŒ
ããã¯ãã代ããã«ããã©ã³ã¶ã¯ã·ã§ã³ããŒã¹ã®ã·ã¹ãã ã¯ã©ãã§ããïŒ Sessionãªããžã§ã¯ãã¯lastModifiedãã£ãŒã«ããéã¶ããšãã§ããŸãã ã»ãã·ã§ã³ãã»ãã·ã§ã³ã¹ãã¢ã«ä¿åãçŽãããšãããšãæåŸã«èªã¿åãããŠããå€æŽãããããšã瀺ããšã©ãŒãè¿ãããŸãã ãã®åŸãããã°ã©ããŒã¯ã»ãã·ã§ã³ãå床ååŸããŠåè©Šè¡ããããšãéžæã§ããŸãã
ããã¯ããŸãããå¯èœæ§ããããã¯ãªãŒã³ã¢ããããå¿ èŠã®ããããã¯ããªãããããããã¯ã®å¯èœæ§ããªããšããå©ç¹ããããŸãã ãªã¯ãšã¹ãã®å®è¡å 容ã«ãã£ãŠã¯ãéçºè ãæå³ã®ããåè©Šè¡ãåžžã«å®è¡ã§ãããã©ããã¯ããããŸããã ããã¯ã¯ééããªãããå®å šãªãªãã·ã§ã³ã ãšæããŸãããAPIã倱æã®å¯èœæ§ãæ確ã«ææžåããéçºè ããããã®ãšã©ãŒãç±å¿ã«åŠçããã°ããã©ã³ã¶ã¯ã·ã§ã³ã¯ç¢ºãã«æ©èœããå¯èœæ§ããããŸãã
ãšã¯ããã FilesystemStore
ããã©ã³ã¶ã¯ã·ã§ã³ã䜿çšããå Žåã§ããAPIã¯ãããã¯ã䜿çšããã¹ãã¬ãŒãžããã¯ãšã³ãçšã«æºåããå¿
èŠããããšæããŸãããããã¯ã session.Save()
è€æ°ååŒã³åºãããšãçŠæ¢ããããæ°ããsession.Release()
å°å
¥ããããšãæå³ããŸãã
RediStoreã«åœ±é¿ããããããã®åé¡ã«ç¶ããŠã æ å ±ãããããšã@cless
é·æçã«ã¯æ£ããããšããã以å€ã«ãçŸæç¹ã§ã¯ç¹ã«å¥œã¿ã¯ãããŸãã:)ãã¡ãããæ¢åã®APIãç¶æããããšæããŸãã ãŸãããã¡ãã¡ã«ããã¯ãè¿œå ãããšãè€éããšãªãŒããŒããããå€§å¹ ã«å¢å ããŸããããããé¿ãããšããã§ãããã
ãã®åé¡ã解決ããä»ã®ã»ãã·ã§ã³ãã¬ãŒã ã¯ãŒã¯ã®äŸã¯ãããŸããïŒ åœŒããäœãããŠããã®ãç¥ãããã§ãã
ããã©ã«ãã®phpã»ãã·ã§ã³ãã³ãã©ãŒããã¡ã€ã«ã·ã¹ãã ããŒã¹ã®ããã¯ã䜿çšããŠããããšãç¥ã£ãŠããŸãïŒphp 5.4 tarballã§ã¯ãããããã¡ã€ã«ext/session/mod_files.c
ããããšã確èªããŸããã ext/standard/flock_compat.c
ã«ãã£ãŠæäŸãããflockã䜿çšããŸãïŒã
phpãè©å€ãèããã°è¯ãäŸãã©ããã¯ããããŸããããçŸæç¹ã§ç§ãç¥ã£ãŠããã®ã¯phpã ãã ãšæããŸãã ä»ã®ãã¬ãŒã ã¯ãŒã¯ãèŠã€ããŠãããããã©ã®ããã«åé¡ã解決ãããã確èªããããã«ãåšããèŠåããŠã¿ãŸãã
FlaskãPyramidããŸãã¯Djangoãããããã©ã®ããã«åŠçããããç¥ããããšæããŸãã æéãããã°èŠãŠãããŸãã 誰ãããã®ã³ãŒãããŒã¹ã«ç²ŸéããŠããã°ãRailsãèå³æ·±ãã§ãããã
PyramidãšFlaskã¯ã©ã¡ããããŒã¿ã®ä¿åã«Cookieã䜿çšããŠããããã§ãããã©ã¡ãã競åç¶æ ãåŠçããŠããªããšæãããŸãã ç§ã¯ããã¥ã¡ã³ããç°¡åã«èªãã ã ããªã®ã§ãééã£ãŠããå¯èœæ§ããããŸãã
Djangoã¯ãµãŒããŒåŽã®ã»ãã·ã§ã³ããŒã¿ããµããŒãããŠããã®ã§ããã®ã³ãŒããå°ãèŠãŠãããŸãã
ããã©ã«ãã®Djangoã»ãã·ã§ã³ããã¯ãšã³ãã¯ããŒã¿ããŒã¹ã§ãããããã¯ç§ãããç¥ããªãDjangoããŒã¿ããŒã¹æœè±¡åã¬ã€ã€ãŒã䜿çšããŠããããã解éããã®ãå°é£ã§ãã ããããç§ã¯ãã®ã³ã¡ã³ãããã¡ã€ã«ã·ã¹ãã ããã¯ãšã³ãã§èŠã€ããŸããïŒ
# Write the session file without interfering with other threads
# or processes. By writing to an atomically generated temporary
# file and then using the atomic os.rename() to make the complete
# file visible, we avoid having to lock the session file, while
# still maintaining its integrity.
#
# Note: Locking the session file was explored, but rejected in part
# because in order to be atomic and cross-platform, it required a
# long-lived lock file for each session, doubling the number of
# files in the session storage directory at any given time. This
# rename solution is cleaner and avoids any additional overhead
# when reading the session data, which is the more common case
# unless SESSION_SAVE_EVERY_REQUEST = True.
#
# See ticket #8616.
ããã¯ãã»ãã·ã§ã³ãã¡ã€ã«ã®å
容ãç Žæããªãããã«ããããšã瀺åããŠããããã§ããã競åç¶æ
ãçºçããªãããšã瀺åããŠããããã§ã¯ãããŸããã 誰ããDjangoã®çµéšãæã£ãŠãããªããcless / sessions @ f84abedã®ãããªãã¹ãã±ãŒã¹ãèŠããšããã§ãããã
Stackoverflowã¯ãDjangoãã»ãã·ã§ã³ã§ç«¶åç¶æ
ã«ãªã£ãŠããå¯èœæ§ãããããšã瀺ããŠããããã§ãïŒ http ïŒ//stackoverflow.com/searchïŒq = django + session + race + condition
äºè§£ããŸãããFileSystemStoreã«ã¯ãã»ãã·ã§ã³ã¹ãã¢ã®ç Žæãé²ãããã«ããã§ã«ç²ç²åºŠã®ãã¥ãŒããã¯ã¹ããããŸãã äžéšã®ãªã¯ãšã¹ãã®äžè²«æ§ãé«ããããã ãã«ããªã¯ãšã¹ãããšã«å€ãã®ãªãŒããŒããããè¿œå ããããããã©ã€ãã©ãªã«è¿œå ã®ä¿è·ãã©ã®çšåºŠè¿œå ãã䟡å€ããããã¯ããããŸããã 確ãã«ããã§ã®ã·ããªãªã¯å®è¡å¯èœã§ãããäžè¬çãªæå³ã§æ±ãã«ã¯ããããè€éããããšæããŸãã çŸåšã®ç¶æ³ããŸã£ããåé¡ãªãå Žåãå€ãããšãããããŸãããäžéšã®ã¢ããªã±ãŒã·ã§ã³ã§ã¯åé¡ã«ãªãå¯èœæ§ããããŸãã ãšã«ãããã»ãšãã©ã®å Žåãç¹å®ã®ã»ãã·ã§ã³ã«å¯ŸããŠå®è¡äžã®ãªã¯ãšã¹ãã¯1ã€ã ãã ãšæããŸãã
å®éãããã¯ã©ã®WebãªãœãŒã¹ã«ãååšããåé¡ã§ããæ å ±ã«åºã¥ããŠãGETã®åŸã«PUTãå®è¡ããå Žåãåãããšãèµ·ãããŸããããã®éã«ç¶æ³ãå€ãã£ãå¯èœæ§ããããŸãã
ãšã«ãããããã¯çŸæç¹ã§ã®ç§ã®èãã§ãããããã«è°è«ã§ããŠããããã§ãã
é·æçã«ã¯ãããã¯ã¢ããªã±ãŒã·ã§ã³ãã¡ã€ã³ã®åé¡ã®ããã§ãã
clessãæçš¿ããã·ããªãªãèãããšããªã¯ãšã¹ã1ãååã«é·ãå®è¡ãããŠãªã¯ãšã¹ã2ã䞊è¡ããŠçºçããå¯èœæ§ãããå ŽåïŒããšãã°ãAngular.jsã§èšè¿°ãããã·ã³ã°ã«ããŒãžã¢ããªã±ãŒã·ã§ã³ããŸãã¯ããã€ãã®APIã«ãããããéåæNode.jsã¢ããªïŒãé·æéå®è¡ããããªã¯ãšã¹ãã¯ã»ãã·ã§ã³ããåãé¢ãããã®æç¹ã§ç¬ç«ããã¯ãŒã«ãŒããã»ã¹ãšèŠãªãå¿ èŠããããŸãã
ãã¡ãããããã¯åé¡ã«çŽæ¥å¯ŸåŠãããã®ã§ã¯ãããŸããããkisielkãè¿°ã¹ãããã«ãããããçš®é¡ã®ããã¯ãå®è¡ãããšãéççãªã±ãŒã¹ã®ããã«èŠãããã®ã«å€ãã®ãªãŒããŒããããè¿œå ãããŸãã
ããã¯ãã»ãã·ã§ã³ã®ç«¶åç¶æ
ã®åœ±é¿ã®å®éã®äŸã§ãã ãã°ã¯ãããã°ãé£ãããäžèŠã©ã³ãã ã«è¡šç€ºãããéçºè
ãšãŠãŒã¶ãŒã®äž¡æ¹ã«ãšã£ãŠè¿·æã§ãã ajaxãå€çšããååã«å€§ããªã¢ããªã±ãŒã·ã§ã³ãèãããšããããã®ç«¶åç¶æ
ã¯é
ããæ©ããçŸããã§ãããã
http://www.hiretheworld.com/blog/tech-blog/codeigniter-session-race-conditions
http://www.chipmunkninja.com/Troubles-with-Asynchronous-Ajax-Requests-g@
åæ§ã®åé¡ãæ±ã£ãŠããEllisLab / CodeIgniterïŒ1746ã®ã¹ã¬ããå šäœãèªã¿ãŸããããCodeIgniterãæã ã»ãã·ã§ã³IDã匷å¶çã«åçæãããšããäºå®ã«ãã£ãŠåé¡ãè€éã«ãªããããã§ã®è°è«ã®ã»ãšãã©ã¯ãã®äºå®ãäžå¿ã«å±éããŠããŸãã
äºææ§ã®ãªãæ¹æ³ã§ã»ãã·ã§ã³ãå€æŽããããæ¢åã®ã¢ããªã±ãŒã·ã§ã³ãå£ãå¯èœæ§ã®ããAPIã«åŸ®åŠãªéããå°å ¥ãããããããšã«æµæãããããšãç解ããŠããŸãã ãã ãããªãã·ã§ã³ã®ããã¯ãå¿ èŠã ãšæããŸãã 次ã®ããã«ã¹ãã¢APIã«2ã€ã®é¢æ°ãè¿œå ããã®ã¯ã©ãã§ããã
type Store interface {
Get(r *http.Request, name string) (*Session, error)
New(r *http.Request, name string) (*Session, error)
Save(r *http.Request, w http.ResponseWriter, s *Session) error
Lock(r *http.Request, name string) error
Release(r *http.Request, name string) error
}
ãããã®é¢æ°ã®äœ¿çšã¯å®å šã«ãªãã·ã§ã³ã§ããïŒã»ãã·ã§ã³ã«æžã蟌ããã¹ãŠã®èŠæ±ãããã¯ããããšãå人çã«æšå¥šããŸããïŒãæ¢åã®ã¢ããªã±ãŒã·ã§ã³ã«åœ±é¿ãäžããããšã¯ãããŸããã
ææ¡ãããããã¯ã€ã³ã¿ãŒãã§ã€ã¹ã«ã¯åé¡ããããŸããããã¯ãMySQLãªã©ã®ããŒã¿ããŒã¹ã«ä¿æãããŠããŠãããã¯ãååŸããåŸã«ããŒã¿ããŒã¹æ¥ç¶ãåæãããå Žåãããã¯ã解æŸããããšã¯ã§ãããã»ãã·ã§ã³ã¯äºå®äžãããããã¯ãããŸãã ããã¯ã¯äœããã®æ¹æ³ã§æéåãã«ãªãã¯ãã§ããããããéçºè ã«ã©ã®ããã«å ¬éãããã¹ããå®å šã«ã¯ããããŸããã
ç³ãèš³ãããŸããããæçš¿ãããšãã«Bojã®è¿ä¿¡ãèŠéããŸããã
é·æéå®è¡ãããèŠæ±ã¯ã競åç¶æ
ãããªã¬ãŒããããã®èŠä»¶ã§ã¯ãªãããšã«æ³šæããããšãéèŠã§ãã ç§ã®ãã¹ãã±ãŒã¹ã§ã®500ããªç§ã®ã¹ãªãŒãã¯ã競åç¶æ
ãããªã¬ãŒãããããšã確èªããããã ãã«ãããŸãã çŸå®ã®äžçã§ã¯ããããã®ç«¶åç¶æ
ã¯ãçããèŠæ±ã§ãçºçããŸãããé »åºŠã¯äœããªããŸãããã®ããããããã°ãå°é£ã«ãªããŸãã
ãŸããé«è² è·ã§ã¯ãçããªã¯ãšã¹ãã§ãå®è¡ã«æéããããå Žåãããããšã«æ³šæããå¿ èŠããããŸãã
@clessè¯ãç¹ã
ç§ã¯ããªãã®ææ¡ãããã€ã³ã¿ãŒãã§ãŒã¹ã®å€æŽã奜ãã§ãã
ããã¯ã®æå¹æéã¯RediStoreã«æ¯èŒçç°¡åã«å®è£ ã§ããŸããRedisã«ã¯ãããŒã«TTLãèšå®ã§ããEXPIREã³ãã³ãããããŸãã
ãã®çš®ã®ãã现ããããã¯ã¯ãå€ãã®çš®é¡ã®ã»ãã·ã§ã³ã¹ãã¢ã«ãšã£ãŠäŸç¶ãšããŠããªãéå¹ççã§ã¯ãªãã§ããããã ãããŠãæå¹æéãåé¡ã§ãã
åé¡ã®äžéšã¯ãã»ãã·ã§ã³ãé·ãååšããŠããŠãä¿åãæåããå¯èœæ§ãããããšã§ããããã§ãªãå Žåãåé¡ã®è§£æ±ºã«å€§ãã«åœ¹ç«ã€ã®ã§ã¯ãªãã§ããããã
@kisielk ãéå¹çãªåºèã®äŸãæããŠããã ããŸããïŒ ã»ãšãã©ã®Key-ValueããŒã¿ããŒã¹ã«ã¯ãããã¯ãäœæã§ããäœããã®åœ¢åŒã®ã¢ãããã¯æäœããããŸãã SQLããŒã¿ããŒã¹ã¯éåžžãè¡ããŒã¹ã®ããã¯ã«ã¢ã¯ã»ã¹ã§ããŸãïŒãã ããããã§ã®è©³çŽ°ã«ã€ããŠã¯ããç¥ããªããšèšããããåŸãŸããïŒã
redisã®ãããªKey-Valueã¹ãã¢ã®ããã¯æ¹æ³ã§ã¯ãããŒã¿ããŒã¹ãžã®è€æ°ã®ã©ãŠã³ãããªãããå¿
èŠã§ããããããããããããªãã®æå³ããããšã§ããïŒ
goã¯ãã¡ã€ã«ããã¯ã«ã¢ã¯ã»ã¹ããããã®ã¯ãã¹ãã©ãããã©ãŒã ã®æ¹æ³ãæäŸããªãããããã¡ã€ã«ã·ã¹ãã ã¹ãã¢ã«åé¡ããããŸãã cgoã䜿çšãããšãã¡ã€ã³ãã©ãããã©ãŒã ããµããŒããããã©ãããã©ãŒã ãäœæã§ãããšæããŸãããããã¯ããããåé¿ãããœãªã¥ãŒã·ã§ã³ã§ãã
çŸåšã®ã»ãã·ã§ã³ãåé€ããã»ãã·ã§ã³åºå®ãé²ãããã«æ°ããã»ãã·ã§ã³ã«çœ®ãæããããšã«ã€ããŠè©±ããŠããã®ã§ãªãéããã»ãã·ã§ã³ãååšããªããªã£ããšãã«ä¿åããããšã¯å®éã®åé¡ã§ã¯ãªããšæããŸãããæ£çŽãªãšãããããã¯ãŸã£ããå¥ã®åé¡ã§ãã
@boj ãåé¡ã¯ãããã°ã©ããŒãä¿åãè©Šã¿ãåã«ãããã¯ããŸã æéåãã«ãªã£ãŠããªãããšã確èªããããã®äœããã®æ¹æ³ãå¿ èŠãªããšã§ãã ããã¯ã®æå¹æéã¯ã©ã®ãããã«ããå¿ èŠããããŸããïŒ
ããã¯ãããå®è¡ããããã®1ã€ã®å¯èœãªæ¹æ³ã§ãããç§ã¯ããããšãŠã奜ããã©ããã¯ããããŸããã ããªãã¯æèšãçªç¶åé²ãããåŸéãããããªãããšã«äŸåããŠãããããã¯å®å šãªä»®å®ã§ã¯ãããŸããïŒ
func Lock(expiration time.Duration) time.Time {
// Block here until the lock becomes your. Set the lock to expire after
// dur+50ms. This extra 50 ms ensures that you never assume you own an
// expired lock
return time.Now().Add(expiration)
}
func main() {
end := Lock(1000 * time.Millisecond)
// Do your thing here ...
// time.Sleep(1100 * time.Millisecond)
if time.Now().After(end) {
fmt.Println("Lock expired, throw an error")
} else {
fmt.Println("Good to go, save the session")
}
}
@clessããªãã®ã³ã¡ã³ãå šäœã¯ã @ kisielkã®å¿é äºã®ããã«æãããããšã
ææ¡ããããã«ãŽãªã©/ã»ãã·ã§ã³ã®ã€ã³ã¿ãŒãã§ãŒã¹éšåãå®è£ ããã®ã¯éåžžã«ç°¡åãããããŸããããåãããã«ç°¡åã«ããã¯/ãªãªãŒã¹ãå®è£ ããªãéããããã¯ãšã³ããç°¡åã«äº€æã§ããå Žåãšã§ããªãå Žåãããã·ããªãªãäœæããŸããããŠå¹ççãªæ¹æ³ã ããªããææ¡ãããã®ã«é¢ããŠã¯ãã©ãããå€ãããããã§ããäœããããŸãããããã¯ãšã³ãã¯ããã¯ã®ããã°ã©ãã³ã°ã«é Œããã«ãããå®è£ ã§ããŸããïŒããç¶ããŠãFileSystemStoreããFooBarStoreã«ã¹ã¯ããããããšããŸããããããã§ã¯ãããŸããã Lock / Releaseãå®è£ ããŠããããã§ãããã°ã©ã ãæåŸ ã©ããã«åäœããŸãããã
ã»ãã·ã§ã³ããšã®ããã¯ã®åŸ®åŠãªéãã«ã€ããŠã®è¯ãèšäºãããã«ãããŸãïŒ
http://thwartedefforts.org/2006/11/11/race-conditions-with-ajax-and-php-sessions/
ããã§ãã§ã«çµè«ãåºããŠããããã«ãäœãåé¡ãçºçããå Žåã®ããã¯ã®ã¿ã€ã ã¢ãŠãã¯ããã®çš®ã®ã¹ããŒã ãå®è£ ããéã®äž»èŠãªåé¡ã®1ã€ã§ãã ããã«ã¯ããã«æ€èšãå¿ èŠã§ãããããã¯ãšã³ãã«å€§ããäŸåããŸã
Lock / Releaseãå®è£ ããéããåå¥ã®ã€ã³ã¿ãŒãã§ã€ã¹ã䜿çšããããšã§ãã»ãã·ã§ã³ããšã®ããã¯ã®å®è£ ããªãã·ã§ã³ã«ããããšãã§ããŸãã ãã®åŸãããã¯ãšã³ãããã®ã€ã³ã¿ãŒãã§ã€ã¹ã«å¯ŸããŠã¢ãµãŒãã§ããŸããããã¯ãšã³ããå®è£ ãããŠããªãå Žåã¯ãã¡ã¢ãªå ããã¯ã䜿çšããŠããã©ã«ãã®å®è£ ãæäŸã§ããŸãã
ãã¡ããããã1ã€ã®åé¡ã¯ãã©ã€ãã©ãªã®ãŠãŒã¶ãŒãããã¯ãšãªãªãŒã¹ã䜿çšããããã«ã³ãŒããæŽæ°ããå¿ èŠãããããšã§ãããããããªããã°ãçŸåšãšåãåäœã«ãªããšæããŸãã
ãã¡ã¢ãªå ããã¯ã䜿çšããŠããã©ã«ãã®å®è£ ãæäŸã§ããŸãã
ããã¯ããªã¯ãšã¹ããè² è·åæ£ãããŠãããã«ããµãŒããŒç°å¢ã§ã¯æå³ããããŸããã
ã»ãã·ã§ã³ã䜿çšããæ¢åã®ã³ãŒãã®åäœãå€æŽããã«æ£ããå®è£ ã§ãããããããã¯çšã«ãŸã£ããç°ãªãã€ã³ã¿ãŒãã§ã€ã¹ãæäŸãããšããã¢ã€ãã¢ãæ°ã«å ¥ã£ãŠããŸãã
@bojãææããããã«ãããŒã¿ããŒã¹ã¹ãã¢ã«æå³ã®ããæ¹æ³ã§ã¡ã¢ãªããã¯ãæäŸããããšã¯ã§ããŸããã ããã¯æ©èœãæäŸããè² æ ã¯ãããããã¹ãã¢éçºè ã«ããã¯ãã§ãã ããã¯ã€ã³ã¿ãŒãã§ã€ã¹ããªãå Žåã§ããã»ãã·ã§ã³ãããã¯ã€ã³ã¿ãŒãã§ã€ã¹ã䜿çšããããšãããšãšã©ãŒãè¿ãããå¯èœæ§ããããŸãã ããã¯å®éã«ã¯åé¡ã«ã¯ãªããªãã¯ãã§ããããã©ã«ãã®ã¹ãã¢ãããã¯ãæäŸããå Žåãä»ã®éçºè ãããã«è¿œéãããŠãŒã¶ãŒã¯ãããšããã£ããšããŠããæå°éã®äžäŸ¿ãæããã§ãããã
äžéšã®ã¹ãã¢ã§ã¯ã¡ã¢ãªããã¯ããŸã æå³ããªãå¯èœæ§ãããã FilesystemStore
ããããã®åè£ãšããŠé©ããŠãããšæããŸãã çŸå®çã«ã¯ãè² è·åæ£ãããç¶æ³ã§ãã¡ã€ã«ã·ã¹ãã ã¹ãã¢ã䜿çšããããšã¯ãããŸããïŒçè«çã«ã¯ãããã¯ãŒã¯ãã¡ã€ã«ã·ã¹ãã ã§å¯èœã§ããïŒã ãã¡ã€ã«ã·ã¹ãã ããã¯ã¯æãŸããããã«æãããŸãããã¯ãã¹ãã©ãããã©ãŒã ãå€åºå
ã§å®è£
ããã®ã¯é£ããããã§ããããã«ãNFSã§ã®åäœãä¿èšŒãããŠããŸããã
@boj ïŒåæããŸãããã @ clessãææããŠããããã«ãããã¯ããªããæã£ãŠããåºã®çš®é¡ã«åºã¥ããŠããŸãã FilesystemStoreã¯ãã»ãã·ã§ã³ã¹ãã¢ã®åæå€æŽãé²ãããã«ããã§ã«RWMutexã«äŸåããŠããŸãã ã»ãšãã©ã®ããã¯ãšã³ãã¯å®éã«ã¯å°ãªããšãæçµçã«ã¯ããã¯ã€ã³ã¿ãŒãã§ã€ã¹ãå®è£ ãããšæããŸãããããã©ã«ããèšå®ãããšãéçºè ã¯ãããŸã§ã®éãåäžãµãŒããŒç°å¢ã«é©ãããªãªãŒã¹ãè¡ãããšãã§ããŸãã FilesystemStoreã¯ãGoã©ã€ãã©ãªã®ã¯ãã¹ãã©ãããã©ãŒã ããã¯ç¶æ³ãæ¹åããããŸã§ã¯ãã®1ã€ã§ãã
ç§ã¯@clessã«å®å šã«åæããã»ãã·ã§ã³ããã¯ã®éèŠæ§ã匷調ããããšæããŸããæçãããã©ãããã©ãŒã ïŒPHPãªã©ïŒã¯ã»ãã·ã§ã³ã¹ãã¢ã«å®è£ ããŸãã ãã¡ã€ã«ã§ã¯ããflockãã·ã¹ãã ã³ãŒã«ã䜿çšããmemcacheã§ã¯ããaddãæäœã®æ»ãå€ãšãããlockããµãã£ãã¯ã¹ãšæå¹æéãèšå®ãããè¿œå ã®ããŒã䜿çšããŸãã ãŸãã @ kisielkãæ°ããã€ã³ã¿ãŒãã§ã€ã¹ã䜿çšãããšããã¢ãããŒãã«ãåæããŸãïŒé¢æ°ãLockããšãReleaseãã䜿çšããã®ã¯çã«ããªã£ãŠããŸããããã䜿çšã§ããŸããïŒGoã¯ãé«ãããã©ãŒãã³ã¹ãšä¿¡é Œæ§ãå®çŸããããã®èšèªã§ããç§ã¯ããšãã°ãããã€ãã®å®è£ ïŒFileSystemãRedisãMemcacheïŒã«è²¢ç®ããçšæããããŸããããã€ãã®æ°ããæ§æãªãã·ã§ã³ãå¿ èŠã§ããããšã«æ³šæããŠãã ããã
ãã®åé¡ã¯ãæè¿ã®æŽæ°ã確èªãããŠããªããããèªåçã«å€ããã®ãšããŠããŒã¯ãããŠããŸãã æ°æ¥ã§èªåçã«ééãããŸãã