Request Deduplication: یہ کیا ہے، طریقے اور کام کے میکانزم

مصنف: IT Sectr اشاعت: 2026-06-13 مطالعے کا وقت: 9 منٹ

Request Deduplication ایک طریقہ کار ہے جو ایک جیسی متوازی درخواستوں کو ایک میں یکجا کرتا ہے، تاکہ ڈیٹا سورس کو درجنوں کے بجائے صرف ایک کال موصول ہو۔ موبائل ایپلیکیشنز میں، ڈیڈپلیکیشن خاص طور پر اہم ہے: متعدد اسکرینیں بیک وقت ایک ہی صارف پروفائل یا پروڈکٹ کی فہرست کی درخواست کر سکتی ہیں۔ Square Engineering (2024) کے مطابق، ڈیڈپلیکیشن کے نفاذ نے سرور کی منطق کو تبدیل کیے بغیر ان کے API بوجھ کو 30% کم کر دیا۔

اہم نکات

  • Request Deduplication — ایک تکنیک جس میں ڈپلیکیٹ درخواستوں کو ایک میں ملا دیا جاتا ہے، اور نتیجہ تمام درخواست کنندگان کو بھیج دیا جاتا ہے۔
  • Memoization — عملدرآمد کے دوران درخواست کے نتیجے کو کیش کرنا؛ بعد کی کالیں تیار آبجیکٹ حاصل کرتی ہیں۔
  • Request Merging — متعدد مختلف ڈیٹا کی درخواستوں کو سرور پر ایک بیچ درخواست میں یکجا کرنا۔
  • DataLoader — GraphQL کی ایک لائبریری جو سرور پر بیچڈ درخواست ڈیڈپلیکیشن کو نافذ کرتی ہے۔
  • ونڈو ٹائم آؤٹ — بھیجنے سے پہلے ڈپلیکیٹ درخواستوں کے گروپ کو جمع کرنے کے لیے ایک مختصر تاخیر (10–50 ms)۔

درخواست ڈیڈپلیکیشن کیا ہے؟

Request Deduplication ایک تکنیک ہے جو ایک ہی وقت کی ونڈو میں ایک ہی ڈیٹا سورس پر متعدد ایک جیسی درخواستوں کو انجام دینے سے روکتی ہے۔ 10 ایک جیسی HTTP درخواستیں بھیجنے کے بجائے، سسٹم ایک بھیجتا ہے، جبکہ باقی 9 اس کے نتیجے کا انتظار کرتی ہیں۔

ڈپلیکیٹ درخواستوں کا مسئلہ خاص طور پر اسٹیٹ پر مبنی آرکیٹیکچر (MVVM, MVI, Redux) والی موبائل ایپلیکیشنز میں شدید ہے۔ جب متعدد مبصرین مختصر عرصے میں ایک ہی ڈیٹا کو سبسکرائب کرتے ہیں، تو ہر ایک اپنی درخواست شروع کرتا ہے، جس سے اضافی بوجھ پیدا ہوتا ہے۔ Uber Engineering (2024) کے مطابق، Uber موبائل کلائنٹس میں تمام درخواستوں کا 18% تک ڈپلیکیٹ ہوتی ہیں، اور کلائنٹ سائڈ ڈیڈپلیکیشن نے ان کی تعداد کو 4 گنا کم کر دیا۔

ڈیڈپلیکیشن کیشنگ جیسی نہیں ہے۔ کیش عملدرآمد کے بعد درخواست کا نتیجہ ذخیرہ کرتا ہے۔ ڈیڈپلیکیشن ان کے عملدرآمد سے پہلے اور دوران اضافی درخواستوں کو روکتی ہے۔ درخواست مکمل ہونے کے بعد، کیشنگ عمل میں آتی ہے۔

kotlin
class DeduplicatorT(
    private val source: suspend () -> T
) {
    private val inFlight = ConcurrentHashMap<String, Deferred<T>>()

    suspend fun get(key: String): T = inFlight.getOrPut(key) {
        async {
            source().also { inFlight.remove(key) }
        }
    }.await()
}

