FilesystemStore
์ ๋ด๊ฐ ๊ณ ์น๋ ค๊ณ ํ๋ ๊ฒฝ์ ์กฐ๊ฑด์ด ์์ง๋ง ๊ณ์ ์งํํ๊ธฐ ์ ์ ๊ทํ์ ์๊ฒฌ์ ๋ถํ๋๋ฆฝ๋๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก ๋ฌธ์ ๋ ๋์ผํ ์ฌ์ฉ์ (๋์ผ ์ธ์
)์ ๋์ ์์ฒญ์ด์๋ ๊ฒฝ์ฐ ๋ค์์ด ๊ฐ๋ฅํ๋ค๋ ๊ฒ์
๋๋ค.
์ด ๊ฒฐํจ์ ๋ํ ํ ์คํธ ์ผ์ด์ค๋ฅผ cless / sessions @ f84abeda17de0b4fcd72d277412f3d3192f206f2์ ์ถ๊ฐํ์ต๋๋ค.
์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๊ฐ์ฅ ์ง์ ์ ์ธ ๋ฐฉ๋ฒ์ ํ์ผ ์์คํ
์์ค์์ ์ ๊ธ์ ๋์
ํ๋ ๊ฒ์
๋๋ค. ๊ทธ๋ฌ๋ golang์๋ ํ์ผ ์ ๊ธ์ ์ํํ๋ ๊ต์ฐจ ํ๋ซํผ ๋ฐฉ๋ฒ์ด ์์ต๋๋ค. ๊ทธ๊ฒ์ ๋
ธ์ถ์ํ์ง flock
์ syscall
ํ์ง๋ง ๊ฒฝ์ฐ์๋ง OS ์ง์์ ์๋ํฉ๋๋ค. ๋๋ ์ด๊ฒ์ด ์ฌ์ค์ธ์ง ํ์คํ์ง ์์ง๋ง ๋ค๋ฅธ ์ ๋์ค์์ ๋ฌด๋ฆฌ์ ํ๋์ด ๋ค๋ฅผ ์๋ ์๋ค๊ณ ์๊ฐํฉ๋๋ค. flock์ ๋ ๋ค๋ฅธ ๋ฌธ์ ๋ 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
์ ๊ณตํ๋ ๋ฌด๋ฆฌ๋ฅผ ์ฌ์ฉํฉ๋๋ค).
php๊ฐ ๋ช ์ฑ์ ๊ฐ์ํ ๋ ์ข์ ์์ธ์ง ํ์คํ์ง ์์ง๋ง ํ์ฌ ๋ด๊ฐ ์๋ ์ ์ผํ ๊ฒ์ ๋๋ค. ๋ค๋ฅธ ํ๋ ์ ์ํฌ๋ฅผ ์ฐพ์ ์ ์๋์ง ํ์ธํ๊ณ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ์ ์ดํด ๋ณด๊ฒ ์ต๋๋ค.
Flask, Pyramid ๋๋ Django๊ฐ ์ด๋ฌํ ์์ ์ ์ด๋ป๊ฒ ์ฒ๋ฆฌํ๋์ง ๊ถ๊ธํฉ๋๋ค. ์๊ฐ์ด ์์ผ๋ฉด ์ดํด ๋ณด๊ฒ ์ต๋๋ค. ๋๊ตฌ๋ ์ง ๊ทธ ์ฝ๋๋ฒ ์ด์ค์ ์ต์ํ๋ค๋ฉด Rails๋ ํฅ๋ฏธ๋ก์ธ ๊ฒ์ ๋๋ค.
ํผ๋ผ๋ฏธ๋ ์ ํ๋ผ์คํฌ ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๊ธฐ ์ํด ์ฟ ํค๋ฅผ ์ฌ์ฉํ๋ ๊ฒ ๊ฐ์ต๋๋ค. ๋๋ ๋ฌธ์๋ฅผ ๊ฐ๋ตํ ์ฝ์์ผ๋ฏ๋ก ๋ด๊ฐ ํ๋ฆด ์ ์์ต๋๋ค.
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.
์ด๊ฒ์ ์ธ์
ํ์ผ ๋ด์ฉ์ด ์ ๋ ์๋ง์ด๋์ง ์๋๋ก ๋ณด์ฅํ์ง๋ง ๊ฒฝ์ ์กฐ๊ฑด์ด ๋ฐ์ํ ์ ์๋ค๋ ๊ฒ์ ์๋ฏธํ๋ ๊ฒ ๊ฐ์ต๋๋ค. ์ฅ๊ณ ๊ฒฝํ์ด ์๋ค๋ฉด cless / session @ f84abed ์ ๊ฐ์ ํ
์คํธ ์ผ์ด์ค๋ฅผ ๋ณด๋ ๊ฒ์ด ์ข์ ๊ฒ์
๋๋ค.
Stackoverflow๋ ๋ํ Django๊ฐ ์ธ์
์์ ๊ฒฝ์ ์กฐ๊ฑด์ ๊ฐ์ง ์ ์์์ ๋ํ๋ด๋ ๊ฒ ๊ฐ์ต๋๋ค. http://stackoverflow.com/search?q=django+session+race+condition
์ข์ต๋๋ค. FileSystemStore์๋ ์ธ์ ์ ์ฅ์์ ์์์ ๋ฐฉ์งํ๊ธฐ ์ํด ์ด๋ฏธ ๊ฑฐ์น ๋ฎคํ ์ค๊ฐ ์์ต๋๋ค. ์ผ๋ถ ์์ฒญ์ ๋ํด ์ผ๊ด์ฑ์ ์ ์งํ๊ธฐ ์ํด ๋ชจ๋ ์์ฒญ์ โโ๋ํด ๋ง์ ์ค๋ฒ ํค๋๋ฅผ ์ถ๊ฐํ๊ธฐ ๋๋ฌธ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ถ๊ฐ๋ก ๋ณดํธ ํ ๊ฐ์น๊ฐ ์ผ๋ง๋ ์๋์ง ์ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค. ํ์คํ ์ฌ๊ธฐ ์๋๋ฆฌ์ค๋ ์คํ ๊ฐ๋ฅํ์ง๋ง ์ผ๋ฐ์ ์ธ ์๋ฏธ์์ ๋ค๋ฃจ๊ธฐ์๋ ์๋ง๋ ๋๋ฌด ๋ณต์กํ๋ค๊ณ ์๊ฐํฉ๋๋ค. ์ง๊ธ ์ผ์ด๋๋ ์ผ์ด ์์ ํ ๊ด์ฐฎ์ ๊ฒฝ์ฐ๊ฐ ๋ง์ง๋ง ์ผ๋ถ ์์ฉ ํ๋ก๊ทธ๋จ์์๋ ๋ฌธ์ ๊ฐ ๋ ์ ์์ต๋๋ค. ์ด์จ๋ ์ฃผ์ด์ง ์ธ์ ์ ๋ํด ๊ธฐ๋ด ์์ฒญ์ด ํ๋๋ง์์ ๊ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.
์ค์ ๋ก ๋ชจ๋ ์น ๋ฆฌ์์ค์ ์กด์ฌํ๋ ๋ฌธ์ ์ ๋๋ค. 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์ ๋ ๊ฐ์ง ๊ธฐ๋ฅ์ ์ถ๊ฐํ๋ ๊ฒ์ ์ด๋ป์ต๋๊น?
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์ ๋ต์ฅ์ ๋์ณ์ ๋ฏธ์ํฉ๋๋ค.
์ฅ๊ธฐ ์คํ ์์ฒญ์ ๊ฒฝ์ ์กฐ๊ฑด์ ํธ๋ฆฌ๊ฑฐํ๊ธฐ์ํ ์๊ตฌ ์ฌํญ์ด ์๋๋ผ๋ ์ ์ ๊ธฐ์ตํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค. ๋ด ํ
์คํธ ์ผ์ด์ค์ 500ms ์ ์ ์ ๊ฒฝ์ ์กฐ๊ฑด์ด ํธ๋ฆฌ๊ฑฐ๋์๋์ง ํ์ธํ๊ธฐ์ํ ๊ฒ์
๋๋ค. ํ์ค ์ธ๊ณ์์ ์ด๋ฌํ ๊ฒฝํฉ ์กฐ๊ฑด์ "์งง์"์์ฒญ์ ๋ํด์๋ ๋ฐ์ํ๋ฉฐ, ๊ทธ ๋น๋๋ ์ ์ต๋๋ค. ์ด๊ฒ์ด ๋ฐ๋ก ๋๋ฒ๊น
์ ์ด๋ ต๊ฒ ๋ง๋๋ ์์ธ์
๋๋ค.
๋ํ ๋ถํ๊ฐ ๋์ผ๋ฉด ์งง์ ์์ฒญ๋ ์คํํ๋ ๋ฐ ์๊ฐ์ด ๊ฑธ๋ฆด ์ ์๋ค๋ ์ ์ ์ผ๋์ ๋์ด์ผํฉ๋๋ค.
@cless ์ข์ ํฌ์ธํธ.
์ ์ ๋ ์ธํฐํ์ด์ค ๋ณ๊ฒฝ์ด ๋ง์์ ๋ญ๋๋ค.
์ ๊ธ ๋ง๋ฃ๋ RediStore์ ๋ํด ๋น๊ต์ ์ฝ๊ฒ ๊ตฌํํ ์ ์์ผ๋ฉฐ Redis์๋ ํค์ TTL์ ์ค์ ํ ์์๋ EXPIRE ๋ช ๋ น์ด ์์ต๋๋ค.
์ด๋ฌํ ์ข ๋ฅ์ ์ธ๋ถํ ๋ ์ ๊ธ์ ๋ง์ ์ ํ์ ์ธ์ ์ ์ฅ์์ ๋ํด ์ฌ์ ํ ์๋นํ ๋นํจ์จ์ ์ด์ง ์์๊น์? ๊ทธ๋ฆฌ๊ณ ๋ง๋ฃ๋ ๋ฌธ์ ์ ๋๋ค.
๋ฌธ์ ์ ์ผ๋ถ๋ ์ธ์ ์ด ๋ ์ค๋ ์กด์ฌํ๋๋ผ๋ ์ ์ฅ์ด ์ฑ๊ณตํ ์ ์๋ค๋ ๊ฒ์ ๋๋ค. ๊ทธ๋ ์ง ์์ ๊ฒฝ์ฐ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋ฐ ํฐ ๋์์ด๋์ง ์์๊น์?
@kisielk , ๋นํจ์จ์ ์ธ ์์ ์ ์๋ฅผ ๋ค์ด ์ค ์ ์์ต๋๊น? ๋๋ถ๋ถ์ ํค-๊ฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค์๋ ์ ๊ธ์ ์์ฑ ํ ์์๋ ์ผ์ข
์ ์์ ์ ์์
์ด ์์ต๋๋ค. SQL ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ์ผ๋ฐ์ ์ผ๋ก ํ ๊ธฐ๋ฐ ์ ๊ธ์ ์ก์ธ์ค ํ ์ ์์ต๋๋ค (์ฌ๊ธฐ์์ ์ธ๋ถ ์ฌํญ์ ์ต์ํ์ง ์๋ค๊ณ ๋งํด์ผํฉ๋๋ค).
redis์ ๊ฐ์ ํค-๊ฐ ์ ์ฅ์์ ์ ๊ธ ๋ฐฉ๋ฒ์๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ํ ์ฌ๋ฌ ๋ฒ์ ์๋ณต์ด ํ์ํฉ๋๋ค.
go๋ ํ์ผ ์ ๊ธ์ ์ก์ธ์คํ๋ ๊ต์ฐจ ํ๋ซํผ ๋ฐฉ๋ฒ์ ์ ๊ณตํ์ง ์๊ธฐ ๋๋ฌธ์ ํ์ผ ์์คํ
์ ์ฅ์์ ๋ฌธ์ ๊ฐ ์์ต๋๋ค. cgo๋ฅผ ์ฌ์ฉํ๋ฉด ๊ธฐ๋ณธ ํ๋ซํผ์ ์ง์ํ๋ ํ๋ซํผ์ ๋ง๋ค ์ ์๋ค๊ณ ์๊ฐํ์ง๋ง ์๋ง๋ ํผํ ์๋ฃจ์
์ผ ๊ฒ์
๋๋ค.
์ธ์ ๊ณ ์ ์ ๋ฐฉ์งํ๊ธฐ ์ํด ํ์ฌ ์ธ์ ์ ์ ๊ฑฐํ๊ณ ์ ์ธ์ ์ผ๋ก ๋ฐ๊พธ๋ ๊ฒ์ ๋ํด ์ด์ผ๊ธฐํ์ง ์๋ ํ ์ธ์ ์ด ๋ ์ด์ ์กด์ฌํ์ง ์์ ๋ ์ ์ฅํ๋ ๊ฒ์ด ์ค์ ๋ฌธ์ ๋ผ๊ณ ์๊ฐํ์ง ์์ง๋ง ์์งํ ์ด๊ฒ์ ์์ ํ ๋ค๋ฅธ ๋ฌธ์ ์ ๋๋ค.
@boj , ๋ฌธ์ ๋ ํ๋ก๊ทธ๋๋จธ๊ฐ ์ ์ฅ์ ์๋ํ๊ธฐ ์ ์ ์ ๊ธ์ด ์์ง ๋ง๋ฃ๋์ง ์์๋์ง ํ์ธํ ๋ฐฉ๋ฒ์ด ํ์ํ๋ค๋ ๊ฒ์ ๋๋ค. ์ ๊ธ ๋ง๋ฃ ์๊ฐ์ ์ผ๋ง์ ๋๊น?
์ด๊ฒ์ ๊ทธ๊ฒ์ ๋ํด ๊ฐ๋ฅํ ํ ๊ฐ์ง ๋ฐฉ๋ฒ์ด์ง๋ง ๋ด๊ฐ ๊ทธ๊ฒ์ ๋ง์ด ์ข์ํ๋์ง ํ์ ํ์ง ๋ชปํฉ๋๋ค. ๋น์ ์ ์๊ณ๊ฐ ๊ฐ์๊ธฐ ์์ผ๋ก ๋ฐ์ง ์๊ฑฐ๋ ๋ค๋ก ๋ฌผ๋ฌ๋์ง ์๋ ๊ฒ์ ์์กดํ๊ณ ์์ผ๋ฉฐ ์ด๊ฒ์ ์์ ํ ๊ฐ์ ์ด ์๋๋๋ค.
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 ์ ๊ฑฑ์ ๊ฑฐ๋ฆฌ๋ฅผ ์์ฝํฉ๋๋ค. X๋ ์ด๊ฒ์ํ๊ณ , Y๋ ๊ทธ๊ฒ์ํ๊ณ , Z๋ ์ด๋ค ๊ทน๋จ์ด ๊ด๋ จ๋์ง ์๋ ํ ๊ฐ๋ฅํ์ง ์์ ์ ์์ต๋๋ค. ๋๋ฌผ๊ฒ ๋ฐ์ํ ์์๋ ๊ฒฝํฉ ์กฐ๊ฑด์ ๋ฐ๋์งํ์ง ์์ง๋ง, ์ ์ด๋ ํ์ฌ์ ๊ณ ๋ฆด๋ผ / ์ธ์ ๋์์ธ์ ๋งค์ฐ ๋จ์ํ๋ฉฐ ์ต์ํ์ ๋๋ผ์ด ์ฒ ํ์ ์์๋ฅผ ๋ฐ๋ฆ ๋๋ค.
์ ์ํ๋๋ก ๊ณ ๋ฆด๋ผ / ์ธ์ ์ ์ธํฐํ์ด์ค ๋ถ๋ถ์ ๊ตฌํํ๋ ๊ฒ์ ๋งค์ฐ ๊ฐ๋จ ํ ์ ์์ง๋ง, ๋๊ฐ์ด ์ฝ๊ฒ ์ ๊ธ / ํด์ ๋ฅผ ๊ตฌํํ์ง ์๋ ํ ๋ฐฑ์๋๋ฅผ ์ฝ๊ฒ ๊ต์ฒด ํ ์์๋ ์๋๋ฆฌ์ค๋ฅผ ๋ง๋ญ๋๋ค. ํจ์จ์ ์ธ ๋ฐฉ์์ ๋๋ค. ๋น์ ์ด ์ ์ํ ๊ฒ๊ณผ ๊ด๋ จํ์ฌ ๋๋ฌด ๋ง์ what ifs๊ฐ์๋ ๊ฒ ๊ฐ์ต๋๋ค. ๊ฐ์ฅ ์ค์ํ ๊ฒ์ "ํดํน ํ๋ก๊ทธ๋๋ฐ์ ์์กดํ์ง ์๊ณ ๋ฐฑ์๋๊ฐ ์ด๊ฒ์ ๊ตฌํํ ์ ์์ต๋๊น?", "FileSystemStore์์ FooBarStore๋ก ์ค์ํ๋ ค๊ณ ์๋ํ์ง๋ง ๊ทธ๋ ์ง ์์ต๋๋ค." Lock / Release๋ฅผ ๊ตฌํํ๋ ๊ฒ์ผ๋ก ๋ณด์ด๋ฉฐ ๋ด ํ๋ก๊ทธ๋จ์ด ์์๋๋ก ์๋ํ์ง ์์ต๋๋ค. "
์ฌ๊ธฐ์ ์ธ์ ๋ณ ์ ๊ธ์ ๋์์ค์ ๋ํ ์ข์ ๊ธฐ์ฌ๊ฐ ์์ต๋๋ค.
http://thwartedefforts.org/2006/11/11/race-conditions-with-ajax-and-php-sessions/
์ฐ๋ฆฌ๊ฐ ์ด๋ฏธ ์ฌ๊ธฐ์์ ๊ฒฐ๋ก ์ ๋ด๋ ธ ๋ฏ์ด ๋ฌด์ธ๊ฐ ์๋ชป๋์์ ๋ ์ ๊ธ ์๊ฐ ์ด๊ณผ๋ ์ด๋ฌํ ์ข ๋ฅ์ ์ฒด๊ณ๋ฅผ ๊ตฌํํ๋ ์ฃผ์ ๋ฌธ์ ์ค ํ๋์ ๋๋ค. ์ด๊ฒ์ ๋ ๋ง์ ์๊ฐ์ด ํ์ํ๊ณ ๋งค์ฐ ๋ฐฑ์๋ ์์กด์ ์ ๋๋ค.
Lock / Release ๊ตฌํ์ ๊ดํด์๋ ๋ณ๋์ ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉํ์ฌ ์ธ์ ๋ณ ์ ๊ธ ๊ตฌํ์ ์ ํ์ ์ผ๋ก ๋ง๋ค ์ ์์ต๋๋ค. ๊ทธ๋ฐ ๋ค์ ๋ฐฑ์๋๊ฐ ํด๋น ์ธํฐํ์ด์ค์ ๋ํด ์ด์ค ์ ๋ ์ ์์ผ๋ฉฐ์ด๋ฅผ ๊ตฌํํ์ง ์๋ ๊ฒฝ์ฐ ๋ฉ๋ชจ๋ฆฌ ๋ด ์ ๊ธ์ ์ฌ์ฉํ์ฌ ๊ธฐ๋ณธ ๊ตฌํ์ ์ ๊ณต ํ ์ ์์ต๋๋ค.
๋ฌผ๋ก ๋ ๋ค๋ฅธ ๋ฌธ์ ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ฌ์ฉ์๊ฐ ์ ๊ธ ๋ฐ ํด์ ๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด ์ฝ๋๋ฅผ ์ ๋ฐ์ดํธํด์ผํ๋ค๋ ๊ฒ์ ๋๋ค.ํ์ง๋ง ๊ทธ๋ ์ง ์์ผ๋ฉด ์ง๊ธ๊ณผ ๋์ผํ ๋์์ ํ ๊ฒ์ ๋๋ค.
"์ธ ๋ฉ๋ชจ๋ฆฌ ์ ๊ธ์ ์ฌ์ฉํ์ฌ ๊ธฐ๋ณธ ๊ตฌํ์ ์ ๊ณต ํ ์ ์์ต๋๋ค."
์์ฒญ์ด๋ก๋ ๋ฐธ๋ฐ์ฑ๋๋ ๋ค์ค ์๋ฒ ํ๊ฒฝ์์๋ ์๋ฏธ๊ฐ ์์ต๋๋ค.
์ธ์ ์ ์ฌ์ฉํ๋ ๊ธฐ์กด ์ฝ๋์ ๋์์ ๋ณ๊ฒฝํ์ง ์๊ณ ๋ ์์ ๋กญ๊ฒ ์ฌ๋ฐ๋ฅด๊ฒ ๊ตฌํํ ์ ์๊ธฐ ๋๋ฌธ์ ์ ๊ธ์ ์์ ํ ๋ค๋ฅธ ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํ๋ค๋ ์์ด๋์ด๊ฐ ๋ง์์ ๋ญ๋๋ค.
@boj๊ฐ ์ธ๊ธํ๋ฏ์ด ์๋ฏธ์๋ ๋ฐฉ์์ผ๋ก ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ ์ฅ์์ ๋ฉ๋ชจ๋ฆฌ ์ ๊ธ์ ์ ๊ณต ํ ์๋ ์์ต๋๋ค. ์ ๊ธ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ ๋ถ๋ด์ ์์ ๊ฐ๋ฐ์์๊ฒ์์ ๊ฒ์ ๋๋ค. ์ ๊ธ ์ธํฐํ์ด์ค๊ฐ ๋๋ฝ ๋ ๊ฒฝ์ฐ ์ธ์ ์ด์ด๋ฅผ ์ฌ์ฉํ๋ ค๊ณ ํ ๋ ์ค๋ฅ๋ฅผ ๋ฐํ ํ ์ ์์ต๋๋ค. ๊ทธ๊ฒ์ ์ ๋ง๋ก ๋ฌธ์ ๊ฐ๋์ง ์์ ๊ฒ์ ๋๋ค. ๋ง์ฝ ๊ธฐ๋ณธ ์คํ ์ด๊ฐ ์ ๊ธ์ ์ ๊ณตํ๋ค๋ฉด ๋ค๋ฅธ ๊ฐ๋ฐ์๋ค์ด์ด๋ฅผ ๋ฐ๋ฅผ ๊ฒ์ด๊ณ ์ฌ์ฉ์๋ ์ต์ํ์ ๋ถํธ ํจ์ ๋๋ผ๊ฒ ๋ ๊ฒ์ ๋๋ค.
๋ฉ๋ชจ๋ฆฌ ์ ๊ธ์ ์ผ๋ถ ์์ ์์ ์ฌ์ ํ ์๋ฏธ๊ฐ ์์ผ๋ฉฐ FilesystemStore
์ด ์ข์ ํ๋ณด๋ผ๊ณ ์๊ฐํฉ๋๋ค. ํ์ค์ ์ผ๋ก๋ ๋ถํ ๋ถ์ฐ ๋ ์ํฉ์์ ํ์ผ ์์คํ
์ ์ฅ์๋ฅผ ์ฌ์ฉํ์ง ์์ ๊ฒ์
๋๋ค (์ด๋ก ์ ์ผ๋ก๋ ๋คํธ์ํฌ ํ์ผ ์์คํ
์์ ๊ฐ๋ฅํจ). ํ์ผ ์์คํ
์ ๊ธ์ ์ ํธ๋๋ ๊ฒ์ฒ๋ผ ๋ณด์ด์ง๋ง ์ด๋ ์ค์ ํฌ๋ก์ค ํ๋ซํผ์ ๊ตฌํํ๊ธฐ๊ฐ ์ด๋ ค์ฐ๋ฉฐ NFS์ ํจ๊ป ์๋ํ๋ค๋ ๋ณด์ฅ๋ ์์ต๋๋ค.
@boj : ๋์ํ์ง๋ง @cless๊ฐ ์ง์ ํ๋ฏ์ด ๊ทํ๊ฐ ๋ณด์ ํ ์์ ์ ์ข ๋ฅ์ ๋ฐ๋ผ
์ ๋ @cless์ ์ ์ ์ผ๋ก ๋์ํ๋ฉฐ ์ธ์ ์ ๊ธ ๋ฐ ์ฑ์ํ ํ๋ซํผ (์ : PHP)์ด ์ธ์ ์ ์ฅ์์์์ด๋ฅผ ๊ตฌํํ๋ ๊ฒ์ ์ค์์ฑ์ ๊ฐ์กฐํ๊ณ ์ถ์ต๋๋ค. ํ์ผ์์๋ 'flock'syscall์ ์ฌ์ฉํ๊ณ memcache์์๋ 'add'์์ ์ ๋ฐํ ๊ฐ๊ณผ '.lock'์ ๋ฏธ์ฌ ๋ฐ ๋ง๋ฃ ์งํฉ์ด์๋ ์ถ๊ฐ ํค๋ฅผ ์ฌ์ฉํฉ๋๋ค. ๋๋ ๋ํ ์๋ก์ด ์ธํฐํ์ด์ค๋ฅผ ๊ฐ๊ธฐ์ํ @kisielk ์ ์ ๊ทผ ๋ฐฉ์์ ๋์ํฉ๋๋ค ( 'Lock'๋ฐ 'Release'๊ธฐ๋ฅ์ด์๋ ๊ฒ์ด ํฉ๋ฆฌ์ ์ ๋๋ค.์ด ๊ธฐ๋ฅ์ ์ฌ์ฉํด ์ฃผ์๊ฒ ์ต๋๊น? Go๋ ๊ณ ์ฑ๋ฅ๊ณผ ์์ ์ฑ์ ์ํด ๊ฐ ์ธ์ด ์ฌ์ผํฉ๋๋ค. ์๋ฅผ ๋ค์ด ์ผ๋ถ ๊ตฌํ (FileSystem, Redis ๋ฐ Memcache)์ ๊ธฐ๊บผ์ด ์ ๊ณตํฉ๋๋ค. ๋ช ๊ฐ์ง ์๋ก์ด ๊ตฌ์ฑ ์ต์ ์ด ํ์ํฉ๋๋ค.
์ด ๋ฌธ์ ๋ ์ต๊ทผ ์ ๋ฐ์ดํธ๋ฅผ ๋ณด์ง ๋ชปํ๊ธฐ ๋๋ฌธ์ ์๋์ผ๋ก ์ค๋๋ ๊ฒ์ผ๋ก ํ์๋์์ต๋๋ค. ๋ฉฐ์น ํ ์๋์ผ๋ก ๋ซํ๋๋ค.