์์ฒญ ๋ฒ์ ์ปจํ ์คํธ ๊ด๋ฆฌ๋ฅผ ์ํ ์๋ฐ์คํฌ๋ฆฝํธ Async Local Storage(ALS)๋ฅผ ์ดํด๋ณด์ธ์. ์ต์ ์น ๊ฐ๋ฐ์์ ALS์ ์ด์ , ๊ตฌํ ๋ฐฉ๋ฒ ๋ฐ ํ์ฉ ์ฌ๋ก๋ฅผ ์์๋ด ๋๋ค.
์๋ฐ์คํฌ๋ฆฝํธ Async Local Storage: ์์ฒญ ๋ฒ์ ์ปจํ ์คํธ ๊ด๋ฆฌ ๋ง์คํฐํ๊ธฐ
๋น๋๊ธฐ ์๋ฐ์คํฌ๋ฆฝํธ์ ์ธ๊ณ์์, ๋ค์ํ ์์ ์ ๊ฑธ์ณ ์ปจํ ์คํธ๋ฅผ ๊ด๋ฆฌํ๋ ๊ฒ์ ๋ณต์กํ ๊ณผ์ ๊ฐ ๋ ์ ์์ต๋๋ค. ํจ์ ํธ์ถ์ ํตํด ์ปจํ ์คํธ ๊ฐ์ฒด๋ฅผ ์ ๋ฌํ๋ ๊ฒ๊ณผ ๊ฐ์ ์ ํต์ ์ธ ๋ฐฉ๋ฒ๋ค์ ์ข ์ข ์ฅํฉํ๊ณ ๋ค๋ฃจ๊ธฐ ํ๋ ์ฝ๋๋ก ์ด์ด์ง๋๋ค. ๋คํํ๋, ์๋ฐ์คํฌ๋ฆฝํธ Async Local Storage (ALS)๋ ๋น๋๊ธฐ ํ๊ฒฝ์์ ์์ฒญ ๋ฒ์์ ์ปจํ ์คํธ๋ฅผ ๊ด๋ฆฌํ๊ธฐ ์ํ ์ฐ์ํ ํด๊ฒฐ์ฑ ์ ์ ๊ณตํฉ๋๋ค. ์ด ๊ธ์์๋ ALS์ ๋ณต์ก์ฑ์ ํํค์น๊ณ , ๊ทธ ์ด์ , ๊ตฌํ ๋ฐฉ๋ฒ, ๊ทธ๋ฆฌ๊ณ ์ค์ ์ฌ์ฉ ์ฌ๋ก๋ฅผ ํ๊ตฌํฉ๋๋ค.
Async Local Storage๋ ๋ฌด์์ธ๊ฐ?
Async Local Storage (ALS)๋ ํน์ ๋น๋๊ธฐ ์คํ ์ปจํ ์คํธ์ ๋ก์ปฌ์ธ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ ์ ์๊ฒ ํด์ฃผ๋ ๋ฉ์ปค๋์ฆ์ ๋๋ค. ์ด ์ปจํ ์คํธ๋ ์ผ๋ฐ์ ์ผ๋ก ์์ฒญ์ด๋ ํธ๋์ญ์ ๊ณผ ๊ด๋ จ์ด ์์ต๋๋ค. Node.js์ ๊ฐ์ ๋น๋๊ธฐ ์๋ฐ์คํฌ๋ฆฝํธ ํ๊ฒฝ์ ์ํ ์ค๋ ๋-๋ก์ปฌ ์คํ ๋ฆฌ์ง(thread-local storage)์ ๋๋ฑํ ๊ฒ์ ๋ง๋๋ ๋ฐฉ๋ฒ์ด๋ผ๊ณ ์๊ฐํ๋ฉด ๋ฉ๋๋ค. (๋จ์ผ ์ค๋ ๋ ์๋ฐ์คํฌ๋ฆฝํธ์๋ ์ง์ ์ ์ฉ๋์ง ์๋) ์ ํต์ ์ธ ์ค๋ ๋-๋ก์ปฌ ์คํ ๋ฆฌ์ง์ ๋ฌ๋ฆฌ, ALS๋ ๋น๋๊ธฐ ํ๋ฆฌ๋ฏธํฐ๋ธ๋ฅผ ํ์ฉํ์ฌ ์ธ์๋ก ๋ช ์์ ์ผ๋ก ์ ๋ฌํ์ง ์๊ณ ๋ ๋น๋๊ธฐ ํธ์ถ ์ ๋ฐ์ ์ปจํ ์คํธ๋ฅผ ์ ํํฉ๋๋ค.
ALS์ ํต์ฌ ์์ด๋์ด๋ ์ฃผ์ด์ง ๋น๋๊ธฐ ์์ (์: ์น ์์ฒญ ์ฒ๋ฆฌ) ๋ด์์ ํด๋น ํน์ ์์ ๊ณผ ๊ด๋ จ๋ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๊ณ ๊ฒ์ํ ์ ์์ผ๋ฉฐ, ์ด๋ฅผ ํตํด ์๋ก ๋ค๋ฅธ ๋์ ๋น๋๊ธฐ ์์ ๊ฐ์ ๊ฒฉ๋ฆฌ๋ฅผ ๋ณด์ฅํ๊ณ ์ปจํ ์คํธ ์ค์ผ์ ๋ฐฉ์งํ๋ค๋ ๊ฒ์ ๋๋ค.
์ Async Local Storage๋ฅผ ์ฌ์ฉํด์ผ ํ๋๊ฐ?
์ต์ ์๋ฐ์คํฌ๋ฆฝํธ ์ ํ๋ฆฌ์ผ์ด์ ์์ Async Local Storage๋ฅผ ์ฑํํ๊ฒ ๋ง๋๋ ๋ช ๊ฐ์ง ๊ฐ๋ ฅํ ์ด์ ๊ฐ ์์ต๋๋ค:
- ๊ฐ์ํ๋ ์ปจํ ์คํธ ๊ด๋ฆฌ: ์ฌ๋ฌ ํจ์ ํธ์ถ์ ํตํด ์ปจํ ์คํธ ๊ฐ์ฒด๋ฅผ ์ ๋ฌํ๋ ๊ฒ์ ํผํ์ฌ ์ฝ๋์ ์ฅํฉํจ์ ์ค์ด๊ณ ๊ฐ๋ ์ฑ์ ํฅ์์ํต๋๋ค.
- ํฅ์๋ ์ฝ๋ ์ ์ง๋ณด์์ฑ: ์ปจํ ์คํธ ๊ด๋ฆฌ ๋ก์ง์ ์ค์ ์ง์คํํ์ฌ ์ ํ๋ฆฌ์ผ์ด์ ์ปจํ ์คํธ๋ฅผ ์์ ํ๊ณ ์ ์ง๋ณด์ํ๊ธฐ ๋ ์ฝ๊ฒ ๋ง๋ญ๋๋ค.
- ๊ฐ์ ๋ ๋๋ฒ๊น ๋ฐ ํธ๋ ์ด์ฑ: ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ค์ํ ๊ณ์ธต์ ํตํด ์์ฒญ์ ์ถ์ ํ๊ธฐ ์ํ ์์ฒญ๋ณ ์ ๋ณด๋ฅผ ์ ํํฉ๋๋ค.
- ๋ฏธ๋ค์จ์ด์์ ์ํํ ํตํฉ: ALS๋ Express.js์ ๊ฐ์ ํ๋ ์์ํฌ์ ๋ฏธ๋ค์จ์ด ํจํด๊ณผ ์ ํตํฉ๋์ด ์์ฒญ ์๋ช ์ฃผ๊ธฐ์ ์ด๊ธฐ์ ์ปจํ ์คํธ๋ฅผ ์บก์ฒํ๊ณ ์ ํํ ์ ์์ต๋๋ค.
- ๋ณด์ผ๋ฌํ๋ ์ดํธ ์ฝ๋ ๊ฐ์: ์ปจํ ์คํธ๊ฐ ํ์ํ ๋ชจ๋ ํจ์์์ ๋ช ์์ ์ผ๋ก ์ปจํ ์คํธ๋ฅผ ๊ด๋ฆฌํ ํ์๊ฐ ์์ด ๋ ๊นจ๋ํ๊ณ ์ง์ค๋ ์ฝ๋๋ฅผ ์์ฑํ ์ ์์ต๋๋ค.
ํต์ฌ ๊ฐ๋ ๋ฐ API
Node.js (๋ฒ์ 13.10.0 ์ด์)์ `async_hooks` ๋ชจ๋์ ํตํด ์ฌ์ฉํ ์ ์๋ Async Local Storage API๋ ๋ค์๊ณผ ๊ฐ์ ์ฃผ์ ๊ตฌ์ฑ ์์๋ฅผ ์ ๊ณตํฉ๋๋ค:
- `AsyncLocalStorage` ํด๋์ค: ๋น๋๊ธฐ ์คํ ๋ฆฌ์ง ์ธ์คํด์ค๋ฅผ ์์ฑํ๊ณ ๊ด๋ฆฌํ๊ธฐ ์ํ ํต์ฌ ํด๋์ค์ ๋๋ค.
- `run(store, callback, ...args)` ๋ฉ์๋: ํน์ ๋น๋๊ธฐ ์ปจํ ์คํธ ๋ด์์ ํจ์๋ฅผ ์คํํฉ๋๋ค. `store` ์ธ์๋ ์ปจํ ์คํธ์ ์ฐ๊ด๋ ๋ฐ์ดํฐ๋ฅผ ๋ํ๋ด๊ณ , `callback`์ ์คํ๋ ํจ์์ ๋๋ค.
- `getStore()` ๋ฉ์๋: ํ์ฌ ๋น๋๊ธฐ ์ปจํ ์คํธ์ ์ฐ๊ด๋ ๋ฐ์ดํฐ๋ฅผ ๊ฒ์ํฉ๋๋ค. ํ์ฑ ์ปจํ ์คํธ๊ฐ ์์ผ๋ฉด `undefined`๋ฅผ ๋ฐํํฉ๋๋ค.
- `enterWith(store)` ๋ฉ์๋: ์ ๊ณต๋ ์คํ ์ด๋ก ์ปจํ ์คํธ์ ๋ช ์์ ์ผ๋ก ์ง์ ํฉ๋๋ค. ์ฝ๋๋ฅผ ๋ฐ๋ผ๊ฐ๊ธฐ ์ด๋ ต๊ฒ ๋ง๋ค ์ ์์ผ๋ฏ๋ก ์ฃผ์ํด์ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
- `disable()` ๋ฉ์๋: AsyncLocalStorage ์ธ์คํด์ค๋ฅผ ๋นํ์ฑํํฉ๋๋ค.
์ค์ฉ์ ์ธ ์์ ๋ฐ ์ฝ๋ ์ค๋ํซ
์๋ฐ์คํฌ๋ฆฝํธ ์ ํ๋ฆฌ์ผ์ด์ ์์ Async Local Storage๋ฅผ ์ฌ์ฉํ๋ ๋ช ๊ฐ์ง ์ค์ฉ์ ์ธ ์์ ๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ
์ด ์์ ๋ ๋น๋๊ธฐ ์ปจํ ์คํธ ๋ด์์ ์์ฒญ ID๋ฅผ ์ ์ฅํ๊ณ ๊ฒ์ํ๋ ๊ฐ๋จํ ์๋๋ฆฌ์ค๋ฅผ ๋ณด์ฌ์ค๋๋ค.
const { AsyncLocalStorage } = require('async_hooks');
const asyncLocalStorage = new AsyncLocalStorage();
function processRequest(req, res) {
const requestId = Math.random().toString(36).substring(2, 15);
asyncLocalStorage.run({ requestId }, () => {
// ๋น๋๊ธฐ ์์
์๋ฎฌ๋ ์ด์
setTimeout(() => {
const currentContext = asyncLocalStorage.getStore();
console.log(`์์ฒญ ID: ${currentContext.requestId}`);
res.end(`์์ฒญ ์ฒ๋ฆฌ ID: ${currentContext.requestId}`);
}, 100);
});
}
// ๋ค์ด์ค๋ ์์ฒญ ์๋ฎฌ๋ ์ด์
const http = require('http');
const server = http.createServer((req, res) => {
processRequest(req, res);
});
server.listen(3000, () => {
console.log('3000๋ฒ ํฌํธ์์ ์๋ฒ ๋๊ธฐ ์ค');
});
Express.js ๋ฏธ๋ค์จ์ด์ ํจ๊ป ALS ์ฌ์ฉํ๊ธฐ
์ด ์์ ๋ ALS๋ฅผ Express.js ๋ฏธ๋ค์จ์ด์ ํตํฉํ์ฌ ์์ฒญ๋ณ ์ ๋ณด๋ฅผ ์บก์ฒํ๊ณ ์์ฒญ ์๋ช ์ฃผ๊ธฐ ์ ์ฒด์์ ์ฌ์ฉํ ์ ์๋๋ก ํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ค๋๋ค.
const express = require('express');
const { AsyncLocalStorage } = require('async_hooks');
const app = express();
const asyncLocalStorage = new AsyncLocalStorage();
// ์์ฒญ ID๋ฅผ ์บก์ฒํ๋ ๋ฏธ๋ค์จ์ด
app.use((req, res, next) => {
const requestId = Math.random().toString(36).substring(2, 15);
asyncLocalStorage.run({ requestId }, () => {
next();
});
});
// ๋ผ์ฐํธ ํธ๋ค๋ฌ
app.get('/', (req, res) => {
const currentContext = asyncLocalStorage.getStore();
const requestId = currentContext.requestId;
console.log(`ID: ${requestId}(์ผ)๋ก ์์ฒญ ์ฒ๋ฆฌ ์ค`);
res.send(`์์ฒญ ์ฒ๋ฆฌ ID: ${requestId}`);
});
app.listen(3000, () => {
console.log('3000๋ฒ ํฌํธ์์ ์๋ฒ ๋๊ธฐ ์ค');
});
๊ณ ๊ธ ์ฌ์ฉ ์ฌ๋ก: ๋ถ์ฐ ์ถ์
ALS๋ ์ฌ๋ฌ ์๋น์ค์ ๋น๋๊ธฐ ์์ ์ ๊ฑธ์ณ ์ถ์ ID๋ฅผ ์ ํํด์ผ ํ๋ ๋ถ์ฐ ์ถ์ ์๋๋ฆฌ์ค์์ ํนํ ์ ์ฉํ ์ ์์ต๋๋ค. ์ด ์์ ๋ ALS๋ฅผ ์ฌ์ฉํ์ฌ ์ถ์ ID๋ฅผ ์์ฑํ๊ณ ์ ํํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ค๋๋ค.
const { AsyncLocalStorage } = require('async_hooks');
const { v4: uuidv4 } = require('uuid');
const asyncLocalStorage = new AsyncLocalStorage();
function generateTraceId() {
return uuidv4();
}
function withTrace(callback) {
const traceId = generateTraceId();
asyncLocalStorage.run({ traceId }, callback);
}
function getTraceId() {
const store = asyncLocalStorage.getStore();
return store ? store.traceId : null;
}
// ์ฌ์ฉ ์์
withTrace(() => {
const traceId = getTraceId();
console.log(`์ถ์ ID: ${traceId}`);
// ๋น๋๊ธฐ ์์
์๋ฎฌ๋ ์ด์
setTimeout(() => {
const nestedTraceId = getTraceId();
console.log(`์ค์ฒฉ๋ ์ถ์ ID: ${nestedTraceId}`); // ๋์ผํ ์ถ์ ID์ฌ์ผ ํฉ๋๋ค
}, 50);
});
์ค์ ์ฌ์ฉ ์ฌ๋ก
Async Local Storage๋ ๋ค์ํ ์๋๋ฆฌ์ค์ ์ ์ฉํ ์ ์๋ ๋ค์ฌ๋ค๋ฅํ ๋๊ตฌ์ ๋๋ค:
- ๋ก๊น : ์์ฒญ ID, ์ฌ์ฉ์ ID ๋๋ ์ถ์ ID์ ๊ฐ์ ์์ฒญ๋ณ ์ ๋ณด๋ก ๋ก๊ทธ ๋ฉ์์ง๋ฅผ ํ๋ถํ๊ฒ ๋ง๋ญ๋๋ค.
- ์ธ์ฆ ๋ฐ ์ธ๊ฐ: ์ฌ์ฉ์ ์ธ์ฆ ์ปจํ ์คํธ๋ฅผ ์ ์ฅํ๊ณ ์์ฒญ ์๋ช ์ฃผ๊ธฐ ์ ์ฒด์์ ์ ๊ทผํฉ๋๋ค.
- ๋ฐ์ดํฐ๋ฒ ์ด์ค ํธ๋์ญ์ : ๋ฐ์ดํฐ๋ฒ ์ด์ค ํธ๋์ญ์ ์ ํน์ ์์ฒญ๊ณผ ์ฐ๊ฒฐํ์ฌ ๋ฐ์ดํฐ ์ผ๊ด์ฑ๊ณผ ๊ฒฉ๋ฆฌ๋ฅผ ๋ณด์ฅํฉ๋๋ค.
- ์๋ฌ ์ฒ๋ฆฌ: ์์ฒญ๋ณ ์๋ฌ ์ปจํ ์คํธ๋ฅผ ์บก์ฒํ์ฌ ์์ธํ ์๋ฌ ๋ณด๊ณ ๋ฐ ๋๋ฒ๊น ์ ์ฌ์ฉํฉ๋๋ค.
- A/B ํ ์คํ : ์คํ ํ ๋น์ ์ ์ฅํ๊ณ ์ฌ์ฉ์ ์ธ์ ์ ์ฒด์ ์ผ๊ด๋๊ฒ ์ ์ฉํฉ๋๋ค.
๊ณ ๋ ค์ฌํญ ๋ฐ ๋ชจ๋ฒ ์ฌ๋ก
Async Local Storage๋ ์๋นํ ์ด์ ์ ์ ๊ณตํ์ง๋ง, ์ ์คํ๊ฒ ์ฌ์ฉํ๊ณ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ์ค์ํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค:
- ์ฑ๋ฅ ์ค๋ฒํค๋: ALS๋ ๋น๋๊ธฐ ์ปจํ ์คํธ์ ์์ฑ ๋ฐ ๊ด๋ฆฌ๋ก ์ธํด ์ฝ๊ฐ์ ์ฑ๋ฅ ์ค๋ฒํค๋๋ฅผ ๋ฐ์์ํต๋๋ค. ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ฏธ์น๋ ์ํฅ์ ์ธก์ ํ๊ณ ๊ทธ์ ๋ฐ๋ผ ์ต์ ํํ์ธ์.
- ์ปจํ ์คํธ ์ค์ผ: ๋ฉ๋ชจ๋ฆฌ ๋์ ๋ฐ ์ฑ๋ฅ ์ ํ๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด ALS์ ๊ณผ๋ํ ์์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ์ง ๋ง์ธ์.
- ๋ช ์์ ์ปจํ ์คํธ ๊ด๋ฆฌ: ์ด๋ค ๊ฒฝ์ฐ์๋, ํนํ ๋ณต์กํ๊ฑฐ๋ ๊น์ด ์ค์ฒฉ๋ ์์ ์ ๊ฒฝ์ฐ, ์ปจํ ์คํธ ๊ฐ์ฒด๋ฅผ ๋ช ์์ ์ผ๋ก ์ ๋ฌํ๋ ๊ฒ์ด ๋ ์ ์ ํ ์ ์์ต๋๋ค.
- ํ๋ ์์ํฌ ํตํฉ: ๋ก๊น ๋ฐ ํธ๋ ์ด์ฑ๊ณผ ๊ฐ์ ์ผ๋ฐ์ ์ธ ์์ ์ ์ํด ALS ์ง์์ ์ ๊ณตํ๋ ๊ธฐ์กด ํ๋ ์์ํฌ ํตํฉ ๋ฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํ์ฉํ์ธ์.
- ์๋ฌ ์ฒ๋ฆฌ: ์ปจํ ์คํธ ๋์๋ฅผ ๋ฐฉ์งํ๊ณ ALS ์ปจํ ์คํธ๊ฐ ์ฌ๋ฐ๋ฅด๊ฒ ์ ๋ฆฌ๋๋๋ก ์ ์ ํ ์๋ฌ ์ฒ๋ฆฌ๋ฅผ ๊ตฌํํ์ธ์.
Async Local Storage์ ๋์
ALS๋ ๊ฐ๋ ฅํ ๋๊ตฌ์ด์ง๋ง ๋ชจ๋ ์ํฉ์ ํญ์ ์ต์ ์ ์ ํ์ ์๋๋๋ค. ๊ณ ๋ คํด๋ณผ ๋งํ ๋ช ๊ฐ์ง ๋์์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- ๋ช ์์ ์ปจํ ์คํธ ์ ๋ฌ: ์ปจํ ์คํธ ๊ฐ์ฒด๋ฅผ ์ธ์๋ก ์ ๋ฌํ๋ ์ ํต์ ์ธ ์ ๊ทผ ๋ฐฉ์์ ๋๋ค. ์ด๋ ๋ ๋ช ์์ ์ด๊ณ ์ถ๋ก ํ๊ธฐ ์ฌ์ธ ์ ์์ง๋ง, ์ฅํฉํ ์ฝ๋๋ก ์ด์ด์ง ์๋ ์์ต๋๋ค.
- ์์กด์ฑ ์ฃผ์ : ์์กด์ฑ ์ฃผ์ ํ๋ ์์ํฌ๋ฅผ ์ฌ์ฉํ์ฌ ์ปจํ ์คํธ์ ์์กด์ฑ์ ๊ด๋ฆฌํฉ๋๋ค. ์ด๋ ์ฝ๋์ ๋ชจ๋์ฑ๊ณผ ํ ์คํธ ์ฉ์ด์ฑ์ ํฅ์์ํฌ ์ ์์ต๋๋ค.
- ์ปจํ ์คํธ ๋ณ์ (TC39 ์ ์): ์ปจํ ์คํธ๋ฅผ ๊ด๋ฆฌํ๋ ๋ ํ์คํ๋ ๋ฐฉ๋ฒ์ ์ ๊ณตํ๋ ์ ์๋ ECMAScript ๊ธฐ๋ฅ์ ๋๋ค. ์์ง ๊ฐ๋ฐ ์ค์ด๋ฉฐ ๋๋ฆฌ ์ง์๋์ง๋ ์์ต๋๋ค.
- ์ปค์คํ ์ปจํ ์คํธ ๊ด๋ฆฌ ์๋ฃจ์ : ํน์ ์ ํ๋ฆฌ์ผ์ด์ ์๊ตฌ ์ฌํญ์ ๋ง๋ ์ปค์คํ ์ปจํ ์คํธ ๊ด๋ฆฌ ์๋ฃจ์ ์ ๊ฐ๋ฐํฉ๋๋ค.
AsyncLocalStorage.enterWith() ๋ฉ์๋
enterWith() ๋ฉ์๋๋ `run()`์ด ์ ๊ณตํ๋ ์๋ ์ ํ๋ฅผ ์ฐํํ์ฌ ALS ์ปจํ ์คํธ๋ฅผ ์ค์ ํ๋ ๋ ์ง์ ์ ์ธ ๋ฐฉ๋ฒ์ ๋๋ค. ๊ทธ๋ฌ๋ ์ฃผ์ํด์ ์ฌ์ฉํด์ผ ํฉ๋๋ค. ์ผ๋ฐ์ ์ผ๋ก๋ ๋น๋๊ธฐ ์์ ์ ๋ฐ์ ๊ฑธ์ณ ์ปจํ ์คํธ ์ ํ๋ฅผ ์๋์ผ๋ก ์ฒ๋ฆฌํ๋ `run()`์ ์ฌ์ฉํ์ฌ ์ปจํ ์คํธ๋ฅผ ๊ด๋ฆฌํ๋ ๊ฒ์ด ๊ถ์ฅ๋ฉ๋๋ค. `enterWith()`๋ ์ ์คํ๊ฒ ์ฌ์ฉํ์ง ์์ผ๋ฉด ์๊ธฐ์น ์์ ๋์์ ์ ๋ฐํ ์ ์์ต๋๋ค.
const { AsyncLocalStorage } = require('async_hooks');
const asyncLocalStorage = new AsyncLocalStorage();
const store = { data: 'Some Data' };
// enterWith๋ฅผ ์ฌ์ฉํ์ฌ ์คํ ์ด ์ค์
asyncLocalStorage.enterWith(store);
// ์คํ ์ด์ ์ ๊ทผ (enterWith ์งํ์ ์๋ํด์ผ ํจ)
console.log(asyncLocalStorage.getStore());
// ์ปจํ
์คํธ๋ฅผ ์๋์ผ๋ก ์์ํ์ง ์๋ ๋น๋๊ธฐ ํจ์ ์คํ
setTimeout(() => {
// enterWith๋ก ์๋ ์ค์ ํ๊ธฐ ๋๋ฌธ์ ์ปจํ
์คํธ๊ฐ ์ฌ๊ธฐ์์๋ ์ฌ์ ํ ํ์ฑ ์ํ์
๋๋ค.
console.log(asyncLocalStorage.getStore());
}, 1000);
// ์ปจํ
์คํธ๋ฅผ ์ ๋๋ก ์ง์ฐ๋ ค๋ฉด try...finally ๋ธ๋ก์ด ํ์ํฉ๋๋ค
// ์ด๊ฒ์ด ์ run()์ด ์ผ๋ฐ์ ์ผ๋ก ์ ํธ๋๋์ง ๋ณด์ฌ์ค๋๋ค. run()์ ์ ๋ฆฌ๋ฅผ ์๋์ผ๋ก ์ฒ๋ฆฌํ๊ธฐ ๋๋ฌธ์
๋๋ค.
ํํ ํจ์ ๊ณผ ์ด๋ฅผ ํผํ๋ ๋ฐฉ๋ฒ
- `run()` ์ฌ์ฉ์ ์๋ ๊ฒฝ์ฐ: AsyncLocalStorage๋ฅผ ์ด๊ธฐํํ์ง๋ง ์์ฒญ ์ฒ๋ฆฌ ๋ก์ง์ `asyncLocalStorage.run()`์ผ๋ก ๊ฐ์ธ๋ ๊ฒ์ ์์ผ๋ฉด, ์ปจํ ์คํธ๊ฐ ์ ๋๋ก ์ ํ๋์ง ์์ `getStore()` ํธ์ถ ์ `undefined` ๊ฐ์ ์ป๊ฒ ๋ฉ๋๋ค.
- Promise์์ ๋ถ์ ํํ ์ปจํ ์คํธ ์ ํ: Promise๋ฅผ ์ฌ์ฉํ ๋, `run()` ์ฝ๋ฐฑ ๋ด์์ ๋น๋๊ธฐ ์์ ์ awaitํ๊ณ ์๋์ง ํ์ธํ์ธ์. awaitํ์ง ์์ผ๋ฉด ์ปจํ ์คํธ๊ฐ ์ฌ๋ฐ๋ฅด๊ฒ ์ ํ๋์ง ์์ ์ ์์ต๋๋ค.
- ๋ฉ๋ชจ๋ฆฌ ๋์: ์ปจํ ์คํธ๊ฐ ์ ๋๋ก ์ ๋ฆฌ๋์ง ์์ผ๋ฉด ๋ฉ๋ชจ๋ฆฌ ๋์๋ก ์ด์ด์ง ์ ์์ผ๋ฏ๋ก AsyncLocalStorage ์ปจํ ์คํธ์ ํฐ ๊ฐ์ฒด๋ฅผ ์ ์ฅํ์ง ๋ง์ธ์.
- AsyncLocalStorage์ ๋ํ ๊ณผ๋ํ ์์กด: AsyncLocalStorage๋ฅผ ์ ์ญ ์ํ ๊ด๋ฆฌ ์๋ฃจ์ ์ผ๋ก ์ฌ์ฉํ์ง ๋ง์ธ์. ์์ฒญ ๋ฒ์์ ์ปจํ ์คํธ ๊ด๋ฆฌ์ ๊ฐ์ฅ ์ ํฉํฉ๋๋ค.
์๋ฐ์คํฌ๋ฆฝํธ ์ปจํ ์คํธ ๊ด๋ฆฌ์ ๋ฏธ๋
์๋ฐ์คํฌ๋ฆฝํธ ์ํ๊ณ๋ ๋์์์ด ์งํํ๊ณ ์์ผ๋ฉฐ, ์ปจํ ์คํธ ๊ด๋ฆฌ์ ๋ํ ์๋ก์ด ์ ๊ทผ ๋ฐฉ์์ด ๋ฑ์ฅํ๊ณ ์์ต๋๋ค. ์ ์๋ ์ปจํ ์คํธ ๋ณ์ ๊ธฐ๋ฅ(TC39 ์ ์)์ ์ปจํ ์คํธ ๊ด๋ฆฌ๋ฅผ ์ํ ๋ ํ์คํ๋๊ณ ์ธ์ด ์์ค์ ์๋ฃจ์ ์ ์ ๊ณตํ๋ ๊ฒ์ ๋ชฉํ๋ก ํฉ๋๋ค. ์ด๋ฌํ ๊ธฐ๋ฅ๋ค์ด ์ฑ์ํ๊ณ ๋ ๋๋ฆฌ ์ฑํ๋จ์ ๋ฐ๋ผ, ์๋ฐ์คํฌ๋ฆฝํธ ์ ํ๋ฆฌ์ผ์ด์ ์์ ์ปจํ ์คํธ๋ฅผ ์ฒ๋ฆฌํ๋ ํจ์ฌ ๋ ์ฐ์ํ๊ณ ํจ์จ์ ์ธ ๋ฐฉ๋ฒ์ ์ ๊ณตํ ์ ์์ต๋๋ค.
๊ฒฐ๋ก
์๋ฐ์คํฌ๋ฆฝํธ Async Local Storage๋ ๋น๋๊ธฐ ํ๊ฒฝ์์ ์์ฒญ ๋ฒ์ ์ปจํ ์คํธ๋ฅผ ๊ด๋ฆฌํ๊ธฐ ์ํ ๊ฐ๋ ฅํ๊ณ ์ฐ์ํ ์๋ฃจ์ ์ ์ ๊ณตํฉ๋๋ค. ์ปจํ ์คํธ ๊ด๋ฆฌ๋ฅผ ๋จ์ํํ๊ณ , ์ฝ๋ ์ ์ง๋ณด์์ฑ์ ํฅ์์ํค๋ฉฐ, ๋๋ฒ๊น ๊ธฐ๋ฅ์ ๊ฐํํจ์ผ๋ก์จ ALS๋ Node.js ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฐ๋ฐ ๊ฒฝํ์ ํฌ๊ฒ ํฅ์์ํฌ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ํต์ฌ ๊ฐ๋ ์ ์ดํดํ๊ณ , ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ์ค์ํ๋ฉฐ, ํ๋ก์ ํธ์ ALS๋ฅผ ๋์ ํ๊ธฐ ์ ์ ์ ์ฌ์ ์ธ ์ฑ๋ฅ ์ค๋ฒํค๋๋ฅผ ๊ณ ๋ คํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค. ์๋ฐ์คํฌ๋ฆฝํธ ์ํ๊ณ๊ฐ ๊ณ์ ์งํํจ์ ๋ฐ๋ผ, ์ปจํ ์คํธ ๊ด๋ฆฌ์ ๋ํ ์๋กญ๊ณ ๊ฐ์ ๋ ์ ๊ทผ ๋ฐฉ์์ด ๋ฑ์ฅํ์ฌ ๋ณต์กํ ๋น๋๊ธฐ ์๋๋ฆฌ์ค๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ํ ํจ์ฌ ๋ ์ ๊ตํ ์๋ฃจ์ ์ ์ ๊ณตํ ์ ์์ต๋๋ค.