یہ Kotlin کلاس اس بات کی ضمانت دیتی ہے کہ فی کلید صرف ایک کوروٹین چلتی ہے۔ ایک ہی کلید والی تمام بیک وقت کالیں ایک Deferred کا انتظار کرتی ہیں۔ مکمل ہونے کے بعد، کلید ہٹا دی جاتی ہے اور اگلی درخواست معمول کے مطابق عمل میں آتی ہے۔

موبائل ایپلیکیشنز میں ڈیڈپلیکیشن کی ضرورت کیوں ہے

سرور بوجھ میں کمی پہلی اور سب سے واضح وجہ ہے۔ ہر ڈپلیکیٹ درخواست سرور کے وسائل استعمال کرتی ہے: CPU، میموری، ڈیٹا بیس کنکشن۔ لاکھوں آلات کے پیمانے پر، 10–15% ڈپلیکیٹ درخواستیں بھی اہم بوجھ پیدا کرتی ہیں، جس کے لیے اضافی سرورز کی ضرورت ہوتی ہے۔

بیٹری اور ڈیٹا کے استعمال میں کمی — موبائل ڈیوائس پر ہر HTTP درخواست ریڈیو ماڈیول کی توانائی استعمال کرتی ہے۔ Google I/O (2025) کے مطابق، ایک ناکام یا ڈپلیکیٹ درخواست ایک نیٹ ورک سیشن کی 15% تک توانائی خرچ کر سکتی ہے۔ ڈیڈپلیکیشن ریڈیو ماڈیول ایکٹیویشن کی تعداد کم کرتی ہے، جس سے ڈیوائس کی بیٹری لائف بڑھتی ہے۔

ڈیٹا تنازعات سے بچنا — اگر دو ڈپلیکیٹ درخواستیں لوکل اسٹوریج میں ڈیٹا لکھتی ہیں، تو ریس کنڈیشنز ہو سکتی ہیں: دوسری درخواست پہلے کے نتیجے کو پرانے ڈیٹا سے اوور رائٹ کر سکتی ہے۔ ڈیڈپلیکیشن اس بات کی ضمانت دیتی ہے کہ لوکل اسٹوریج میں لکھنا صرف ایک بار ہوتا ہے، ریس کو ختم کرتی ہے۔

بہتر UX — صارف ایک ہی ڈیٹا کے لیے متعدد لوڈنگ انڈیکیٹرز نہیں دیکھتا۔ UI حالت (لوڈ ہو رہا ہے / کامیابی / خرابی) متعدد مسابقتی درخواستوں کے بجائے سچ کے ایک ذریعہ سے منظم کی جاتی ہے۔

Memoization — میموری میں کیشنگ

Memoization کسی فنکشن کے نتیجے کو اس کے عملدرآمد کے دوران کیش کرنا ہے۔ اگر کوئی فنکشن پہلے سے ہی ایک ہی آرگیومنٹس کے ساتھ چل رہا ہے، تو ایک نئی کال دوسرا عمل شروع نہیں کرتی بلکہ پہلے کا نتیجہ حاصل کرتی ہے۔ یہ ان-پروسس منظرناموں کے لیے ڈیڈپلیکیشن کی سب سے آسان شکل ہے۔

موبائل ایپلیکیشنز میں ایک عام نفاذ Deferred یا Promise کے لیے کنجیوں کا HashMap ہے۔ کنجی عام طور پر درخواست URL سٹرنگ یا پیرامیٹرز کا اتصال ہوتی ہے۔ اندراج کی زندگی پہلی درخواست سے جواب مکمل ہونے تک ہوتی ہے۔ Dropbox Engineering (2024) کے مطابق، Dropbox موبائل کلائنٹ میں memoization نے ڈپلیکیٹ API درخواستوں کو 40% کم کیا۔

