এজ কম্পিউট
CDN-এর এজে নিজের কোড চালানো — isolate, Wasm আর কন্টেইনারের পার্থক্য, কোন কাজ এজে মানায় আর কোনটা মানায় না, KV-এর eventual consistency, লিমিট, টেস্টিং আর ভেন্ডর লক-ইন।
গল্পে বুঝি
যমুনা সেতুর পূর্ব পাড়ে টোল প্লাজা। দিনে হাজার হাজার গাড়ি, বাস, ট্রাক। প্লাজার দায়িত্বে খোয়ারিজমি, আর সেতু কর্তৃপক্ষের হেড অফিস ঢাকায়, যেখানে ফাইল, খাতা আর বড় সিদ্ধান্ত থাকে। শুরুর দিকে নিয়ম ছিল কঠিন: যেকোনো প্রশ্ন উঠলে, যেমন একটা ট্রাকের ওজন বেশি কিনা, একটা অ্যাম্বুলেন্স টোল-মুক্ত কিনা, কেউ ভুল লেনে ঢুকেছে কিনা, প্লাজার লোক ফোন তুলে ঢাকায় জিজ্ঞেস করত। প্রতিটা ফোনে কয়েক মিনিট, পেছনে গাড়ির লাইন সিরাজগঞ্জ পর্যন্ত।
খোয়ারিজমি নিয়মটা বদলালেন। তিনি প্রতিটা বুথে একটা ছোট নিয়মের কার্ড দিলেন: অ্যাম্বুলেন্স আর ফায়ার সার্ভিস টোল-মুক্ত, মোটরসাইকেল বাঁ লেনে, ১০ টনের বেশি হলে ওজন স্টেশনে পাঠাও, আর যার কাছে মাসিক পাসের সিলমোহর আছে, সিলটা মিলিয়ে ছেড়ে দাও। এই প্রশ্নগুলোর উত্তর কার্ডে আছে, ঢাকায় ফোন লাগে না, প্রতিটা গাড়ি কয়েক সেকেন্ডে পার। বুথের কর্মী কিন্দি জানেন তার কাজ ছোট আর দ্রুত হতে হবে; একটা গাড়ির পেছনে দশ মিনিট দেওয়ার অনুমতি তার নেই, বুথে আলমারি বা ফাইল রাখার জায়গাও নেই।
কিন্তু কিছু কাজ বুথে হয় না। কেউ মাসিক পাসের মেয়াদ বাড়াতে চাইলে সেটা হেড অফিসের খাতায় লিখতে হয়, কারণ খাতা একটাই, আর প্রতিটা বুথে আলাদা খাতা থাকলে কেউ পূর্ব বুথে নবায়ন করে পশ্চিম বুথে গিয়ে বলবে “আমার পাস তো বাতিল দেখাচ্ছে।” আবার নতুন নিয়মের কার্ড যখন ঢাকা থেকে আসে, সব বুথে একসাথে পৌঁছায় না; কিছুক্ষণ পূর্ব আর পশ্চিম বুথ দুই রকম নিয়ম মানে।
মিলিয়ে নিই: টোল প্লাজার বুথগুলো হলো এজ লোকেশন (PoP), ঢাকার হেড অফিস হলো origin, আর বুথের নিয়মের কার্ড হলো এজ ফাংশন, যেটা প্রতিটা রিকোয়েস্টে ছোট সিদ্ধান্ত নেয়। মোটরসাইকেল বাঁ লেনে পাঠানো হলো রাউটিং ও রিডাইরেক্ট, মাসিক পাসের সিল মেলানো হলো টোকেন (JWT) ভেরিফিকেশন, আর অ্যাম্বুলেন্স ছেড়ে দেওয়া হলো হেডার দেখে নিয়ম প্রয়োগ। কর্মীর “ছোট আর দ্রুত” নিয়ম হলো এজ রানটাইমের CPU ও মেমরি লিমিট। পাস নবায়নের একমাত্র খাতা হলো strong consistency দরকার এমন ডেটাবেস রাইট, যেটা origin-এর কাছেই থাকা উচিত, আর নতুন নিয়মের কার্ড ধীরে ধীরে সব বুথে পৌঁছানো হলো এজ KV-এর eventual consistency। বাস্তবে এজ কম্পিউট ঠিক এই কাজেই ব্যবহার হয়: প্রতিটা রিকোয়েস্টে ছোট, দ্রুত, স্থানীয় সিদ্ধান্ত, আর বাকি সব origin-এর হাতে।
এজ কম্পিউট আসলে কী
সাধারণ CDN একটা নির্দিষ্ট কাজ করে: ক্যাশে থাকলে দাও, না থাকলে origin থেকে আনো। আপনি কনফিগ দিয়ে নিয়ম বদলাতে পারেন (কোন পাথ কতক্ষণ ক্যাশ হবে), কিন্তু যুক্তি লিখতে পারেন না। এজ কম্পিউট আপনাকে প্রতিটা PoP-এ নিজের কোড চালাতে দেয়, রিকোয়েস্ট আসা আর রেসপন্স যাওয়ার মাঝখানে।
এজ ফাংশন তিনটা কাজের যেকোনোটা করতে পারে:
- রিকোয়েস্ট বদলানো origin-এ যাওয়ার আগে (হেডার যোগ, URL রিরাইট, অন্য origin বাছাই)।
- নিজেই উত্তর দেওয়া (রিডাইরেক্ট, 403, ছোট JSON), origin-কে না জাগিয়ে।
- রেসপন্স বদলানো ইউজারের কাছে ফেরার আগে (হেডার যোগ, HTML-এ কিছু ঢোকানো)।
তিন ধরনের রানটাইম
ভেন্ডররা এজে কোড চালানোর জন্য মূলত তিনটা পদ্ধতি ব্যবহার করে। এটা জানা জরুরি, কারণ পদ্ধতিটাই ঠিক করে কোন ল্যাঙ্গুয়েজ চলবে, কত দ্রুত শুরু হবে, আর কী কী লিমিট থাকবে।
| পদ্ধতি | কীভাবে কাজ করে | শুরুর সময় | উদাহরণ |
|---|---|---|---|
| V8 isolate | একটা প্রসেসের ভেতরে অনেকগুলো আলাদা JavaScript পরিবেশ, প্রতিটা আলাদা মেমরি নিয়ে | খুব কম (মিলিসেকেন্ডের নিচে থেকে কয়েক মিলিসেকেন্ড) | Cloudflare Workers, Deno Deploy |
| WebAssembly (Wasm) | কোড Wasm-এ কম্পাইল হয়, প্রতিটা রিকোয়েস্টে একটা নতুন sandbox | খুব কম; Fastly নিজে “মাইক্রোসেকেন্ডে” দাবি করে | Fastly Compute (Wasmtime) |
| কন্টেইনার / microVM | পুরো একটা ছোট Linux পরিবেশ | বেশি (cold start শত মিলিসেকেন্ড বা তার বেশি হতে পারে) | কিছু “edge” লেবেলের serverless প্ল্যাটফর্ম |
Isolate আর Wasm-এর সুবিধা হলো শুরুর খরচ এত কম যে প্রতিটা রিকোয়েস্টে নতুন করে শুরু করা যায়, আর একটা মেশিনে হাজারটা আলাদা কাস্টমারের কোড নিরাপদে পাশাপাশি চলে। এর দাম হলো সীমাবদ্ধতা: পুরো Node.js API নেই, ফাইলসিস্টেম নেই, যেকোনো native লাইব্রেরি চলে না।
ভেন্ডরদের রানটাইম আর লিমিট ঘনঘন বদলায়। এই চ্যাপ্টারের ভেন্ডর-নির্দিষ্ট তথ্য ২০২৬ সালের অক্টোবর অনুযায়ী তাদের নিজেদের ডক থেকে নেওয়া; কিছু ডিজাইন করার আগে আপনার ভেন্ডরের বর্তমান “limits” পেজটা দেখে নিন।
কোন কাজ এজে মানায়
নিয়মটা সহজ: কাজটা যদি ছোট হয়, শুধু রিকোয়েস্টের তথ্য (URL, হেডার, কুকি, দেশ) আর কিছু রিড-অনলি কনফিগ লাগে, তাহলে এজে মানায়।
- রিডাইরেক্ট আর URL রিরাইট। পুরনো URL থেকে নতুন URL,
wwwথেকে apex, ট্রেইলিং স্ল্যাশ ঠিক করা। হাজারটা রিডাইরেক্টের তালিকা KV-এ রাখা যায়। - হেডার যোগ বা বদল। সিকিউরিটি হেডার (
Content-Security-Policy,Strict-Transport-Security), CORS হেডার, ক্যাশ হেডার ঠিক করা যখন origin ভুল পাঠায়। - অথ চেক। JWT-এর সিগনেচার আর মেয়াদ এজেই যাচাই করা যায় (পাবলিক কী দিয়ে), ফলে অবৈধ রিকোয়েস্ট origin পর্যন্ত পৌঁছায় না। শুধু সিগনেচার যাচাই, কোনো ডেটাবেস লুকআপ না।
- A/B বাকেটিং। ইউজারকে কুকি দিয়ে একটা বাকেটে রাখা, আর সেই অনুযায়ী আলাদা origin বা আলাদা ক্যাশ কী।
- জিও রাউটিং। দেশ দেখে ভাষা বা অঞ্চলের পেজে পাঠানো (তবে চ্যাপ্টার ১২-এর জিও-ব্লকিং সতর্কতা দেখুন)।
- HTML রিরাইট। স্ট্রিমিং অবস্থায় HTML-এ একটা ব্যানার বা ট্যাগ যোগ করা।
- Origin-এ রিকোয়েস্ট সাইন করা। এজ একটা গোপন কী দিয়ে রিকোয়েস্টে সিগনেচার যোগ করে, origin শুধু সাইন করা রিকোয়েস্ট মানে।
কোন কাজ এজে মানায় না
- ভারী কম্পিউট। বড় ইমেজ প্রসেসিং, ML ইনফারেন্স, লম্বা লুপ। CPU লিমিটে আটকাবে, আর যদি না-ও আটকায়, প্রতিটা PoP-এ একই ভারী কাজ চালানো খরচসাপেক্ষ।
- Strong consistency দরকার এমন রাইট। পেমেন্ট, ইনভেন্টরি কমানো, অ্যাকাউন্ট ব্যালান্স। আপনার ডেটাবেস যদি সিঙ্গাপুরে থাকে, ফ্রাঙ্কফুর্টের এজ থেকে প্রতিটা কুয়েরি সিঙ্গাপুর ঘুরে আসবে। একটা রিকোয়েস্টে পাঁচটা কুয়েরি মানে পাঁচটা আন্তঃমহাদেশীয় round trip, যা origin-এ সরাসরি চালানোর চেয়ে অনেক ধীর।
- অনেক ডেটা দরকার এমন কাজ। রিপোর্ট বানানো, সার্চ, জয়েন। ডেটা যেখানে আছে, কোড সেখানে চালান।
“এজে চালালেই দ্রুত” একটা ভুল ধারণা। কোড ইউজারের কাছে চলে আসে, কিন্তু ডেটা আসে না। যে ফাংশন প্রতিটা রিকোয়েস্টে দূরের ডেটাবেসে যায়, সেটা origin-এ চালানো একই কোডের চেয়ে ধীর হতে পারে, কারণ origin অন্তত ডেটাবেসের পাশে বসে আছে। কোড সরানোর আগে জিজ্ঞেস করুন: এই কাজের জন্য কোন ডেটা লাগে, আর সেটা কোথায় থাকে?
এজ KV ও eventual consistency
বেশিরভাগ এজ প্ল্যাটফর্ম একটা key-value স্টোর দেয় যেটা সব PoP থেকে পড়া যায়। এটা পড়ার জন্য দ্রুত, কারণ ডেটা প্রতিটা PoP-এর কাছে ক্যাশ হয়। কিন্তু রাইট সাথে সাথে সব জায়গায় দেখা যায় না।
# Illustrative timeline
t=0s write redirects["/old-catalog"] = "/catalog" (from Dhaka)
t=0.2s read in Dhaka PoP -> "/catalog"
t=0.2s read in Frankfurt PoP -> (old value or missing)
t=30s+ read in Frankfurt PoP -> "/catalog" কতক্ষণ পর সব জায়গায় পৌঁছায়, সেটা ভেন্ডর ভেদে আলাদা, আর সাধারণত সেকেন্ড থেকে এক মিনিটের মতো। এর মানে:
- কনফিগ, রিডাইরেক্ট লিস্ট, ফিচার ফ্ল্যাগ এজ KV-এর জন্য চমৎকার: কম লেখা হয়, বেশি পড়া হয়, আর কয়েক সেকেন্ডের পুরনো মান ক্ষতিকর না।
- সেশন, কাউন্টার, ইনভেন্টরি এজ KV-এ রাখবেন না। দুইটা PoP একই কাউন্টার পড়ে, দুজনেই এক বাড়িয়ে লেখে, একটা আপডেট হারায়।
কিছু ভেন্ডর strong consistency দেয় এমন আলাদা প্রোডাক্টও রাখে (যেমন একটা নির্দিষ্ট জায়গায় থাকা stateful অবজেক্ট বা এজ থেকে অ্যাক্সেসযোগ্য ডেটাবেস), কিন্তু তখন ডেটা আবার একটা জায়গায় থাকে, আর দূরের ইউজারের জন্য latency ফেরত আসে। পদার্থবিজ্ঞান বদলায় না।
Cold start ও লিমিট
Cold start
একটা ফাংশন যখন কোনো PoP-এ অনেকক্ষণ রিকোয়েস্ট পায়নি, রানটাইম তাকে মেমরি থেকে সরিয়ে দিতে পারে। পরের রিকোয়েস্টে আবার লোড করতে হয়: এটা cold start। Isolate আর Wasm ভিত্তিক রানটাইমে এটা সাধারণত এত ছোট যে ইউজার টের পায় না; কন্টেইনার ভিত্তিক প্ল্যাটফর্মে এটা লক্ষণীয় হতে পারে। আপনার নিজের কোডও cold start বাড়ায়: বড় বান্ডেল, গ্লোবাল স্কোপে ভারী ইনিশিয়ালাইজেশন।
// Bad: parses a large JSON on every cold start, at module scope
import bigTable from './geo-table.json';
// Better: keep the bundle small; fetch rarely-needed data lazily and cache it
let table: Record<string, string> | undefined;
async function getTable(env: Env) {
table ??= await env.CONFIG.get('geo-table', 'json');
return table;
} লিমিট
প্রতিটা প্ল্যাটফর্মের CPU সময়, মেমরি, সাবরিকোয়েস্ট আর কোডের সাইজের লিমিট আছে। একটা উদাহরণ হিসেবে, Cloudflare Workers-এর ডক অনুযায়ী (২০২৬ সালের অক্টোবর অনুযায়ী):
| লিমিট | Free | Paid |
|---|---|---|
| প্রতি HTTP রিকোয়েস্টে CPU সময় | ১০ ms | ডিফল্ট ৩০ সেকেন্ড, কনফিগ করে সর্বোচ্চ ৫ মিনিট |
| প্রতি isolate মেমরি | ১২৮ MB | ১২৮ MB |
| প্রতি invocation সাবরিকোয়েস্ট | ৫০ | ডিফল্ট ১০,০০০ |
এই সংখ্যাগুলো বদলায়, তাই ভেন্ডরের limits পেজ দেখে নিন। খেয়াল করুন CPU সময় আর মোট সময় আলাদা: একটা fetch()-এর জন্য অপেক্ষা করার সময় সাধারণত CPU সময়ে গোনা হয় না। আর ১২৮ MB মেমরি মানে বড় ফাইল পুরোটা মেমরিতে তুলবেন না; স্ট্রিম করুন।
একটা পোর্টেবল উদাহরণ
এজ রানটাইমগুলো ক্রমশ একই ওয়েব-স্ট্যান্ডার্ড API-এর দিকে যাচ্ছে: Request, Response, fetch, URL, Headers, Web Crypto। এই সাধারণ API-এর তালিকা ঠিক করার কাজটা আগে W3C-র WinterCG কমিউনিটি গ্রুপ করত; জানুয়ারি ২০২৫-এ সেটা Ecma International-এর TC55 (WinterTC) হয়েছে, যার মূল কাজ “Minimum Common Web API”। এই API-এর মধ্যে থাকলে কোড এক প্ল্যাটফর্ম থেকে আরেকটায় নিতে কম ঝামেলা।
নিচের হ্যান্ডলারটা শুধু স্ট্যান্ডার্ড API ব্যবহার করে। এটা তিনটা কাজ করে: পুরনো পাথ রিডাইরেক্ট, দেশ অনুযায়ী ভাষার পেজে পাঠানো, আর origin রেসপন্সে সিকিউরিটি হেডার যোগ।
// edge.ts — portable fetch handler: geo redirect + legacy redirects + header rewrite
const LEGACY: Record<string, string> = {
'/old-catalog': '/catalog',
'/kitab': '/books'
};
const LANG_BY_COUNTRY: Record<string, string> = { BD: 'bn', EG: 'ar', IR: 'fa' };
const SECURITY_HEADERS: Record<string, string> = {
'strict-transport-security': 'max-age=31536000; includeSubDomains',
'x-content-type-options': 'nosniff',
'referrer-policy': 'strict-origin-when-cross-origin'
};
// The platform supplies the country differently (a header, or a request property).
// Read it in one place so the rest stays portable.
function countryOf(req: Request): string | undefined {
return req.headers.get('x-viewer-country') ?? undefined;
}
export async function handle(req: Request, origin: string): Promise<Response> {
const url = new URL(req.url);
const legacy = LEGACY[url.pathname];
if (legacy) return Response.redirect(new URL(legacy, url).toString(), 301);
// Only the bare home page is geo-routed; never override a language the user chose.
if (url.pathname === '/' && !req.headers.get('cookie')?.includes('lang=')) {
const lang = LANG_BY_COUNTRY[countryOf(req) ?? ''];
if (lang) {
const res = Response.redirect(new URL(`/${lang}/`, url).toString(), 302);
// A geo-dependent redirect must not be cached as one shared answer.
const out = new Response(null, res);
out.headers.set('cache-control', 'private, no-store');
return out;
}
}
const upstream = await fetch(new URL(url.pathname + url.search, origin), req);
const res = new Response(upstream.body, upstream);
for (const [k, v] of Object.entries(SECURITY_HEADERS)) res.headers.set(k, v);
return res;
} প্ল্যাটফর্মের সাথে জোড়া লাগানোর অংশটা ছোট আর আলাদা থাকে। যেমন যে প্ল্যাটফর্ম একটা default export অবজেক্টে fetch মেথড চায়, সেখানে:
// worker-entry.ts — platform glue only
import { handle } from './edge';
export default {
async fetch(req: Request, env: { ORIGIN: string }): Promise<Response> {
return handle(req, env.ORIGIN);
}
}; দুইটা জিনিস খেয়াল করুন। এক, দেশের তথ্য প্রতিটা ভেন্ডর আলাদাভাবে দেয়, তাই সেটা একটা ফাংশনে আটকে রাখা হয়েছে। দুই, জিও-নির্ভর রিডাইরেক্টকে no-store করা হয়েছে, নইলে CDN একটা দেশের রিডাইরেক্ট ক্যাশ করে সবাইকে সেটাই দেবে (চ্যাপ্টার ৪)।
টেস্টিং ও অবজার্ভেবিলিটি
এজ কোড প্রতিটা রিকোয়েস্টের পথে বসে থাকে, তাই এর একটা বাগ মানে পুরো সাইট ডাউন। সাধারণ সার্ভার কোডের চেয়ে বেশি সাবধান হতে হয়।
- লোকালি ইউনিট টেস্ট। যেহেতু হ্যান্ডলার শুধু
Requestনেয় আরResponseদেয়, সাধারণ টেস্ট রানারে (Node বা Deno-তে, যেখানে এই API-গুলো আছে) সরাসরি টেস্ট করা যায়।
// edge.test.ts
import { test, expect } from 'vitest';
import { handle } from './edge';
test('legacy path redirects permanently', async () => {
const res = await handle(new Request('https://baytalhikma.org/kitab'), 'https://origin.example');
expect(res.status).toBe(301);
expect(res.headers.get('location')).toBe('https://baytalhikma.org/books');
});
test('geo redirect is never cacheable', async () => {
const req = new Request('https://baytalhikma.org/', { headers: { 'x-viewer-country': 'BD' } });
const res = await handle(req, 'https://origin.example');
expect(res.headers.get('location')).toBe('https://baytalhikma.org/bn/');
expect(res.headers.get('cache-control')).toContain('no-store');
}); - ধাপে ধাপে রোলআউট। বেশিরভাগ প্ল্যাটফর্ম ভার্সন রাখে আর শতাংশ ধরে ট্রাফিক নতুন ভার্সনে পাঠাতে দেয়। প্রথমে একটা স্টেজিং হোস্টনেমে, তারপর ১%, তারপর সবাই।
- লগ ও মেট্রিক। এরর রেট, CPU সময়, আর সাবরিকোয়েস্টের latency দেখুন। লগ সাধারণত স্যাম্পলড বা রিয়েল-টাইম টেইল আকারে আসে; দীর্ঘমেয়াদি রাখতে চাইলে নিজের লগ সংগ্রহের জায়গায় পাঠান।
- একটা ডিবাগ হেডার। কোন ভার্সন রিকোয়েস্টটা হ্যান্ডেল করল, সেটা একটা রেসপন্স হেডারে দিন (যেমন
x-edge-version: 2026-10-25.3)। ইনসিডেন্টের সময় এটা অনেক প্রশ্নের উত্তর দেয়। - ফেইল-ওপেন নাকি ফেইল-ক্লোজড। আপনার ফাংশন এক্সেপশন দিলে কী হবে? রিডাইরেক্ট বা হেডারের মতো কাজে ভালো হলো এরর হলে সরাসরি origin-এ পাঠিয়ে দেওয়া (ফেইল-ওপেন)। অথ চেকের মতো কাজে উল্টো: এরর হলে রিকোয়েস্ট আটকাতে হবে (ফেইল-ক্লোজড)।
ভেন্ডর লক-ইন
এজ কোড সহজেই একটা ভেন্ডরের সাথে বাঁধা পড়ে যায়: তাদের KV, তাদের দেশ জানার পদ্ধতি, তাদের কনফিগ ফাইল, তাদের HTML রিরাইটার API। কিছুটা লক-ইন অনিবার্য, কিন্তু কমানো যায়:
- ব্যবসায়িক যুক্তি স্ট্যান্ডার্ড API-তে লিখুন (
Request,Response,fetch, Web Crypto), আর ভেন্ডর-নির্দিষ্ট অংশ একটা পাতলা অ্যাডাপ্টারে রাখুন, উপরের উদাহরণের মতো। - ডেটা পোর্টেবল রাখুন। KV-এর কনফিগ আপনার রিপোজিটরিতে ফাইল হিসেবে রাখুন আর ডিপ্লয়ের সময় পুশ করুন, যাতে ভেন্ডর বদলালে ডেটা হারায় না।
- এজ কোড ছোট রাখুন। যত কম যুক্তি এজে, তত কম কিছু নতুন করে লিখতে হবে। যেটা origin-এ চলতে পারে, সেটা origin-এ রাখুন।
- নিজের CDN-এর কথা মাথায় রাখলে (চ্যাপ্টার ১৩), একই ধরনের যুক্তি nginx-এর
njsবা OpenResty-র Lua-তে চালানো যায়; ধারণাটা একই, সিনট্যাক্স আলাদা।
ডিবাগিং: এই চ্যাপ্টারের সমস্যাগুলো
| লক্ষণ | নিশ্চিত করার উপায় | সমাধান |
|---|---|---|
| ডিপ্লয়ের পর সব রিকোয়েস্টে 5xx | curl -sI URL দেখুন ভেন্ডরের এরর পেজ আসছে কিনা, প্ল্যাটফর্মের লাইভ লগ টেইল করুন | আগের ভার্সনে রোলব্যাক; এরপর থেকে শতাংশ ধরে রোলআউট |
| কিছু রিকোয়েস্ট CPU লিমিটে মারা যাচ্ছে | প্ল্যাটফর্মের মেট্রিকে “exceeded CPU” জাতীয় এরর দেখুন | ভারী কাজ origin-এ সরান, গ্লোবাল স্কোপের ইনিশিয়ালাইজেশন কমান |
| এজ ফাংশন origin-এর চেয়ে ধীর | Server-Timing বা লগে সাবরিকোয়েস্টের সময় দেখুন | দূরের ডেটাবেস কুয়েরি এজ থেকে সরান; একটা রিকোয়েস্টে একাধিক round trip এড়ান |
| KV-এ নতুন মান কিছু দেশে আসছে না | দুই অঞ্চল থেকে একই কী পড়ুন (দুইটা VPS বা প্ল্যাটফর্মের রিমোট টেস্ট) | মিনিটখানেক অপেক্ষা; এটা eventual consistency। জরুরি হলে ডেটা ভার্সনড কী-তে রাখুন |
| কাউন্টার বা সেশন এলোমেলো | একই ইউজারের দুইটা রিকোয়েস্ট দুই PoP-এ গেলে কী হয় দেখুন | strong consistency লাগে এমন ডেটা origin-এর ডেটাবেসে রাখুন |
| জিও রিডাইরেক্ট ভুল দেশের ইউজারকে যাচ্ছে | রেসপন্সে cache-control আর age দেখুন | জিও-নির্ভর রেসপন্সে private, no-store, বা দেশকে ক্যাশ কীতে রাখুন |
| লোকালে চলে, এজে চলে না | এরর মেসেজে কোনো Node-নির্দিষ্ট API (fs, Buffer) আছে কিনা দেখুন | স্ট্যান্ডার্ড ওয়েব API ব্যবহার করুন, বা প্ল্যাটফর্মের কম্প্যাটিবিলিটি ফ্ল্যাগ দেখুন |
| অথ চেক এরর হলে রিকোয়েস্ট পার হয়ে যাচ্ছে | ভুল টোকেন দিয়ে curl -H 'Authorization: Bearer bad' URL | অথ কোডে try/catch-এর ডিফল্ট 401/403 করুন (ফেইল-ক্লোজড) |
| কোন ভার্সন চলছে বোঝা যাচ্ছে না | রেসপন্স হেডারে ভার্সন খুঁজুন | একটা x-edge-version হেডার যোগ করুন |
মূল শিক্ষা
- এজ কম্পিউট মানে প্রতিটা রিকোয়েস্টের পথে ছোট, দ্রুত, স্থানীয় সিদ্ধান্ত: রিডাইরেক্ট, হেডার, টোকেন যাচাই, বাকেটিং, রাউটিং।
- রানটাইমের ধরন (isolate, Wasm, কন্টেইনার) ঠিক করে শুরুর সময়, ল্যাঙ্গুয়েজ আর লিমিট।
- কোড ইউজারের কাছে আসে, ডেটা আসে না। দূরের ডেটাবেসে বারবার যাওয়া এজ ফাংশন origin-এর চেয়ে ধীর।
- এজ KV eventually consistent। কনফিগ আর ফ্ল্যাগের জন্য চমৎকার, কাউন্টার আর সেশনের জন্য ভুল।
- লিমিট বদলায়। CPU সময়, মেমরি আর সাবরিকোয়েস্টের সংখ্যা ভেন্ডরের বর্তমান ডক থেকে দেখে নিন।
- স্ট্যান্ডার্ড API-তে যুক্তি, পাতলা অ্যাডাপ্টারে ভেন্ডর-নির্দিষ্ট অংশ। WinterTC-র Minimum Common Web API এই দিকেই।
- এজ কোডের বাগ পুরো সাইট নামায়। ইউনিট টেস্ট, শতাংশ ধরে রোলআউট, ভার্সন হেডার, আর কাজ অনুযায়ী ফেইল-ওপেন বা ফেইল-ক্লোজড।