์น ์ ํ๋ฆฌ์ผ์ด์ ์์ ๋ฆฌ์์ค ๋๊ธฐํ ๋ฐ ๋์ ์ ๊ทผ ๊ด๋ฆฌ๋ฅผ ์ํ Web Locks API์ ์ฌ์ฉ๋ฒ, ์ฅ์ , ํ๊ณ ๋ฐ ์ค์ ์์ ๋ฅผ ๋ค๋ฃจ๋ ์ข ํฉ ๊ฐ์ด๋์ ๋๋ค.
Web Locks API: ๋ฆฌ์์ค ๋๊ธฐํ์ ๋์ ์ ๊ทผ ์ ์ด
ํ๋ ์น ๊ฐ๋ฐ ํ๊ฒฝ์์ ๊ฐ๋ ฅํ๊ณ ๋ฐ์์ฑ์ด ๋ฐ์ด๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๋ ๊ฒ์ ์ข ์ข ๊ณต์ ๋ฆฌ์์ค๋ฅผ ๊ด๋ฆฌํ๊ณ ๋์ ์ ๊ทผ์ ์ฒ๋ฆฌํ๋ ์์ ์ ํฌํจํฉ๋๋ค. ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฌ๋ฌ ๋ถ๋ถ์ด๋ ์ฌ๋ฌ ๋ธ๋ผ์ฐ์ ํญ ๋๋ ์ฐฝ์ด ๋์์ ๋์ผํ ๋ฐ์ดํฐ์ ์ ๊ทผํ๊ณ ์์ ํ๋ ค๊ณ ํ ๋, ๊ฒฝ์ ์ํ(race conditions)์ ๋ฐ์ดํฐ ์์์ด ๋ฐ์ํ ์ ์์ต๋๋ค. Web Locks API๋ ์ด๋ฌํ ๋ฆฌ์์ค์ ๋ํ ์ ๊ทผ์ ๋๊ธฐํํ๋ ๋ฉ์ปค๋์ฆ์ ์ ๊ณตํ์ฌ ๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ์ ๋ณด์ฅํ๊ณ ์๊ธฐ์น ์์ ๋์์ ๋ฐฉ์งํฉ๋๋ค.
๋ฆฌ์์ค ๋๊ธฐํ์ ํ์์ฑ ์ดํดํ๊ธฐ
์ฌ์ฉ์๊ฐ ์น ์ ํ๋ฆฌ์ผ์ด์ ์์ ๋ฌธ์๋ฅผ ํธ์งํ๋ ์๋๋ฆฌ์ค๋ฅผ ์๊ฐํด ๋ณด์ญ์์ค. ๋์ผํ ๋ฌธ์๊ฐ ์ฌ๋ฌ ๋ธ๋ผ์ฐ์ ํญ์ ์ด๋ ค ์๊ฑฐ๋, ์ ํ๋ฆฌ์ผ์ด์ ์ด ์ฃผ๊ธฐ์ ์ผ๋ก ๋ฌธ์๋ฅผ ์ ์ฅํ๋ ๋ฐฑ๊ทธ๋ผ์ด๋ ํ๋ก์ธ์ค๋ฅผ ๊ฐ์ง ์ ์์ต๋๋ค. ์ ์ ํ ๋๊ธฐํ ์์ด๋ ํ ํญ์์ ๋ณ๊ฒฝํ ๋ด์ฉ์ด ๋ค๋ฅธ ํญ์์ ๋ณ๊ฒฝํ ๋ด์ฉ์ผ๋ก ๋ฎ์ด์์์ ธ ๋ฐ์ดํฐ ์์ค๊ณผ ์ค๋ง์ค๋ฌ์ด ์ฌ์ฉ์ ๊ฒฝํ์ ์ด๋ํ ์ ์์ต๋๋ค. ๋ง์ฐฌ๊ฐ์ง๋ก, ์ ์์๊ฑฐ๋ ์ ํ๋ฆฌ์ผ์ด์ ์์๋ ์ฌ๋ฌ ์ฌ์ฉ์๊ฐ ๋์์ ์ฌ๊ณ ์ ๋ง์ง๋ง ํ๋ชฉ์ ๊ตฌ๋งคํ๋ ค๊ณ ์๋ํ ์ ์์ต๋๋ค. ์ด๊ณผ ํ๋งค๋ฅผ ๋ฐฉ์งํ๋ ๋ฉ์ปค๋์ฆ์ด ์๋ค๋ฉด, ์ดํํ ์ ์๋ ์ฃผ๋ฌธ์ด ๋ฐ์ํ์ฌ ๊ณ ๊ฐ ๋ถ๋ง์ผ๋ก ์ด์ด์ง ์ ์์ต๋๋ค.
์๋ฒ ์ธก ๋ฝ(locking) ๋ฉ์ปค๋์ฆ์๋ง ์์กดํ๋ ๊ฒ๊ณผ ๊ฐ์ ์ ํต์ ์ธ ๋์์ฑ ๊ด๋ฆฌ ์ ๊ทผ ๋ฐฉ์์ ์๋นํ ์ง์ฐ ์๊ฐ๊ณผ ๋ณต์ก์ฑ์ ์ด๋ํ ์ ์์ต๋๋ค. Web Locks API๋ ๊ฐ๋ฐ์๊ฐ ๋ธ๋ผ์ฐ์ ๋ด์์ ์ง์ ๋ฆฌ์์ค์ ๋ํ ์ ๊ทผ์ ์กฐ์ ํ ์ ์๋๋ก ํ๋ ํด๋ผ์ด์ธํธ ์ธก ์๋ฃจ์ ์ ์ ๊ณตํ์ฌ ์ฑ๋ฅ์ ๊ฐ์ ํ๊ณ ์๋ฒ์ ๋ถํ๋ฅผ ์ค์ ๋๋ค.
Web Locks API ์๊ฐ
Web Locks API๋ ์น ์ ํ๋ฆฌ์ผ์ด์ ๋ด์์ ์ด๋ฆ์ด ์ง์ ๋ ๋ฆฌ์์ค์ ๋ํ ๋ฝ(lock)์ ํ๋ํ๊ณ ํด์ ํ ์ ์๊ฒ ํด์ฃผ๋ JavaScript API์ ๋๋ค. ์ด ๋ฝ์ ๋ฐฐํ์ ์ด๋ฏ๋ก(exclusive), ํน์ ๋ฆฌ์์ค์ ๋ํ ๋ฝ์ ํ ๋ฒ์ ํ๋์ ์ฝ๋ ์กฐ๊ฐ๋ง ๋ณด์ ํ ์ ์์ต๋๋ค. ์ด๋ฌํ ๋ฐฐํ์ฑ์ ๊ณต์ ๋ฐ์ดํฐ๋ฅผ ์ ๊ทผํ๊ณ ์์ ํ๋ ์ฝ๋์ ์ค์ ์น์ (critical section)์ด ํต์ ๋๊ณ ์์ธก ๊ฐ๋ฅํ ๋ฐฉ์์ผ๋ก ์คํ๋๋๋ก ๋ณด์ฅํฉ๋๋ค.
์ด API๋ ๋ฝ์ด ํ๋๋๊ฑฐ๋ ํด์ ๋ ๋๋ฅผ ์๋ฆฌ๊ธฐ ์ํด Promise๋ฅผ ์ฌ์ฉํ์ฌ ๋น๋๊ธฐ์ ์ผ๋ก ์ค๊ณ๋์์ต๋๋ค. ์ด๋ฌํ ๋น์ฐจ๋จ(non-blocking) ํน์ฑ์ ๋ฝ์ ๊ธฐ๋ค๋ฆฌ๋ ๋์ UI๊ฐ ๋ฉ์ถ๋ ๊ฒ์ ๋ฐฉ์งํ์ฌ ๋ฐ์์ฑ ์๋ ์ฌ์ฉ์ ๊ฒฝํ์ ๋ณด์ฅํฉ๋๋ค.
์ฃผ์ ๊ฐ๋ ๋ฐ ์ฉ์ด
- ๋ฝ ์ด๋ฆ(Lock Name): ๋ฝ์ผ๋ก ๋ณดํธ๋๋ ๋ฆฌ์์ค๋ฅผ ์๋ณํ๋ ๋ฌธ์์ด์ ๋๋ค. ์ด ์ด๋ฆ์ ๋์ผํ ๋ฆฌ์์ค์ ๋ํ ๋ฝ์ ํ๋ํ๊ณ ํด์ ํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค. ๋ฝ ์ด๋ฆ์ ๋์๋ฌธ์๋ฅผ ๊ตฌ๋ถํฉ๋๋ค.
- ๋ฝ ๋ชจ๋(Lock Mode): ์์ฒญ๋๋ ๋ฝ์ ์ ํ์ ์ง์ ํฉ๋๋ค. API๋ ๋ ๊ฐ์ง ๋ชจ๋๋ฅผ ์ง์ํฉ๋๋ค:
- `exclusive` (๊ธฐ๋ณธ๊ฐ): ํ ๋ฒ์ ํ๋์ ๋ฝ ๋ณด์ ์๋ง ํ์ฉ๋ฉ๋๋ค.
- `shared`: ๋ค๋ฅธ ๋ณด์ ์๊ฐ ๋์ผํ ๋ฆฌ์์ค์ ๋ํ ๋ฐฐํ์ ๋ฝ์ ๊ฐ์ง๊ณ ์์ง ์์ ๊ฒฝ์ฐ, ๋์์ ์ฌ๋ฌ ๋ฝ ๋ณด์ ์๋ฅผ ํ์ฉํฉ๋๋ค.
- ๋ฝ ์์ฒญ(Lock Request): ๋ฝ์ ํ๋ํ๋ ค๋ ๋น๋๊ธฐ ์์ ์ ๋๋ค. ์์ฒญ์ ๋ฝ์ด ์ฑ๊ณต์ ์ผ๋ก ํ๋๋๋ฉด ์ดํ(resolve)๋๊ณ , ๋ฝ์ ํ๋ํ ์ ์๋ ๊ฒฝ์ฐ(์: ๋ค๋ฅธ ์ฝ๋ ์กฐ๊ฐ์ด ์ด๋ฏธ ๋ฐฐํ์ ๋ฝ์ ๋ณด์ ํ๊ณ ์๋ ๊ฒฝ์ฐ) ๊ฑฐ๋ถ(reject)๋ฉ๋๋ค.
- ๋ฝ ํด์ (Lock Release): ๋ฝ์ ํด์ ํ์ฌ ๋ค๋ฅธ ์ฝ๋๊ฐ ํ๋ํ ์ ์๋๋ก ๋ง๋๋ ์์ ์ ๋๋ค.
Web Locks API ์ฌ์ฉํ๊ธฐ: ์ค์ ์์
์น ์ ํ๋ฆฌ์ผ์ด์ ์์ ๋ฆฌ์์ค ์ ๊ทผ์ ๋๊ธฐํํ๊ธฐ ์ํด Web Locks API๋ฅผ ์ด๋ป๊ฒ ์ฌ์ฉํ ์ ์๋์ง ๋ช ๊ฐ์ง ์ค์ ์์ ๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
์์ 1: ๋์ ๋ฌธ์ ํธ์ง ๋ฐฉ์ง
์ฌ๋ฌ ์ฌ์ฉ์๊ฐ ๋์์ ๊ฐ์ ๋ฌธ์๋ฅผ ํธ์งํ ์ ์๋ ํ์ ๋ฌธ์ ํธ์ง ์ ํ๋ฆฌ์ผ์ด์ ์ ์์ํด ๋ณด์ธ์. ์ถฉ๋์ ๋ฐฉ์งํ๊ธฐ ์ํด Web Locks API๋ฅผ ์ฌ์ฉํ์ฌ ํ ๋ฒ์ ํ ๋ช ์ ์ฌ์ฉ์๋ง ๋ฌธ์๋ฅผ ์์ ํ ์ ์๋๋ก ํ ์ ์์ต๋๋ค.
async function saveDocument(documentId, content) {
try {
await navigator.locks.request(documentId, async () => {
// ์ค์ ์น์
: ๋ฌธ์ ๋ด์ฉ์ ์๋ฒ์ ์ ์ฅ
console.log(`๋ฌธ์ ${documentId}์ ๋ํ ๋ฝ ํ๋. ์ ์ฅ ์ค...`);
await saveToServer(documentId, content);
console.log(`๋ฌธ์ ${documentId} ์ ์ฅ ์๋ฃ.`);
});
} catch (error) {
console.error(`๋ฌธ์ ${documentId} ์ ์ฅ ์คํจ:`, error);
}
}
async function saveToServer(documentId, content) {
// ์๋ฒ์ ์ ์ฅํ๋ ๊ฒ์ ์๋ฎฌ๋ ์ด์
(์ค์ API ํธ์ถ๋ก ๋์ฒด)
return new Promise(resolve => setTimeout(resolve, 1000));
}
์ด ์์ ์์ `saveDocument` ํจ์๋ ๋ฌธ์์ ID๋ฅผ ๋ฝ ์ด๋ฆ์ผ๋ก ์ฌ์ฉํ์ฌ ๋ฌธ์์ ๋ํ ๋ฝ์ ํ๋ํ๋ ค๊ณ ์๋ํฉ๋๋ค. `navigator.locks.request` ๋ฉ์๋๋ ๋ฝ ์ด๋ฆ๊ณผ ์ฝ๋ฐฑ ํจ์์ ๋ ๊ฐ์ง ์ธ์๋ฅผ ๋ฐ์ต๋๋ค. ์ฝ๋ฐฑ ํจ์๋ ๋ฝ์ด ์ฑ๊ณต์ ์ผ๋ก ํ๋๋ ํ์๋ง ์คํ๋ฉ๋๋ค. ์ฝ๋ฐฑ ๋ด๋ถ์์ ๋ฌธ์ ๋ด์ฉ์ด ์๋ฒ์ ์ ์ฅ๋ฉ๋๋ค. ์ฝ๋ฐฑ ํจ์๊ฐ ์๋ฃ๋๋ฉด ๋ฝ์ ์๋์ผ๋ก ํด์ ๋ฉ๋๋ค. ๋ง์ฝ ๋์ผํ `documentId`๋ก ์ด ํจ์์ ๋ค๋ฅธ ์ธ์คํด์ค๊ฐ ์คํ์ ์๋ํ๋ฉด, ๋ฝ์ด ํด์ ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฝ๋๋ค. ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ฉด ํฌ์ฐฉ๋์ด ๊ธฐ๋ก๋ฉ๋๋ค.
์์ 2: ๋ก์ปฌ ์คํ ๋ฆฌ์ง ์ ๊ทผ ์ ์ด
๋ก์ปฌ ์คํ ๋ฆฌ์ง๋ ๋ธ๋ผ์ฐ์ ์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ ์ผ๋ฐ์ ์ธ ๋ฉ์ปค๋์ฆ์ ๋๋ค. ๊ทธ๋ฌ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฌ๋ฌ ๋ถ๋ถ์ด ๋์์ ๋ก์ปฌ ์คํ ๋ฆฌ์ง์ ์ ๊ทผํ๊ณ ์์ ํ๋ ค๊ณ ํ๋ฉด ๋ฐ์ดํฐ ์์์ด ๋ฐ์ํ ์ ์์ต๋๋ค. Web Locks API๋ฅผ ์ฌ์ฉํ์ฌ ๋ก์ปฌ ์คํ ๋ฆฌ์ง์ ๋ํ ์ ๊ทผ์ ๋๊ธฐํํ์ฌ ๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ์ ๋ณด์ฅํ ์ ์์ต๋๋ค.
async function updateLocalStorage(key, value) {
try {
await navigator.locks.request('localStorage', async () => {
// ์ค์ ์น์
: ๋ก์ปฌ ์คํ ๋ฆฌ์ง ์
๋ฐ์ดํธ
console.log(`localStorage์ ๋ํ ๋ฝ ํ๋. ํค ${key} ์
๋ฐ์ดํธ ์ค...`);
localStorage.setItem(key, value);
console.log(`localStorage์์ ํค ${key} ์
๋ฐ์ดํธ ์๋ฃ.`);
});
} catch (error) {
console.error(`localStorage ์
๋ฐ์ดํธ ์คํจ:`, error);
}
}
์ด ์์ ์์ `updateLocalStorage` ํจ์๋ 'localStorage' ๋ฆฌ์์ค์ ๋ํ ๋ฝ์ ํ๋ํ๋ ค๊ณ ์๋ํฉ๋๋ค. ๊ทธ๋ฐ ๋ค์ ์ฝ๋ฐฑ ํจ์๋ ๋ก์ปฌ ์คํ ๋ฆฌ์ง์์ ์ง์ ๋ ํค๋ฅผ ์ ๋ฐ์ดํธํฉ๋๋ค. ์ด ๋ฝ์ ํ ๋ฒ์ ํ๋์ ์ฝ๋ ์กฐ๊ฐ๋ง ๋ก์ปฌ ์คํ ๋ฆฌ์ง์ ์ ๊ทผํ ์ ์๋๋ก ๋ณด์ฅํ์ฌ ๊ฒฝ์ ์ํ๋ฅผ ๋ฐฉ์งํฉ๋๋ค.
์์ 3: ์น ์์ปค์์ ๊ณต์ ๋ฆฌ์์ค ๊ด๋ฆฌ
์น ์์ปค๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฉ์ธ ์ค๋ ๋๋ฅผ ์ฐจ๋จํ์ง ์๊ณ ๋ฐฑ๊ทธ๋ผ์ด๋์์ JavaScript ์ฝ๋๋ฅผ ์คํํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ์น ์์ปค๊ฐ ๋ฉ์ธ ์ค๋ ๋๋ ๋ค๋ฅธ ์น ์์ปค์ ๊ณต์ ๋ฆฌ์์ค์ ์ ๊ทผํด์ผ ํ๋ ๊ฒฝ์ฐ ๋๊ธฐํ๋ ํ์์ ์ ๋๋ค. Web Locks API๋ ์ด๋ฌํ ๋ฆฌ์์ค์ ๋ํ ์ ๊ทผ์ ์กฐ์ ํ๋ ๋ฐ ์ฌ์ฉ๋ ์ ์์ต๋๋ค.
๋จผ์ , ๋ฉ์ธ ์ค๋ ๋์์:
async function mainThreadFunction() {
try {
await navigator.locks.request('sharedResource', async () => {
console.log('๋ฉ์ธ ์ค๋ ๋๊ฐ sharedResource์ ๋ํ ๋ฝ์ ํ๋ํ์ต๋๋ค');
// ๊ณต์ ๋ฆฌ์์ค ์ ๊ทผ ๋ฐ ์์
await new Promise(resolve => setTimeout(resolve, 2000)); // ์์
์๋ฎฌ๋ ์ด์
console.log('๋ฉ์ธ ์ค๋ ๋๊ฐ sharedResource์ ๋ํ ๋ฝ์ ํด์ ํฉ๋๋ค');
});
} catch (error) {
console.error('๋ฉ์ธ ์ค๋ ๋๊ฐ ๋ฝ์ ํ๋ํ๋ ๋ฐ ์คํจํ์ต๋๋ค:', error);
}
}
mainThreadFunction();
๋ค์์ผ๋ก, ์น ์์ปค์์:
self.addEventListener('message', async (event) => {
if (event.data.type === 'accessSharedResource') {
try {
await navigator.locks.request('sharedResource', async () => {
console.log('์น ์์ปค๊ฐ sharedResource์ ๋ํ ๋ฝ์ ํ๋ํ์ต๋๋ค');
// ๊ณต์ ๋ฆฌ์์ค ์ ๊ทผ ๋ฐ ์์
await new Promise(resolve => setTimeout(resolve, 3000)); // ์์
์๋ฎฌ๋ ์ด์
console.log('์น ์์ปค๊ฐ sharedResource์ ๋ํ ๋ฝ์ ํด์ ํฉ๋๋ค');
self.postMessage({ type: 'sharedResourceAccessed', success: true });
});
} catch (error) {
console.error('์น ์์ปค๊ฐ ๋ฝ์ ํ๋ํ๋ ๋ฐ ์คํจํ์ต๋๋ค:', error);
self.postMessage({ type: 'sharedResourceAccessed', success: false, error: error.message });
}
}
});
์ด ์์ ์์ ๋ฉ์ธ ์ค๋ ๋์ ์น ์์ปค๋ ๋ชจ๋ `sharedResource`์ ๋ํ ๋ฝ์ ํ๋ํ๋ ค๊ณ ์๋ํฉ๋๋ค. `navigator.locks` ๊ฐ์ฒด๋ ์น ์์ปค์์๋ ์ฌ์ฉํ ์ ์์ผ๋ฏ๋ก ๋ฉ์ธ ์ค๋ ๋์ ๋์ผํ ๋ฝ ๋ฉ์ปค๋์ฆ์ ์ฐธ์ฌํ ์ ์์ต๋๋ค. ๋ฉ์ธ ์ค๋ ๋์ ์์ปค ๊ฐ์ ํต์ ์๋ ๋ฉ์์ง๊ฐ ์ฌ์ฉ๋์ด ๋ฝ ํ๋ ์๋๋ฅผ ํธ๋ฆฌ๊ฑฐํฉ๋๋ค.
๋ฝ ๋ชจ๋: ๋ฐฐํ์ (Exclusive) vs. ๊ณต์ (Shared)
Web Locks API๋ `exclusive`์ `shared` ๋ ๊ฐ์ง ๋ฝ ๋ชจ๋๋ฅผ ์ง์ํฉ๋๋ค. ๋ฝ ๋ชจ๋์ ์ ํ์ ์ ํ๋ฆฌ์ผ์ด์ ์ ํน์ ์๊ตฌ ์ฌํญ์ ๋ฐ๋ผ ๋ฌ๋ผ์ง๋๋ค.
๋ฐฐํ์ ๋ฝ (Exclusive Locks)
๋ฐฐํ์ ๋ฝ์ ๋ฆฌ์์ค์ ๋ํ ๋ ์ ์ ์ธ ์ ๊ทผ ๊ถํ์ ๋ถ์ฌํฉ๋๋ค. ํน์ ๋ฆฌ์์ค์ ๋ํ ๋ฐฐํ์ ๋ฝ์ ํ ๋ฒ์ ํ๋์ ์ฝ๋ ์กฐ๊ฐ๋ง ๋ณด์ ํ ์ ์์ต๋๋ค. ์ด ๋ชจ๋๋ ํ ๋ฒ์ ํ๋์ ํ๋ก์ธ์ค๋ง ๋ฆฌ์์ค๋ฅผ ์์ ํ ์ ์์ด์ผ ํ๋ ์๋๋ฆฌ์ค์ ์ ํฉํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ํ์ผ์ ๋ฐ์ดํฐ๋ฅผ ์ฐ๊ฑฐ๋, ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ ์ฝ๋๋ฅผ ์ ๋ฐ์ดํธํ๊ฑฐ๋, UI ์ปดํฌ๋ํธ์ ์ํ๋ฅผ ์์ ํ๋ ๊ฒฝ์ฐ์ ๋๋ค.
์์ ๋ชจ๋ ์์ ๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ฐฐํ์ ๋ฝ์ ์ฌ์ฉํ์ต๋๋ค. `exclusive`๊ฐ ๊ธฐ๋ณธ๊ฐ์ด๋ฏ๋ก ๋ชจ๋๋ฅผ ์ง์ ํ ํ์๊ฐ ์์ต๋๋ค.
๊ณต์ ๋ฝ (Shared Locks)
๊ณต์ ๋ฝ์ ๋ค๋ฅธ ์ฝ๋๊ฐ ๋์ผํ ๋ฆฌ์์ค์ ๋ํ ๋ฐฐํ์ ๋ฝ์ ๋ณด์ ํ๊ณ ์์ง ์์ ํ, ์ฌ๋ฌ ์ฝ๋ ์กฐ๊ฐ์ด ๋์์ ๋ฆฌ์์ค์ ๋ํ ๋ฝ์ ๋ณด์ ํ ์ ์๋๋ก ํ์ฉํฉ๋๋ค. ์ด ๋ชจ๋๋ ์ฌ๋ฌ ํ๋ก์ธ์ค๊ฐ ๋์์ ๋ฆฌ์์ค๋ฅผ ์ฝ์ด์ผ ํ์ง๋ง ์์ ํ ํ์๋ ์๋ ์๋๋ฆฌ์ค์ ์ ํฉํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ํ์ผ์์ ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ฑฐ๋, ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ฟผ๋ฆฌํ๊ฑฐ๋, UI ์ปดํฌ๋ํธ๋ฅผ ๋ ๋๋งํ๋ ๊ฒฝ์ฐ์ ๋๋ค.
๊ณต์ ๋ฝ์ ์์ฒญํ๋ ค๋ฉด `navigator.locks.request` ๋ฉ์๋์์ `mode` ์ต์ ์ ์ง์ ํด์ผ ํฉ๋๋ค.
async function readData(resourceId) {
try {
await navigator.locks.request(resourceId, { mode: 'shared' }, async () => {
// ์ค์ ์น์
: ๋ฆฌ์์ค์์ ๋ฐ์ดํฐ ์ฝ๊ธฐ
console.log(`๋ฆฌ์์ค ${resourceId}์ ๋ํ ๊ณต์ ๋ฝ ํ๋. ์ฝ๋ ์ค...`);
const data = await readFromResource(resourceId);
console.log(`๋ฆฌ์์ค ${resourceId}์์ ์ฝ์ ๋ฐ์ดํฐ:`, data);
return data;
});
} catch (error) {
console.error(`๋ฆฌ์์ค ${resourceId}์์ ๋ฐ์ดํฐ๋ฅผ ์ฝ๋ ๋ฐ ์คํจํ์ต๋๋ค:`, error);
}
}
async function readFromResource(resourceId) {
// ๋ฆฌ์์ค์์ ์ฝ๋ ๊ฒ์ ์๋ฎฌ๋ ์ด์
(์ค์ API ํธ์ถ๋ก ๋์ฒด)
return new Promise(resolve => setTimeout(() => resolve({ value: 'Some data' }), 500));
}
์ด ์์ ์์ `readData` ํจ์๋ ์ง์ ๋ ๋ฆฌ์์ค์ ๋ํ ๊ณต์ ๋ฝ์ ์์ฒญํฉ๋๋ค. ์ด ํจ์์ ์ฌ๋ฌ ์ธ์คํด์ค๋ ๋ค๋ฅธ ์ฝ๋๊ฐ ๋์ผํ ๋ฆฌ์์ค์ ๋ํ ๋ฐฐํ์ ๋ฝ์ ๋ณด์ ํ์ง ์๋ ํ ๋์์ ์คํ๋ ์ ์์ต๋๋ค.
๊ธ๋ก๋ฒ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํ ๊ณ ๋ ค์ฌํญ
๊ธ๋ก๋ฒ ์ฌ์ฉ์๋ฅผ ๋์์ผ๋ก ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฐ๋ฐํ ๋๋ ๋ค์ํ ํ๊ฒฝ์์ ๋ฆฌ์์ค ๋๊ธฐํ ๋ฐ ๋์ ์ ๊ทผ ์ ์ด์ ์ํฅ์ ๊ณ ๋ คํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค.
- ๋คํธ์ํฌ ์ง์ฐ ์๊ฐ: ๋์ ๋คํธ์ํฌ ์ง์ฐ ์๊ฐ์ ๋์์ฑ ๋ฌธ์ ์ ์ํฅ์ ์ ํ์ํฌ ์ ์์ต๋๋ค. ์๋ฒ ์ธก ๋ฝ ๋ฉ์ปค๋์ฆ์ ์๋นํ ์ง์ฐ์ ์ ๋ฐํ์ฌ ์ข์ง ์์ ์ฌ์ฉ์ ๊ฒฝํ์ผ๋ก ์ด์ด์ง ์ ์์ต๋๋ค. Web Locks API๋ ๋ฆฌ์์ค ์ ๊ทผ์ ๋๊ธฐํํ๊ธฐ ์ํ ํด๋ผ์ด์ธํธ ์ธก ์๋ฃจ์ ์ ์ ๊ณตํ์ฌ ์ด๋ฅผ ์ํํ๋ ๋ฐ ๋์์ด ๋ ์ ์์ต๋๋ค.
- ์๊ฐ๋: ์ด๋ฒคํธ ์์ฝ์ด๋ ํธ๋์ญ์ ์ฒ๋ฆฌ์ ๊ฐ์ด ์๊ฐ์ ๋ฏผ๊ฐํ ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฃฐ ๋๋ ๋ค๋ฅธ ์๊ฐ๋๋ฅผ ๊ณ ๋ คํ๋ ๊ฒ์ด ํ์์ ์ ๋๋ค. ์ ์ ํ ๋๊ธฐํ ๋ฉ์ปค๋์ฆ์ ์ถฉ๋์ ๋ฐฉ์งํ๊ณ ์ง๋ฆฌ์ ์ผ๋ก ๋ถ์ฐ๋ ์์คํ ์ ๋ฐ์ ๊ฑธ์ณ ๋ฐ์ดํฐ ์ผ๊ด์ฑ์ ๋ณด์ฅํ๋ ๋ฐ ๋์์ด ๋ ์ ์์ต๋๋ค.
- ๋ฌธํ์ ์ฐจ์ด: ๋ฌธํ๋ง๋ค ๋ฐ์ดํฐ ์ ๊ทผ ๋ฐ ์์ ์ ๋ํ ๊ธฐ๋์น๊ฐ ๋ค๋ฅผ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ์ผ๋ถ ๋ฌธํ๋ ์ค์๊ฐ ํ์ ์ ์ฐ์ ์ํ๋ ๋ฐ๋ฉด, ๋ค๋ฅธ ๋ฌธํ๋ ๋ ๋น๋๊ธฐ์ ์ธ ์ ๊ทผ ๋ฐฉ์์ ์ ํธํ ์ ์์ต๋๋ค. ์ด๋ฌํ ๋ค์ํ ์๊ตฌ๋ฅผ ์์ฉํ ์ ์๋๋ก ์ ํ๋ฆฌ์ผ์ด์ ์ ์ค๊ณํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค.
- ์ธ์ด ๋ฐ ํ์งํ: Web Locks API ์์ฒด๋ ์ธ์ด ๋๋ ํ์งํ์ ์ง์ ๊ด๋ จ์ด ์์ต๋๋ค. ๊ทธ๋ฌ๋ ๋๊ธฐํ๋๋ ๋ฆฌ์์ค์๋ ํ์งํ๋ ์ฝํ ์ธ ๊ฐ ํฌํจ๋ ์ ์์ต๋๋ค. ๋๊ธฐํ ๋ฉ์ปค๋์ฆ์ด ํ์งํ ์ ๋ต๊ณผ ํธํ๋๋์ง ํ์ธํ์ญ์์ค.
Web Locks API ์ฌ์ฉ์ ์ํ ๋ชจ๋ฒ ์ฌ๋ก
- ์ค์ ์น์ ์ ์งง๊ฒ ์ ์งํ๊ธฐ: ๋ฝ์ ์ค๋ ๋ณด์ ํ ์๋ก ๊ฒฝํฉ๊ณผ ์ง์ฐ ๊ฐ๋ฅ์ฑ์ด ์ปค์ง๋๋ค. ๊ณต์ ๋ฐ์ดํฐ๋ฅผ ์ ๊ทผํ๊ณ ์์ ํ๋ ์ฝ๋์ ์ค์ ์น์ ์ ๊ฐ๋ฅํ ํ ์งง๊ฒ ์ ์งํ์ญ์์ค.
- ๊ต์ฐฉ ์ํ(Deadlocks) ํผํ๊ธฐ: ๊ต์ฐฉ ์ํ๋ ๋ ์ด์์ ์ฝ๋ ์กฐ๊ฐ์ด ์๋ก๊ฐ ๋ฝ์ ํด์ ํ๊ธฐ๋ฅผ ๊ธฐ๋ค๋ฆฌ๋ฉฐ ๋ฌด๊ธฐํ ์ฐจ๋จ๋ ๋ ๋ฐ์ํฉ๋๋ค. ๊ต์ฐฉ ์ํ๋ฅผ ํผํ๋ ค๋ฉด ํญ์ ์ผ๊ด๋ ์์๋ก ๋ฝ์ ํ๋ํ๊ณ ํด์ ํด์ผ ํฉ๋๋ค.
- ์ค๋ฅ๋ฅผ ์ ์์ ์ผ๋ก ์ฒ๋ฆฌํ๊ธฐ: ๋ฝ์ ํ๋ํ ์ ์๋ ๊ฒฝ์ฐ `navigator.locks.request` ๋ฉ์๋๊ฐ ๊ฑฐ๋ถ๋ ์ ์์ต๋๋ค. ์ด๋ฌํ ์ค๋ฅ๋ฅผ ์ ์์ ์ผ๋ก ์ฒ๋ฆฌํ์ฌ ์ฌ์ฉ์์๊ฒ ์ ์ฉํ ํผ๋๋ฐฑ์ ์ ๊ณตํ์ญ์์ค.
- ์๋ฏธ ์๋ ๋ฝ ์ด๋ฆ ์ฌ์ฉํ๊ธฐ: ๋ณดํธ๋๋ ๋ฆฌ์์ค๋ฅผ ๋ช ํํ๊ฒ ์๋ณํ๋ ๋ฝ ์ด๋ฆ์ ์ ํํ์ญ์์ค. ์ด๋ ๊ฒ ํ๋ฉด ์ฝ๋๋ฅผ ๋ ์ฝ๊ฒ ์ดํดํ๊ณ ์ ์ง ๊ด๋ฆฌํ ์ ์์ต๋๋ค.
- ๋ฝ ๋ฒ์ ๊ณ ๋ คํ๊ธฐ: ๋ฝ์ ๋ํ ์ ์ ํ ๋ฒ์๋ฅผ ๊ฒฐ์ ํ์ญ์์ค. ๋ฝ์ด ์ ์ญ์ (๋ชจ๋ ๋ธ๋ผ์ฐ์ ํญ ๋ฐ ์ฐฝ์ ๊ฑธ์ณ)์ด์ด์ผ ํฉ๋๊น, ์๋๋ฉด ํน์ ํญ์ด๋ ์ฐฝ์ผ๋ก ์ ํ๋์ด์ผ ํฉ๋๊น? Web Locks API๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฝ์ ๋ฒ์๋ฅผ ์ ์ดํ ์ ์์ต๋๋ค.
- ์ฒ ์ ํ๊ฒ ํ ์คํธํ๊ธฐ: ์ฝ๋๊ฐ ๋์์ฑ์ ์ฌ๋ฐ๋ฅด๊ฒ ์ฒ๋ฆฌํ๊ณ ๊ฒฝ์ ์ํ๋ฅผ ๋ฐฉ์งํ๋์ง ํ์ธํ๊ธฐ ์ํด ์ฒ ์ ํ๊ฒ ํ ์คํธํ์ญ์์ค. ๋์์ฑ ํ ์คํธ ๋๊ตฌ๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ๋ฌ ์ฌ์ฉ์๊ฐ ๋์์ ๊ณต์ ๋ฆฌ์์ค๋ฅผ ์ ๊ทผํ๊ณ ์์ ํ๋ ์ํฉ์ ์๋ฎฌ๋ ์ด์ ํ์ญ์์ค.
Web Locks API์ ํ๊ณ
Web Locks API๋ ์น ์ ํ๋ฆฌ์ผ์ด์ ์์ ๋ฆฌ์์ค ์ ๊ทผ์ ๋๊ธฐํํ๋ ๊ฐ๋ ฅํ ๋ฉ์ปค๋์ฆ์ ์ ๊ณตํ์ง๋ง, ๊ทธ ํ๊ณ๋ฅผ ์ธ์งํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค.
- ๋ธ๋ผ์ฐ์ ์ง์: Web Locks API๋ ๋ชจ๋ ๋ธ๋ผ์ฐ์ ์์ ์ง์๋์ง๋ ์์ต๋๋ค. ํ๋ก๋์ ์ฝ๋์์ API๋ฅผ ์ฌ์ฉํ๊ธฐ ์ ์ ๋ธ๋ผ์ฐ์ ํธํ์ฑ์ ํ์ธํ์ญ์์ค. ์ค๋๋ ๋ธ๋ผ์ฐ์ ๋ฅผ ์ง์ํ๊ธฐ ์ํด ํด๋ฆฌํ(polyfill)์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
- ์ง์์ฑ: ๋ฝ์ ๋ธ๋ผ์ฐ์ ์ธ์ ๊ฐ์ ์ง์๋์ง ์์ต๋๋ค. ๋ธ๋ผ์ฐ์ ๊ฐ ๋ซํ๊ฑฐ๋ ์๋ก๊ณ ์นจ๋๋ฉด ๋ชจ๋ ๋ฝ์ด ํด์ ๋ฉ๋๋ค.
- ๋ถ์ฐ ๋ฝ ๋ฏธ์ง์: Web Locks API๋ ๋จ์ผ ๋ธ๋ผ์ฐ์ ์ธ์คํด์ค ๋ด์์์ ๋๊ธฐํ๋ง ์ ๊ณตํฉ๋๋ค. ์ฌ๋ฌ ์ปดํจํฐ๋ ์๋ฒ์ ๊ฑธ์ณ ๋ฆฌ์์ค ์ ๊ทผ์ ๋๊ธฐํํ๋ ๋ฉ์ปค๋์ฆ์ ์ ๊ณตํ์ง ์์ต๋๋ค. ๋ถ์ฐ ๋ฝ์ ๊ฒฝ์ฐ ์๋ฒ ์ธก ๋ฝ ๋ฉ์ปค๋์ฆ์ ์์กดํด์ผ ํฉ๋๋ค.
- ํ๋ ฅ์ ๋ฝ: Web Locks API๋ ํ๋ ฅ์ ๋ฝ์ ์์กดํฉ๋๋ค. ๊ณต์ ๋ฆฌ์์ค์ ์ ๊ทผํ๋ ์ฝ๋๊ฐ ๋ฝ ํ๋กํ ์ฝ์ ์ค์ํ๋๋ก ํ๋ ๊ฒ์ ๊ฐ๋ฐ์์ ์ฑ ์์ ๋๋ค. ์ด API๋ ์ฝ๋๊ฐ ๋จผ์ ๋ฝ์ ํ๋ํ์ง ์๊ณ ๋ฆฌ์์ค์ ์ ๊ทผํ๋ ๊ฒ์ ๋ง์ ์ ์์ต๋๋ค.
Web Locks API์ ๋์
Web Locks API๋ ๋ฆฌ์์ค ๋๊ธฐํ๋ฅผ ์ํ ์ ์ฉํ ๋๊ตฌ๋ฅผ ์ ๊ณตํ์ง๋ง, ๊ฐ๊ฐ์ ์ฅ๋จ์ ์ ๊ฐ์ง ๋ช ๊ฐ์ง ๋์์ ์ธ ์ ๊ทผ ๋ฐฉ์์ด ์กด์ฌํฉ๋๋ค.
- ์๋ฒ ์ธก ๋ฝ: ์๋ฒ์ ๋ฝ ๋ฉ์ปค๋์ฆ์ ๊ตฌํํ๋ ๊ฒ์ ๋์์ฑ์ ๊ด๋ฆฌํ๋ ์ ํต์ ์ธ ์ ๊ทผ ๋ฐฉ์์ ๋๋ค. ์ฌ๊ธฐ์๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค ํธ๋์ญ์ , ๋๊ด์ ๋ฝ ๋๋ ๋น๊ด์ ๋ฝ์ ์ฌ์ฉํ์ฌ ๊ณต์ ๋ฆฌ์์ค๋ฅผ ๋ณดํธํ๋ ๊ฒ์ด ํฌํจ๋ฉ๋๋ค. ์๋ฒ ์ธก ๋ฝ์ ๋ถ์ฐ ๋์์ฑ์ ๋ํด ๋ ๊ฐ๋ ฅํ๊ณ ์ ๋ขฐํ ์ ์๋ ์๋ฃจ์ ์ ์ ๊ณตํ์ง๋ง, ์ง์ฐ ์๊ฐ์ ์ ๋ฐํ๊ณ ์๋ฒ์ ๋ถํ๋ฅผ ์ฆ๊ฐ์ํฌ ์ ์์ต๋๋ค.
- ์์์ ์ฐ์ฐ(Atomic Operations): ์ผ๋ถ ๋ฐ์ดํฐ ๊ตฌ์กฐ ๋ฐ API๋ ์ผ๋ จ์ ์์ ์ด ๋จ์ผํ๊ณ ๋ถํ ํ ์ ์๋ ๋จ์๋ก ์คํ๋จ์ ๋ณด์ฅํ๋ ์์์ ์ฐ์ฐ์ ์ ๊ณตํฉ๋๋ค. ์ด๋ ๋ช ์์ ์ธ ๋ฝ ์์ด ๊ฐ๋จํ ๋ฐ์ดํฐ ๊ตฌ์กฐ์ ๋ํ ์ ๊ทผ์ ๋๊ธฐํํ๋ ๋ฐ ์ ์ฉํ ์ ์์ต๋๋ค.
- ๋ฉ์์ง ์ ๋ฌ(Message Passing): ๋ณ๊ฒฝ ๊ฐ๋ฅํ ์ํ๋ฅผ ๊ณต์ ํ๋ ๋์ , ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ค๋ฅธ ๋ถ๋ถ ๊ฐ์ ํต์ ํ๊ธฐ ์ํด ๋ฉ์์ง ์ ๋ฌ์ ์ฌ์ฉํ๋ ๊ฒ์ ๊ณ ๋ คํ์ญ์์ค. ์ด ์ ๊ทผ ๋ฐฉ์์ ๊ณต์ ๋ฝ์ ํ์์ฑ์ ์ ๊ฑฐํ์ฌ ๋์์ฑ ๊ด๋ฆฌ๋ฅผ ๋จ์ํํ ์ ์์ต๋๋ค.
- ๋ถ๋ณ์ฑ(Immutability): ๋ถ๋ณ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ๋ ๋์์ฑ ๊ด๋ฆฌ๋ฅผ ๋จ์ํํ ์ ์์ต๋๋ค. ๋ถ๋ณ ๋ฐ์ดํฐ๋ ์์ฑ๋ ํ์ ์์ ํ ์ ์์ผ๋ฏ๋ก ๊ฒฝ์ ์ํ์ ๊ฐ๋ฅ์ฑ์ ์ ๊ฑฐํฉ๋๋ค.
๊ฒฐ๋ก
Web Locks API๋ ์น ์ ํ๋ฆฌ์ผ์ด์ ์์ ๋ฆฌ์์ค์ ๋ํ ์ ๊ทผ์ ๋๊ธฐํํ๊ณ ๋์ ์ ๊ทผ์ ๊ด๋ฆฌํ๋ ๋ฐ ์ ์ฉํ ๋๊ตฌ์ ๋๋ค. ํด๋ผ์ด์ธํธ ์ธก ๋ฝ ๋ฉ์ปค๋์ฆ์ ์ ๊ณตํจ์ผ๋ก์จ ์ด API๋ ์ฑ๋ฅ์ ํฅ์์ํค๊ณ , ๋ฐ์ดํฐ ์์์ ๋ฐฉ์งํ๋ฉฐ, ์ฌ์ฉ์ ๊ฒฝํ์ ๊ฐ์ ํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ API์ ํ๊ณ๋ฅผ ์ดํดํ๊ณ ์ ์ ํ๊ฒ ์ฌ์ฉํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค. Web Locks API๋ฅผ ๊ตฌํํ๊ธฐ ์ ์ ์ ํ๋ฆฌ์ผ์ด์ ์ ํน์ ์๊ตฌ ์ฌํญ, ๋ธ๋ผ์ฐ์ ํธํ์ฑ ๋ฐ ๊ต์ฐฉ ์ํ ๊ฐ๋ฅ์ฑ์ ๊ณ ๋ คํ์ญ์์ค.
์ด ๊ฐ์ด๋์ ์ค๋ช ๋ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ๋ฐ๋ฅด๋ฉด Web Locks API๋ฅผ ํ์ฉํ์ฌ ๋์์ฑ์ ์ ์์ ์ผ๋ก ์ฒ๋ฆฌํ๊ณ ๋ค์ํ ๊ธ๋ก๋ฒ ํ๊ฒฝ์์ ๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ์ ๋ณด์ฅํ๋ ๊ฐ๋ ฅํ๊ณ ๋ฐ์์ฑ์ด ๋ฐ์ด๋ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ ์ ์์ต๋๋ค.