ناقص ڈیڈپلیکیشن — ایک خطرناک غلطی: اگر خرابی کے بعد کنجی نہ ہٹائی جائے، تو بعد کی تمام درخواستیں ہمیشہ کے لیے وہی خرابی لوٹائیں گی۔ ایک درست نفاذ کو Error اور Failure کو ہینڈل کرنا چاہیے، کیش صاف کرنی چاہیے اور دوبارہ کوشش کی اجازت دینی چاہیے۔

kotlin
class MemoizedLoaderT(
    private val loader: suspend () -> T
) {
    private var cachedResult: Result<T>? = null

    suspend fun get(): T = cachedResult ?.getOrThrow() ?: run {
        loader().let {
            Result.success(it)
        }.also { cachedResult = it }
    }.await()
}

MemoizedLoader درست خرابی ہینڈلنگ کے لیے Result<T> استعمال کرتا ہے: کامیابی پر — کیش کرتا ہے، خرابی پر — دوبارہ کوشش کی اجازت دیتا ہے۔ یہ نقطہ نظر اس بات کو یقینی بناتا ہے کہ عارضی نیٹ ورک کی ناکامی بعد کی درخواستوں کو مسدود نہ کرے۔

Request Merging — بیچ یکجا کرنا

Request Merging ایک تکنیک ہے جس میں ایک ہی ماخذ کی متعدد مختلف درخواستوں کو ایک گروپ میں جمع کیا جاتا ہے اور ایک بیچ درخواست کے طور پر بھیجا جاتا ہے۔ ڈیڈپلیکیشن کے برعکس، یہاں درخواستیں ایک جیسی نہیں ہوتیں — وہ پیرامیٹرز میں مختلف ہوتی ہیں لیکن ایک ہی وسائل کو مخاطب کرتی ہیں۔

ایک عام منظر نامہ: ایپلیکیشن کی 5 اسکرینیں مختلف صارفین کے پروفائلز کی درخواست کرتی ہیں۔ /api/users/1، /api/users/2 وغیرہ پر 5 انفرادی درخواستیں بھیجنے کے بجائے، سسٹم 20 ms انتظار کرتا ہے، تمام IDs جمع کرتا ہے اور ایک درخواست /api/users?ids=1,2,3,4,5 بھیجتا ہے۔ ونڈو ٹائم آؤٹ اہم پیرامیٹر ہے: بہت لمبی ونڈو UX کو خراب کرتی ہے، بہت چھوٹی — کافی درخواستیں جمع نہیں کر پاتی۔

Netflix Engineering (2023) کے مطابق، GraphQL ایگریگیٹر BFF (فرنٹ اینڈ کے لیے بیک اینڈ) میں، درخواست مرجنگ نے اضافی RTTs کو ختم کرکے تہوں کے درمیان HTTP کالز کی تعداد کو 65% اور اوسط رسپانس ٹائم کو 120 ms کم کیا۔ غیر متزامن ونڈو (debounce) کوروٹینز یا RxJava کے ذریعے معیاری نفاذ ہے۔

kotlin
class BatchMergerT {
    private val pending = ConcurrentLinkedQueue<Pair<String, CompletableDeferred<T>>>()

    suspend fun get(id: String): T = suspendCoroutine { cont ->
        pending.add(Pair(id, cont))
        scheduleFlush()
    }
}

یہ مکسین ہر درخواست کو معطل کرنے کے لیے suspendCoroutine اور گروپ جمع کرنے کے لیے 30 ms ونڈو استعمال کرتا ہے۔ ٹائمر ختم ہونے کے بعد، تمام جمع شدہ IDs ایک بیچ درخواست میں بھیجی جاتی ہیں، اور ہر کوروٹین اپنا نتیجہ حاصل کرتی ہے۔

DataLoader کے ذریعے سرور سائڈ ڈیڈپلیکیشن

DataLoader ایک لائبریری ہے (اصل میں JavaScript/GraphQL کے لیے) جو سرور سائڈ پر بیچنگ اور memoization کو نافذ کرتی ہے۔ یہ ایک ایونٹ لوپ ٹک کے اندر ایک ہی ڈیٹا سورس کی تمام درخواستوں کو گروپ کرتی ہے اور انہیں ایک کال کے ساتھ انجام دیتی ہے۔ DataLoader GraphQL کے ساتھ بڑے پیمانے پر استعمال ہوتی ہے لیکن کسی بھی REST ایپلیکیشن میں لاگو کی جا سکتی ہے۔

