Ubuntu TechHive

How fetch Connects JavaScript Runtimes to Durable Compute

How fetch Connects JavaScript Runtimes to Durable Compute

जावास्क्रिप्ट रनटाइम से लेकर पोर्टेबल, स्टेटफुल कंप्यूटेशन तक...

fetch कैसे JavaScript रनटाइम को Durable Compute से जोड़ता है

Durable Compute

JavaScript एक सामान्य निष्पादन लक्ष्य (execution target) है; वेब प्लेटफ़ॉर्म API इसके रनटाइम में एक साझा इंटरफ़ेस प्रदान करते हैं। fetch ब्राउज़र और सर्वर को जोड़ता है, जबकि वही Request=/=Response मॉडल नामित, स्टेटफुल (stateful) एक्टर्स तक भी पहुँचता है। महत्वपूर्ण बदलाव यह है कि एक अनुरोध—या पूरी प्रक्रिया—के समाप्त होने के बाद होस्ट क्या रिकवर कर सकता है।

एक ऐसे वर्कफ़्लो पर विचार करें जो इनपुट फ़ेच करता है, AI सेवा को कॉल करता है, मानवीय स्वीकृति के लिए घंटों प्रतीक्षा करता है, और फिर परिणाम प्रकाशित करता है। इसका जीवनकाल किसी भी एक HTTP अनुरोध या सर्वर प्रक्रिया से अधिक होता है। JavaScript रनटाइम और वेब API एक परिचित प्रोग्रामिंग मॉडल प्रदान करते हैं; टिकाऊपन (durability) उस काम को उस निष्पादन से अधिक समय तक जीवित रहने देता है जिसने इसे शुरू किया था।1

रनटाइम और वेब प्लेटफ़ॉर्म API

एक इंजन JavaScript निष्पादित करता है; एक रनटाइम I/O जोड़ता है। साझा वेब API कोर: fetch, Request, Response, Headers, स्ट्रीम्स, URL और वेब क्रिप्टो।

रनटाइम सामान्य वातावरण वेब API समर्थन
ब्राउज़र क्लाइंट कोर + DOM
Node.js सर्वर / क्लाउड VM कोर; HTTP सर्वर एडेप्टर
Deno सर्वर / क्लाउड VM कोर; Deno.serve
Bun सर्वर / क्लाउड VM कोर; Bun.serve
QuickJS एम्बेडेड इंजन होस्ट द्वारा प्रदान किए गए वेब API
workerd Cloudflare / स्व-होस्टेड वर्कर सबसेट; fetch हैंडलर
celld स्व-होस्टेड फ्लीट वर्कर्स-संगत सबसेट

समर्थन रनटाइम/संस्करण के अनुसार भिन्न होता है; DOM, CORS, कुकीज़ और स्ट्रीमिंग समान नहीं हैं। क्लाइंट: fetch(request) -> Promise. सर्वर: handler(Request) -> Response | Promise; स्टार्टअप API भिन्न होते हैं।

यह सामान्य सीमा वह जगह है जहाँ टुकड़े जुड़ते हैं: एक fetch कॉल एक टिकाऊ वर्कफ़्लो चरण के अंदर बैठ सकता है, एक Request को एक नामित स्टेटफुल ऑब्जेक्ट पर रूट किया जा सकता है, और एक होस्ट प्रोग्राम को तब निलंबित (suspend) कर सकता है जब बाहरी काम पूरा हो रहा हो। HTTP इंटरफ़ेस परिचित रहता है जबकि होस्ट पर्सिस्टेंस, शेड्यूलिंग और रिकवरी जोड़ता है—इसलिए नहीं कि Fetch स्वयं टिकाऊ है, बल्कि इसलिए कि टिकाऊपन इसके चारों ओर बनाया जा सकता है।

Deno की टीम ने अक्टूबर 2026 में एक साल के बग/सुरक्षा सुधारों की घोषणा की, और फिर अपने रनटाइम विकास को समाप्त कर दिया; Deno ओपन सोर्स बना हुआ है।

