နားလည်ထားရမယ့် အချက်
နှေးတဲ့ work တွေ — email, video processing, report, AI call — က web request ကို block မလုပ်သင့်ပါဘူး။ Queue ဆီ ရွှေ့ပြီး separate worker တစ်ခုကို run ခိုင်းပါ။
- Producer — job တစ်ခုဖန်တီးပြီး queue ပေါ်ချတဲ့ web server။
- Queue — worker အားရအောင်စောင့်နေတဲ့ job တွေကို ထိန်းသိမ်းထား။
- Worker — job တွေကို ကောက်ယူပြီး သီးခြား run တဲ့ process တစ်ခု။
Cron job တွေက schedule အပေါ်မှာ run ပါတယ် (backup, digest, cleanup) request ကို တုံ့ပြန်တာမဟုတ်ဘဲပါ။ Webhook တွေက direction ကို ပြောင်းပစ်ပါတယ် — external service က သင့် app ကို ခေါ်ပါတယ်။
Webhook တွေက တစ်ကြိမ်ထက်ပို ရောက်လာတတ်တယ် — ကြိုတင်ပြင်ဆင်ပါ
Webhook ရဲ့ signature ကို verify လုပ်ပါ၊ network timeout ကနေ retry တွေကို မျှော်လင့်ထားပါ၊ ကိုင်တွယ်မှုကို idempotent ဖြစ်အောင်လုပ်ပါ။ ဒါကို ကျော်လိုက်ရင် duplicate webhook က duplicate charge ဖြစ်သွားနိုင်ပါတယ်။
Idempotency ဆိုတာ request တစ်ခုတည်းကို နှစ်ကြိမ်လုပ်ရင် တစ်ကြိမ်လုပ်ရင်နဲ့ အဆုံးရလဒ် တူညီစေတာပါ — handle ပြီးသား ID တွေကို track လုပ်ပြီး တွေ့ဖူးပြီးသားကို skip လုပ်ပါ။
- Queue
- Worker တစ်ခုက ကောက်ယူပြီး process လုပ်ဖို့ စောင့်နေတဲ့ pending job တွေရဲ့ ထိန်းသိမ်းရာ နေရာ။
- Worker
- Queue ကနေ job တွေ ဆွဲထုတ်ပြီး original request ကနေ သီးခြား run တဲ့ process တစ်ခု။
- Idempotency
- Request တစ်ခုတည်းကို တစ်ကြိမ်ထက်ပို process လုပ်ခြင်းက တစ်ကြိမ်လုပ်ခြင်းနဲ့ ရလဒ်တူညီစေတဲ့ property။
- Webhook
- External service ရဲ့ ဘက်မှာ event တစ်ခု ဖြစ်တဲ့အခါ သင့် app ဆီ ပို့တဲ့ HTTP callback။
QUEUE, WORKER, AND WEBHOOK FLOW
-------------------------------
QUEUE, WORKER, AND WEBHOOK FLOW
----------------------------------
[ WEB REQUEST ] [ EXTERNAL SERVICE ]
| |
| producer enqueues job | webhook call
v v
[ QUEUE ] [ YOUR APP ENDPOINT ]
| |
v verify signature
[ WORKER ] check idempotency key
| |
v already seen? -> skip
[ RESULT ] new? -> process once
CRON: same worker pattern, triggered by a clock, not a request.လက်တွေ့ scenario နဲ့ ချိတ်ကြည့်မယ်
Process လုပ်ပြီးသား request ID တွေရဲ့ set တစ်ခု ထားပါ။ Work အစစ် မလုပ်ခင် ဝင်လာတဲ့ ID က ဒီ set ထဲမှာ ရှိပြီးသားလား စစ်ပါ။
Fresh ID နဲ့ first call က ပုံမှန် process လုပ်ပါတယ်။ ID တူတဲ့ repeat call က skip ခံရပါတယ်။ ID မတူတဲ့ request က ပုံမှန် process ပြန်လုပ်ပါတယ်။
Production မှာ real storage နဲ့ ထောက်ပံ့ပါ
Idempotency guard အစစ်တစ်ခုက database table ဒါမှမဟုတ် key-value store လိုအပ်ပါတယ် — in-memory Set မဟုတ်ဘူး — restart ကို survive ဖို့နဲ့ instance အများကြီးမှာ အလုပ်ဖြစ်ဖို့ပါ။
အတူတူ စမ်းရေးကြည့်မယ်
function makeIdempotencyGuard() {
const processed = new Set();
return function handleRequest(requestId) {
if (processed.has(requestId)) {
return { action: "skipped", reason: "already processed", requestId };
}
processed.add(requestId);
return { action: "processed", requestId };
};
}
const handle = makeIdempotencyGuard();
console.log(JSON.stringify(handle("charge-9f1a")));
console.log(JSON.stringify(handle("charge-9f1a")));
console.log(JSON.stringify(handle("charge-7bd2")));{"action":"processed","requestId":"charge-9f1a"}
{"action":"skipped","reason":"already processed","requestId":"charge-9f1a"}
{"action":"processed","requestId":"charge-7bd2"}
(output က locale နှစ်ခုစလုံးအတွက် တူညီပါတယ်)၅ မိနစ် စမ်းကြည့်
makeIdempotencyGuard ကို process လုပ်ပြီးသား ID တစ်ခုစီအတွက် timestamp ပါ သိမ်းအောင် ချဲ့ပါ၊ ပြီးရင် unique request ဘယ်နှစ်ခု process လုပ်ခဲ့လဲ၊ duplicate ဘယ်နှစ်ခု skip ခံရလဲ report ပြမယ့် function ဒုတိယတစ်ခု ထပ်ထည့်ပါ။
သတိလေးတစ်ချက်
Request handler ထဲမှာ နှေးတဲ့ work (email, video processing) ကို တိုက်ရိုက် လုပ်ပြီး user တွေကို စောင့်စေတာ ဒါမှမဟုတ် platform request timeout ဖြစ်စေတာ။
Webhook တစ်ခုတည်းသာ တစ်ကြိမ်တည်း ရောက်လာမယ်လို့ ယုံကြည်ထားတာ — idempotency check မပါဘဲ retry ထားတဲ့ webhook က charge ဒါမှမဟုတ် order ကို duplicate ဖြစ်စေနိုင်ပါတယ်။
Stripe docs — Idempotent requests — Cloud & Deployment