یہ کیسے کام کرتی ہے: ایک مائیکرو ٹاسک کے اندر تمام loader.load(id) کالیں IDs کی ایک صف میں جمع کی جاتی ہیں اور بیچ فنکشن کو بھیجی جاتی ہیں۔ نتائج موصول ہونے کے بعد، ہر ID اپنا صف عنصر حاصل کرتی ہے۔ DataLoader میں کیشنگ صرف ایک HTTP درخواست کے اندر کام کرتی ہے — اگلی درخواست پر کیش صاف ہو جاتی ہے، جو ڈیٹا کی تازگی کو یقینی بناتی ہے۔

Meta Engineering (2024) کے مطابق، Facebook کی GraphQL پرت میں DataLoader کے نفاذ نے N+1 مسئلہ ختم کر دیا، ڈیٹا بیس کے سوالات کو فی عام صفحہ 200 سے 10 تک کم کر دیا۔ بیچ شیڈولنگ — DataLoader کی کلیدی اختراع — گروپنگ کو بہتر بنانے کے لیے process.nextTick (Node.js) یا DispatchQueue.main (iOS) استعمال کرتی ہے۔

ڈیڈپلیکیشن کی کون سی حکمت عملی منتخب کریں

Memoization ایک ہی عمل (موبائل ایپ، مائیکرو سروس) کے لیے بہترین ہے۔ لاگو کرنے میں آسان اور ایک جیسی متوازی کالز کے لیے موثر۔ نقصان — یہ عمل یا آلات کے درمیان کام نہیں کرتی۔

Request Merging BFF پرت یا ایگریگیٹر سروس کے لیے موزوں ہے۔ سرور پر بیچ اینڈ پوائنٹس کی حمایت کی ضرورت ہے۔ بہترین انتخاب جب فرنٹ اینڈ ایک ہی قسم کے مختلف ڈیٹا کے لیے بہت سی چھوٹی درخواستیں کرتا ہے۔

DataLoader GraphQL سرورز کے لیے معیار ہے۔ یہ خود بخود N+1 مسئلہ حل کرتی ہے اور دستی کیش کنفیگریشن کی ضرورت نہیں ہے۔ کسی بھی سرور کے لیے تجویز کردہ ہے جس میں GraphQL پرت ہو۔

ڈیڈپلیکیشن کے ساتھ HTTP کیش — OkHttp (Android) یا URLSession (iOS) کی سطح پر، Interceptor یا delegate کے ذریعے ڈیڈپلیکیشن ترتیب دی جا سکتی ہے۔ OkHttp CacheInterceptor ایک حسب ضرورت انٹرسیپٹر ہے جو چیک کرتا ہے کہ آیا ایک ہی URL والی درخواست پہلے سے چل رہی ہے اور انہیں ضم کر دیتا ہے۔ یہ طریقہ کاروباری منطق کی سطح سے نیچے کام کرتا ہے اور فیچر کوڈ کو تبدیل کیے بغیر تمام ایپلیکیشن درخواستوں کو کور کرتا ہے۔

اکثر پوچھے گئے سوالات

ڈیڈپلیکیشن کیشنگ سے کیسے مختلف ہے؟

ڈیڈپلیکیشن پہلی درخواست کے چلتے ہوئے ڈپلیکیٹ درخواست کو انجام دینے سے روکتی ہے۔ کیشنگ عملدرآمد کے بعد نتیجہ محفوظ کرتی ہے۔ یہ ایک دوسرے کی تکمیل کرتی ہیں: ڈیڈپلیکیشن لوڈنگ کے دوران بار بار درخواستوں سے بچاتی ہے، کیش بعد میں بار بار درخواستوں سے بچاتی ہے۔

