کافی شاپ کے WiFi پر دو گیگا بائٹ کی ویڈیو اپ لوڈ کرنا محض ایک امید کا نام ہے۔ آپ پروگریس بار کو ستر فیصد کی طرف بڑھتے ہوئے دیکھتے ہیں، اور پھر کنکشن ٹمٹمانے لگتا ہے۔ اپ لوڈ فیل ہو جاتا ہے۔ جب آپ دوبارہ کوشش کرتے ہیں، تو سرور ایک بالکل نئی فائل کی توقع کرتا ہے۔ آپ کو صفر سے شروع کرنا پڑتا ہے۔ جو کوئی بھی ایسی ایپلی کیشن بنا رہا ہے جو صارف کے تیار کردہ (user-generated) ویڈیوز کو سنبھالتی ہے، اس کے لیے یہ کوئی غیر معمولی صورتحال نہیں بلکہ ایک معمول کی بات ہے۔ tus پروٹوکول کو خاص طور پر اس مسئلے کو ختم کرنے کے لیے بنایا گیا تھا۔ یہ ایک اوپن اسٹینڈرڈ ہے جو عام HTTP پر چلتا ہے اور اپ لوڈز کو ایک "یادداشت" (memory) فراہم کرتا ہے۔ جب نیٹ ورک بحال ہوتا ہے، تو فائل ٹرانسفر بالکل وہیں سے شروع ہو جاتا ہے جہاں سے وہ رکا تھا۔

عام اپ لوڈز کیوں ناکام ہو جاتے ہیں

اسٹینڈرڈ ملٹی پارٹ (multipart) فائل اپ لوڈز پورے پے لوڈ (payload) کو ایک ہی ٹرانزیکشن کے طور پر لیتے ہیں۔ براؤزر یا ایپ ایک TCP کنکشن کھولتی ہے، بائٹس (bytes) کو اسٹریم کرتی ہے، اور آخر میں 200 OK کی توقع کرتی ہے۔ اگر صارف LTE سے WiFi پر منتقل ہونے کی وجہ سے، یا لیپ ٹاپ سلیپ موڈ میں جانے کی وجہ سے کنکشن ری سیٹ ہو جاتا ہے، تو سرور کے پاس یہ جاننے کا کوئی طریقہ نہیں ہوتا کہ کون سے بائٹس بحفاظت پہنچ چکے ہیں۔ زیادہ تر فریم ورکس محض ادھورے ڈیٹا کو ضائع کر دیتے ہیں۔ صارف کے پاس صرف ایک فیل فارم اور برا موڈ رہ جاتا ہے۔ ویڈیو فائلیں اس تکلیف کو مزید بڑھا دیتی ہیں کیونکہ وہ بڑی ہوتی ہیں، اکثر غیر مستحکم نیٹ ورکس پر موبائل ڈیوائسز سے اپ لوڈ کی جاتی ہیں، اور اکثر ایسے فارمیٹس میں انکوڈ ہوتی ہیں جنہیں فائل کے مکمل ہونے تک پراسیس نہیں کیا جا سکتا۔

Tus گیم کو کیسے بدلتا ہے

tus اپ لوڈ کو ایک بار کی ڈیلیوری کے بجائے ایک stateful گفتگو کے طور پر دوبارہ سوچتا ہے۔ فائل کو بائٹس کے ایک مسلسل سلسلے میں بھیجنے کے بجائے، کلائنٹ پے لوڈ کو ٹکڑوں (chunks) میں تقسیم کر دیتا ہے۔ اس سے بھی اہم بات یہ ہے کہ سرور offset کو یاد رکھتا ہے، یعنی ان بائٹس کی صحیح تعداد جو اسے اب تک موصول ہو چکی ہیں۔ یہی state persistence دوبارہ شروع کرنے (resumption) کو ممکن بناتی ہے۔ یہ پروٹوکول جان بوجھ کر سادہ رکھا گیا ہے۔ اسے WebSockets، gRPC، یا کسی مخصوص (proprietary) SDKs کی ضرورت نہیں ہے۔ یہ ان HTTP میتھڈز کا استعمال کرتا ہے جنہیں آپ پہلے سے جانتے ہیں۔