टिकाऊ निष्पादन (Durable execution)

  • वर्कफ़्लो: चरण परिणामों को पर्सिस्ट करें; रुकावट के बाद, रीप्ले पूर्ण किए गए चरणों का पुन: उपयोग करता है और अधूरे काम को फिर से प्रयास करता है। बाहरी प्रभावों को आइडम्पोटेंट (idempotent) बनाएं।
  • dquickts: सेफ़पॉइंट्स पर JS हीप और निलंबित स्टैक का स्नैपशॉट लें; उसी इंजन बिल्ड का उपयोग करके दूसरी प्रक्रिया में पुनर्स्थापित और फिर से शुरू करें। होस्ट I/O अलग है।

dquickts: केवल चरण परिणाम ही नहीं, चल रहे प्रोग्राम को सहेजें

QuickJS एक्सटेंशन रुकावट और फिर से शुरू करने का एक गहरा रूप प्रदर्शित करता है: एक होस्ट JavaScript को लूप के बीच में भी रोक सकता है, रनटाइम हीप और निलंबित कॉल स्टैक को क्रमबद्ध (serialize) कर सकता है, और उस स्नैपशॉट को डिस्क पर लिख सकता है। ऑब्जेक्ट्स, क्लोजर, स्थानीय चर, लंबित प्रॉमिस जॉब्स और सहेजी गई निर्देश स्थिति रिकवरेबल निष्पादन स्थिति का हिस्सा हैं।2

मूल होस्ट प्रक्रिया तब बाहर निकल सकती है। एक नई प्रक्रिया स्नैपशॉट को एक संगत इंजन बिल्ड में लोड करती है और प्रोग्राम को सहेजे गए निर्देश पर फिर से शुरू करती है, न कि अपनी प्रगति को पुनर्गठित करने के लिए वर्कफ़्लो को फिर से चलाती है। यह मूल प्रक्रिया को रेजिडेंट रखे बिना हाइबरनेशन और लंबी प्रतीक्षा को संभव बनाता है।

वर्कफ़्लो I/O से संबंध समान रूप से महत्वपूर्ण है: JS_SuspendCall() एक होस्ट कॉल को पार्क कर सकता है, और JS_ResumeWith() रनटाइम को पुनर्स्थापित करने के बाद इसका परिणाम प्रदान कर सकता है। प्रोजेक्ट का उदाहरण इस सीमा को स्पष्ट करने के लिए एक फ़ेच-जैसे होस्ट फ़ंक्शन का उपयोग करता है; यह मानक Fetch API का इन-बिल्ट कार्यान्वयन नहीं है। होस्ट अभी भी बाहरी I/O और बार-बार होने वाले साइड इफेक्ट्स के सुरक्षित प्रबंधन का मालिक है।3