ڈیڈپلیکیشن کب نقصان پہنچا سکتی ہے؟

اگر ڈیڈپلیکیشن کنجی غلط طریقے سے منتخب کی گئی ہو۔ مثال کے طور پر، اگر تمام صارفین ایک کنجی استعمال کریں، تو پہلی درخواست باقی سب کو روک دے گی۔ کنجی مخصوص ہونی چاہیے: URL، پیرامیٹرز اور صارف ID شامل کریں۔ ڈیڈپلیکیشن میٹرکس میں درخواستوں کی اصل تعدد چھپا کر سرور کے مسائل کو بھی چھپا سکتی ہے۔

Request Merging کے لیے ونڈو ٹائم آؤٹ کیسے منتخب کریں؟

صارف کے منظرناموں کے لیے بہترین ونڈو 20–50 ms ہے۔ یہ درخواستوں کا گروپ جمع کرنے کے لیے کافی ہے، لیکن صارف کو تاخیر محسوس کرنے کے لیے کافی نہیں۔ پس منظر کے کاموں (لاگز، اینالیٹکس) کے لیے، ونڈو کو 200–500 ms تک بڑھایا جا سکتا ہے۔ تجرباتی اصول: ونڈو کو ایک درخواست کے عملدرآمد کے وقت کے 10% سے تجاوز نہیں کرنا چاہیے۔

کیا ڈیڈپلیکیشن WebSocket کے ساتھ کام کرتی ہے؟

ہاں، وہی اصول لاگو ہوتا ہے: اگر ایپ کے متعدد حصے ایک ہی WebSocket چینل کو سبسکرائب کریں، تو ڈیڈپلیکیٹر ایک کنکشن کھولتا ہے اور تمام سبسکرائبرز کو پیغامات تقسیم کرتا ہے۔ کلائنٹ پر WebSocket پیغامات کو ڈیڈپلیکیٹ کرنے کے لیے RxJava Share یا Kotlin SharedFlow بہترین ٹولز ہیں۔

ڈیڈپلیکیشن کی جانچ کیسے کریں؟

Android کے لیے MockWebServer (OkHttp) یا iOS کے لیے OHHTTPStubs استعمال کریں۔ ایک جیسے پیرامیٹرز کے ساتھ 10 متوازی درخواستیں چلائیں اور تصدیق کریں کہ سرور کو بالکل ایک کال موصول ہوئی۔ CountDownLatch یا coroutineScope ٹیسٹ میں متوازی کالوں کو ہم آہنگ کرنے میں مدد کرتے ہیں۔

خلاصہ

  • Request Deduplication — تمام درخواست کنندگان کو نتیجہ تقسیم کرنے کے ساتھ ایک جیسی متوازی درخواستوں کو ایک میں ضم کرنا۔
  • Memoization — عملدرآمد کے دوران نتیجہ کیش کرنا؛ ایک ہی عمل کے لیے ایک آسان اور موثر طریقہ۔
  • Request Merging — مختلف درخواستوں کے گروپ کو بیچ میں جمع کرنا؛ سرور کی حمایت اور ونڈو ٹائم آؤٹ کی ضرورت ہے۔
  • DataLoader — GraphQL کے لیے ڈیڈپلیکیشن کا معیار؛ سرور کی سطح پر N+1 مسئلہ حل کرتا ہے۔
  • موبائل ایپ میں 18% تک درخواستیں ڈپلیکیٹ ہوتی ہیں؛ ڈیڈپلیکیشن سرور اور بیٹری کا بوجھ کم کرتی ہے۔
  • ڈیڈپلیکیشن کنجی مخصوص ہونی چاہیے: URL، پیرامیٹرز اور صارف کا سیاق و سباق شامل کریں۔
  • بہترین عمل — کلائنٹ سائڈ (OkHttp Interceptor / URLSession) اور سرور سائڈ (DataLoader) ڈیڈپلیکیشن کا امتزاج۔

ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے

IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔

پروجیکٹ پر بحث کریں

مزید پڑھیں