وہ تین ریکویسٹس جو دوبارہ شروع کرنے کی طاقت فراہم کرتی ہیں

ہر tus اپ لوڈ ایک قابلِ پیش گوئی عمل پر عمل کرتا ہے۔

سب سے پہلے، کلائنٹ ایک معلوم tus اینڈ پوائنٹ پر POST ریکویسٹ بھیجتا ہے۔ ہیڈرز فائل کی تفصیل بتاتے ہیں۔ Upload-Length ہیڈر بائٹس میں حتمی سائز بتاتا ہے، اور اختیاری میٹا ڈیٹا جیسے کہ فائل کا نام یا کنٹینٹ ٹائپ، Upload-Metadata ہیڈر میں base64-encoded key-value جوڑوں کی ایک کومہ سے الگ شدہ فہرست کے طور پر منتقل ہوتا ہے۔ سرور ایک خالی اپ لوڈ ریسورس بناتا ہے اور 201 Created اسٹیٹس کے ساتھ جواب دیتا ہے، جس میں ایک Location ہیڈر بھی ہوتا ہے جو ایک منفرد URL کی طرف اشارہ کرتا ہے۔ یہ URL اپ لوڈ کی باقی زندگی کے لیے اس کا پتہ (address) ہوتا ہے۔

اس کے بعد PATCH ریکویسٹ آتی ہے۔ کلائنٹ اس منفرد URL پر خام (raw) بائنری ڈیٹا کے ٹکڑے (chunks) بھیجتا ہے۔ پے لوڈ کے ساتھ دو اہم ہیڈرز بھیجے جاتے ہیں۔ Content-Type کا application/offset+octet-stream ہونا ضروری ہے، اور Upload-Offset اس بائٹ پوزیشن سے میل کھانا چاہیے جہاں سے یہ ٹکڑا شروع ہوتا ہے۔ سرور تصدیق کرتا ہے کہ کیا offset اس کے اپنے ریکارڈ سے مطابقت رکھتا ہے۔ اگر ایسا نہیں ہے، تو سرور 409 Conflict واپس کرتا ہے، تاکہ خراب حالت (corrupted state) سے بچا جا سکے۔ اگر سب کچھ درست ہو، تو سرور بائٹس کو شامل کر دیتا ہے، اپنے اندرونی offset کو اپ ڈیٹ کرتا ہے، اور نئے Upload-Offset کے ساتھ 204 No Content کا جواب دیتا ہے۔ ٹکڑے (chunk) کا سائز تبدیل کیا جا سکتا ہے، لیکن عام طور پر یہ چند سو کلو بائٹس سے لے کر چند میگا بائٹس کے درمیان ہوتا ہے۔ چھوٹے ٹکڑے زیادہ HTTP اوور ہیڈ (overhead) پیدا کرتے ہیں لیکن غلطیوں سے تیزی سے ریکور ہوتے ہیں۔ بڑے ٹکڑے راؤنڈ ٹرپس (round trips) کو کم کرتے ہیں لیکن اگر وہ درمیان میں فیل ہو جائیں تو زیادہ بینڈوڈتھ ضائع کرتے ہیں۔

آخر میں، HEAD ریکویسٹ آتی ہے۔ یہ ایک حفاظتی جال (safety net) ہے۔ اگر ایک PATCH کسی ٹکڑے کے درمیان میں فیل ہو جائے، مثال کے طور پر پانچ میگا بائٹ کے حصے میں سے تین میگا بائٹ کے بعد، تو کنکشن ٹوٹ جاتا ہے۔ جب کلائنٹ کو نیٹ ورک تک رسائی دوبارہ حاصل ہوتی ہے، تو وہ اپ لوڈ URL پر HEAD ریکویسٹ بھیجتا ہے۔ سرور موجودہ Upload-Offset کے ساتھ جواب دیتا ہے۔ کلائنٹ موازنہ کرتا ہے