%%{init: {"themeVariables": {"fontSize": "18px"}, "flowchart": {"htmlLabels": false, "curve": "linear", "nodeSpacing": 24, "rankSpacing": 32}}}%%
flowchart TB
  subgraph WF["वर्कफ़्लो"]
    direction TB
    W1["एक चरण चलाएं"] --> W2[("चरण परिणाम पर्सिस्ट करें")]
    W2 -->|"प्रक्रिया पुनरारंभ"| W3["वर्कफ़्लो रीप्ले करें
सहेजे गए परिणामों का पुन: उपयोग करें"]
end subgraph JS["dquickts"] direction TB R1["लूप के अंदर निलंबित करें"] --> R2[("हीप + स्टैक स्नैपशॉट
डिस्क पर लिखा गया")]
R2 -->|"नई प्रक्रिया"| R3["पुनर्स्थापित + फिर से शुरू करें
सहेजा गया निर्देश"]
end classDef running fill:#f8fafc,stroke:#64748b,color:#0f172a classDef saved fill:#eff6ff,stroke:#2563eb,color:#0f172a classDef resumed fill:#ecfdf5,stroke:#059669,color:#0f172a class W1,R1 running class W2,R2 saved class W3,R3 resumed style WF fill:#fff,stroke:#cbd5e1,color:#0f172a style JS fill:#fff,stroke:#cbd5e1,color:#0f172a

Durable Objects

एक नामित, सिंगल-थ्रेडेड एक्टर दृढ़ता से सुसंगत SQLite/KV स्टोरेज का मालिक होता है। Cloudflare workerd के वेब API मॉडल पर वितरित रूटिंग, स्टोरेज, अलार्म और WebSocket हाइबरनेशन को लेयर करता है। fetch HTTP सीम है, न कि स्वयं टिकाऊपन; RPC एक और प्रवेश बिंदु है। पर्सिस्टेड स्थिति निष्कासन (eviction) से बच जाती है; JS कॉल स्टैक नहीं बचते।

वर्कफ़्लो-जैसे वर्कलोड के लिए, ये पूरक बिल्डिंग ब्लॉक्स हैं: एक ऑब्जेक्ट किसी जॉब या एजेंट की स्थिति का मालिक हो सकता है, प्रगति को पर्सिस्ट कर सकता है, और बाद में जारी रखने के लिए एक अलार्म शेड्यूल कर सकता है। Cloudflare का WebSocket हाइबरनेशन क्लाइंट्स को कनेक्ट रख सकता है जबकि ऑब्जेक्ट मेमोरी से बाहर है। यह dquickts की तरह रनिंग स्टैक को पुनर्स्थापित करने के बजाय संग्रहीत स्थिति से एक एक्टर को रिकवर करता है।4

%%{init: {"themeVariables": {"fontSize": "18px"}, "flowchart": {"htmlLabels": false, "curve": "linear", "nodeSpacing": 24, "rankSpacing": 32}}}%%
flowchart TB
  C["ब्राउज़र या सर्वर
fetch(request)"]
W["वर्कर
Request → Response"]
D["Durable Object / cell
नामित फ़ेच हैंडलर"]
S[("निजी SQLite / KV
निष्कासन से बचता है")]
E["वेक-अप इवेंट्स
अलार्म / WebSocket"]
C <-->|"Request / Response"| W W <-->|"Object ID + stub.fetch"| D D <-->|"पढ़ें / लिखें"| S E -.->|जागना| D classDef handler fill:#f8fafc,stroke:#64748b,color:#0f172a classDef actor fill:#ecfdf5,stroke:#059669,color:#0f172a classDef saved fill:#eff6ff,stroke:#2563eb,color:#0f172a class C,W,E handler class D actor class S saved

celld: प्रदाता-तटस्थ परिनियोजन (provider-neutral deployment)

celld आपके इंफ्रास्ट्रक्चर में वर्कर्स/Durable Objects मॉडल लाता है: V8 + प्रति-सेल SQLite + एक साझा ऑब्जेक्ट-स्टोरेज बकेट; संगतता अंतराल लागू होते हैं।

Cloudflare के लिए Deno टीम के कदम के बाद, घोषित योजना celld के वितरित स्व-होस्टिंग कोड और विचारों को workerd में मर्ज करने की है—यह एक पूर्ण एकीकरण नहीं है।

भाषाएं जो JavaScript में कंपाइल होती हैं

भाषा का चुनाव होस्टिंग का चुनाव नहीं होना चाहिए

ClojureScript, ReScript और TypeScript एक अलग प्रोडक्शन VM की आवश्यकता के बजाय JavaScript में कंपाइल होते हैं। उनके इंटरऑप/बाइंडिंग्स fetch, स्ट्रीम्स और अन्य होस्ट API को उजागर करते हैं: भाषा चुनने का मतलब JavaScript के रनटाइम इकोसिस्टम को छोड़ना नहीं है।

ClojureScript के डेटा स्ट्रक्चर या ReScript के प्रकार Request=/=Response सीमा को नहीं बदलते हैं। संगत आउटपुट ब्राउज़र, सर्वर या टिकाऊ होस्ट को लक्षित कर सकते हैं। यह इंटरफ़ेस पोर्टेबिलिटी है, न कि इस बात की गारंटी कि हर बंडल बिना बदले चलता है: उत्सर्जित JS, मॉड्यूल और निर्भरता को होस्ट में फिट होना चाहिए। केवल-DOM कोड और नोड-विशिष्ट लाइब्रेरी प्लेटफ़ॉर्म बाधाएं बनी रहती हैं।

FastTwitch: ClojureScript मैप्स, नेटिव Fetch

FastTwitch HTTP एप्लिकेशन को रिंग-स्टाइल रिक्वेस्ट/रिस्पॉन्स मैप्स और सामान्य हैंडलर फ़ंक्शंस और मिडलवेयर के रूप में व्यक्त करता है। इसके एडेप्टर उन मैप्स को नेटिव Request=/=Response ऑब्जेक्ट्स से जोड़ते हैं; इसके क्लाइंट नेटिव fetch, बॉडी स्ट्रीम्स और रिक्वेस्ट विकल्पों का उपयोग करते हैं। नोड HTTP, Deno.serve और Bun.serve नीचे अलग हैं, लेकिन एप्लिकेशन-फेसिंग हैंडलर अनुबंध सुसंगत रहता है।

व्यावहारिक लाभ: HTTP सीमा को फिर से बनाने के बजाय रनटाइम बदलते समय रूटिंग, प्रमाणीकरण और एप्लिकेशन लॉजिक का पुन: उपयोग करें। रनटाइम-विशिष्ट सुविधाओं के लिए अभी भी मिलान एडेप्टर और परीक्षणों की आवश्यकता होती है। ReScript उन्हीं वेब API से जुड़ सकता है; FastTwitch ClojureScript का उदाहरण है, अन्य भाषाओं के लिए कोई आवश्यकता नहीं है।

FastTwitch Celld: HTTP हैंडलर से नामित, स्टेटफुल सेल्स तक

एक चैट एप्लिकेशन पर विचार करें: एक सर्वर प्रक्रिया के अंदर सभी कमरों का समन्वय करने के बजाय प्रत्येक कमरे को अपनी सेल दें। FastTwitch Celld ClojureScript सेल घोषणाएं, HTTP/RPC प्रवेश बिंदु, स्टोरेज, अलार्म और WebSocket बाइंडिंग्स जोड़ता है। HTTP अभी भी Fetch मॉडल का उपयोग करता है; प्लेटफ़ॉर्म प्रत्येक कमरे को उसके नामित सेल पर रूट करता है, और एप्लिकेशन कोड उस सेल के SQLite/KV स्टोरेज में संदेश इतिहास को पर्सिस्ट करता है।

निष्कासन या पुनरारंभ के बाद, एक नया सक्रियण उस संग्रहीत इतिहास से कमरे को पुनर्गठित कर सकता है। एक सामान्य ClojureScript atom स्वचालित रूप से टिकाऊ नहीं होता है; न ही कॉल स्टैक होता है। यह Durable Objects-शैली की स्थिति रिकवरी है, न कि dquickts-शैली का निष्पादन स्नैपशॉट। एक्सटेंशन अभी रिलीज़ के लिए तैयार नहीं है।

%%{init: {"themeVariables": {"fontSize": "18px"}, "flowchart": {"htmlLabels": false, "curve": "linear", "nodeSpacing": 24, "rankSpacing": 32}}}%%
flowchart TB
  H["ClojureScript एप्लिकेशन
हैंडलर्स + मिडलवेयर"]
F["FastTwitch
नेटिव Fetch एडेप्टर"]
N["Node · Deno · Bun
HTTP एप्लिकेशन"]
X["FastTwitch Celld
सेल प्रवेश बिंदु"]
C["सेल: room-42
HTTP · RPC · इवेंट्स"]
S[("निजी SQLite / KV
संदेश इतिहास")]
H --> F F --> N F -->|विस्तार| X X --> C C <-->|"पर्सिस्ट / पुनर्स्थापित"| S classDef application fill:#f8fafc,stroke:#64748b,color:#0f172a classDef bridge fill:#eff6ff,stroke:#2563eb,color:#0f172a classDef durable fill:#ecfdf5,stroke:#059669,color:#0f172a class H,N application class F,X bridge class C,S durable

थ्रू-लाइन: साझा रनटाइम और वेब API इसे एक सामान्य एप्लिकेशन मॉडल बनाते हैं, न कि हर भाषा या होस्ट के लिए एक अलग नेटवर्किंग स्टैक। वर्कफ़्लो जर्नल पूर्ण किए गए काम को संरक्षित करते हैं, रनटाइम स्नैपशॉट निष्पादन स्थिति को संरक्षित करते हैं, और टिकाऊ ऑब्जेक्ट्स एक एड्रेसेबल यूनिट के डेटा और जीवनचक्र को संरक्षित करते हैं। ये आधुनिक वर्कलोड को एक एकल अनुरोध या प्रक्रिया से परे जीवित रहने देने के विभिन्न तरीके हैं।