ہر کوئی ریئل ٹائم اپ ڈیٹس چاہتا ہے جب تک کہ انہیں یہ احساس نہ ہو جائے کہ "تیز" اور "درست" ایک ہی چیز نہیں ہیں۔ ایک ڈسٹری بیوٹڈ سسٹم میں، واقعات روشنی کی رفتار سے سفر کر سکتے ہیں لیکن پھر بھی غلط ترتیب میں پہنچ سکتے ہیں۔ WebSockets ڈراپ ہو کر دوبارہ کنیکٹ ہوتے ہیں۔ Message brokers پیکٹس کو دوبارہ بھیجتے ہیں۔ Background workers ٹائم آؤٹ کینسلریشن کے خلاف دوڑ لگاتے ہیں۔ نتیجہ؟ ایک کلائنٹ ایونٹ 42 دیکھ سکتا ہے، پھر ایونٹ 40، اور پھر ایک اسنیپ شاٹ جو دعویٰ کرتا ہے کہ سسٹم پہلے ہی ایونٹ 45 پر پہنچ چکا ہے۔ اگر آپ طویل مدتی ایجنٹ ورک فلو بنا رہے ہیں، تو یہ افراتفری کوئی غیر معمولی صورتحال (edge case) نہیں ہے۔ یہ ایک بنیادی حقیقت ہے۔ ڈیلیوری کے وقت سے ملی سیکنڈز بچانے کی فکر کرنے سے پہلے اپنے واقعات (events) کی ترتیب درست کریں۔
"ریئل ٹائم" کی الجھی ہوئی حقیقت
ریئل ٹائم ایک ٹرانسپورٹ پراپرٹی ہے۔ یہ اس بات کی وضاحت کرتا ہے کہ ایک پیکٹ تار کے ذریعے کتنی تیزی سے حرکت کرتا ہے، نہ کہ اس بات کی کہ اس کے ذریعے بتائی گئی کہانی بامعنی ہے یا نہیں۔ طویل مدتی کام ہر قسم کے تضاد کو بڑھا دیتے ہیں کیونکہ وہ وقت کے ایک طویل عرصے تک پھیلے ہوتے ہیں۔ ایک ماڈل ٹریننگ جاب، کثیر مرحلہ وار منظوری کا عمل، یا ویڈیو رینڈرنگ پائپ لائن منٹوں یا گھنٹوں کے دوران درجنوں ایونٹس جاری کر سکتی ہے۔ اس دوران، کچھ بھی غلط ہو سکتا ہے۔
ایک بروکر کسی پیغام کو دوبارہ بھیج سکتا ہے کیونکہ ایکنولیجمنٹ (acknowledgement) گم ہو گئی ہو۔ ایک لوڈ بیلنسر دو ایونٹس کو مختلف نیٹ ورک راستوں سے بھیج سکتا ہے، جس سے نیا ایونٹ پہلے پہنچ جاتا ہے۔ ایک ورکر پراسیس ڈیٹا بیس میں لکھنے کے بعد لیکن کامیابی کا ایونٹ شائع کرنے سے پہلے ختم ہو سکتا ہے، اور پھر دوسرا ورکر اس کام کو سنبھال کر اپنا پروگریس ایونٹ جاری کر سکتا ہے۔ اگر آپ کا فرنٹ اینڈ یہ فرض کرتا ہے کہ تازہ ترین پیغام ہی سب سے سچا پیغام ہے، تو وہ ایک ایسی حالت (state) دکھائے گا جو کبھی موجود ہی نہیں تھی۔ صارفین دیکھیں گے کہ "مکمل" (completed) کا بیج اچانک "پروسیسنگ" (processing) پر واپس آ گیا ہے، یا اس سے بھی بدتر، ایک منسوخ شدہ کام اچانک دوبارہ زندہ ہو گیا ہے۔ ترتیب کے بغیر رفتار محض زیادہ فریم ریٹ پر ہونے والی الجھن ہے۔
سیکوئنس نمبرز ہی اصل گھڑی ہیں
اس کا حل پروڈیوسر کے ذریعے تیار کردہ سخت، مونوٹونک سیکوئنس نمبرز ہیں۔ ہر وہ آپریشن جو اسٹیٹ کو تبدیل کرتا ہے اسے ایک ایسا نمبر ملتا ہے جو بالکل ایک سے بڑھتا ہے، بغیر کسی وقفے اور بغیر کسی واپسی (rollback) کے۔ وہ نمبر اسی ٹرانزیکشن میں محفوظ ہونا چاہیے جس میں ایونٹ خود موجود ہے۔ اگر ڈیٹا بیس کی رو (row) اپ ڈیٹ ہوتی ہے لیکن سیکوئنس کمٹ (commit) فیل ہو جاتا ہے، تو آپ دونوں کو واپس (roll back) کر دیتے ہیں۔ یہ منطقی ٹائم لائن کو اسٹیٹ کی تبدیلی کے ساتھ ایٹامک رکھتا ہے۔
ایونٹ آئی ڈیز اب بھی مفید ہیں، لیکن وہ ایک مختلف مسئلہ حل کرتی ہیں۔ ایک ایونٹ آئی ڈی ایک مخصوص پے لوڈ کی شناخت کرتی ہے تاکہ جب بروکر ایک ہی پیغام دو بار بھیجے تو آپ اسے ڈی ڈپلیکیٹ کر سکیں۔ دوسری طرف، ایک سیکوئنس نمبر آپ کو بتاتا ہے کہ وہ پے لوڈ وجہ کے سلسلے (causal chain) میں کہاں واقع ہے۔ یہ وقفوں کو ظاہر کرتا ہے۔ یہ ترتیب کو ظاہر کرتا ہے۔ ٹائم اسٹیمپ ان میں سے کچھ نہیں کرتا۔ گھڑیاں آگے پیچھے ہو جاتی ہیں، NTP پیچھے چلا جاتا ہے، اور ورچوئل مشینز رک جاتی ہیں۔ ٹائم اسٹیمپ کو صرف ڈسپلے کے مقاصد کے لیے استعمال کریں، جیسے کہ "3 منٹ پہلے شروع ہوا،" اور اسے بزنس لاجک کے لیے ترتیب دینے والی کلید (sorting key) کے طور پر کبھی استعمال نہ کریں۔
کلائنٹ کو اسٹریم کو کیسے سنبھالنا چاہیے
ایک بار جب پروڈیوسر مونوٹونک سیکوئنس کی ضمانت دے دیتا ہے، تو کنزیومر کے لیے سادہ اور سخت اصول بن جاتے ہیں۔ اگر ان باؤنڈ سیکوئنس نمبر پچھلے لاگو شدہ نمبر کے برابر یا اس سے کم ہے، تو اسے چھوڑ دیں۔ یہ یا تو ایک ڈپلیکیٹ ہے یا ایک پرانا لیٹ کمر۔ اگر سیکوئنس پچھلے لاگو شدہ نمبر سے بالکل ایک زیادہ ہے، تو اسے فوری طور پر لاگو کریں۔ یہ خوشگوار راستہ (happy path) ہے۔ اگر سیکوئنس آگے چھلانگ لگاتا ہے، مثال کے طور پر آپ 12 کی توقع کر رہے تھے لیکن 15 موصول ہوا، تو کچھ غائب ہے۔ نئے ایونٹ کو بفر کریں اور سرور سے اگلے متوقع سیکوئنس سے شروع ہونے والی ری پلے (replay) کا مطالبہ کریں۔ اندازہ نہ لگائیں۔ یہ امید کرتے ہوئے آگے نہ بڑھیں کہ وقفہ اہمیت نہیں رکھتا۔
ٹرمینل اسٹیٹس (Terminal states) کو ناقابل واپسی سمجھا جانا چاہیے۔ ایک بار جب کسی کام کو مکمل (completed)، ناکام (failed)، یا منسوخ (cancelled) قرار دے دیا جائے، تو کلائنٹ کو اس آپریشن کے لیے کسی بھی بعد کی اسٹیٹ تبدیلیوں کو مسترد کر دینا چاہیے۔ یہ تب تک بظاہر سادہ لگتا ہے جب تک آپ کا سامنا
