اس صفحہ پر
AI Engineer کی جانب سے 3 اکتوبر 2026 کو شائع ہونے والی ایک گفتگو میں، Crusoe کے ایک ڈیولپر ایڈووکیٹ نے دو A100 نوڈز پر PyTorch کی ایک ٹریننگ جاب شروع کی۔ پھر انہوں نے ڈیمو کے اپنے مانیٹرنگ سسٹم کو بتایا کہ ایک GPU نے XID 79 کی غلطی دی ہے۔ نوڈ کو بند نشان زد کیا گیا اور جاب منسوخ ہو گئی۔ پروسیس کو SIGTERM ملا اور اس کے پاس “اس SIGTERM کو سنبھالنے کے لیے دو منٹ تک کا وقت تھا، تاکہ یا تو آپ اپنے چیک پوائنٹس محفوظ کر لیں یا اپنے لاگز فلش کر دیں”۔ ایک فالتو نوڈ آیا، اور “slurm جاب دوبارہ شروع ہوگی۔ یہ چیک پوائنٹ لوڈ کرے گی اور ٹریننگ وہیں سے جاری رکھے گی جہاں چھوڑی تھی”۔ شروع سے آخر تک پندرہ منٹ سے کچھ کم۔ کسی کو پیج نہیں کیا گیا۔
سنک ٹریننگ رن کے مقابلے میں کہیں چھوٹا جانور ہے۔ سوال وہی ہے۔ ایک رن کو کیا چاہیے تاکہ ورکر کے بند ہونے کی قیمت چند منٹ ہو اور کوئی ڈپلیکیٹ نہ ہو؟
یہ Tajo کے اپنے سنک رنر کا جواب ہے، جو کسی بروشر سے نہیں بلکہ کوڈ سے پڑھا گیا ہے۔ Reverse ETL کام کی شکل بیان کرتا ہے۔ یہ وہ ہے جو تب ہوتا ہے جب کام رک جائے۔
ایک کانٹیکٹ کا پیچھا کیجیے
ایک رن محفوظ کیے گئے کرسر سے شروع کر کے سورس کو ایک وقت میں ایک صفحہ پڑھتا ہے۔ صفحے کے کرسر کو c3 کہیے اور ہمارے کانٹیکٹ کو اس صفحے کا 212واں ریکارڈ۔ کچھ بھی لکھے جانے سے پہلے اس کانٹیکٹ کے بارے میں تین باتیں درست ہیں۔
پہلی، اس کی ایک ڈیلیوری کلید ہے۔ یہ کلید سنک کی آئی ڈی، سورس، صفحے کے کرسر، صفحے پر جگہ اور خود ریکارڈ کا hash ہے۔ کرسر اور ریکارڈ hash میں جاتے ہیں اور کبھی کلید کے اندر شامل نہیں کیے جاتے، اس لیے کلید میں کوئی ای میل ایڈریس نہیں ہوتا۔
دوسری، تحریر سیدھی منزل پر نہیں جاتی بلکہ ایک لیجر سے گزرتی ہے۔ منزل کو کال کرنے سے پہلے کلید کو زیرِ التوا کے طور پر حاصل کیا جاتا ہے۔ جب تحریر کامیاب ہو جائے تو اندراج کو مکمل نشان زد کیا جاتا ہے اور سات دن تک رکھا جاتا ہے۔
تیسری، کرسر آگے نہیں بڑھا۔ یہ صرف بیچ کے آخر میں آگے بڑھتا ہے، صرف تب جب اس بیچ کا ہر ریکارڈ پہنچ گیا ہو، اور صرف اس کے بعد جب رن ثابت کر دے کہ سنک اب بھی اسی کی ملکیت ہے۔
اب ورکر کو تحریر اور چیک پوائنٹ کے درمیان بند کیجیے۔
SIGTERM پر ہر قطار ورکر ایک مشترکہ پندرہ سیکنڈ کی ڈیڈ لائن کے اندر خالی ہوتا ہے، اور پروسیس پچیس سیکنڈ بعد بند ہو جاتا ہے، چاہے کچھ بھی ابھی چل رہا ہو؛ systemd اسے ختم کرنے سے پہلے پینتالیس سیکنڈ دیتا ہے۔ جو رن اس وقفے میں مکمل نہ ہو، وہ اب بھی جاری نشان زد رہتا ہے، اور اگلا ورکر اسے قطار کی رکی ہوئی جاب کی بحالی کے ذریعے اٹھا لیتا ہے۔ ہارڈ کِل پر خالی کرنے کا کوئی مرحلہ ہوتا ہی نہیں۔ دونوں صورتوں میں وہی دو حقائق قائم رہتے ہیں۔ منزل کے پاس ہمارا کانٹیکٹ ہے۔ ہمارا کرسر اب بھی c3 کہتا ہے۔
ری پلے
اگلا رن c3 سے شروع ہوتا ہے، وہی صفحہ پڑھتا ہے، 212ویں ریکارڈ کے لیے وہی کلید بناتا ہے، اور لیجر سے پوچھتا ہے۔ لیجر کہتا ہے: مکمل۔ منزل کو کال نہیں کیا جاتا؛ محفوظ نتیجہ دوبارہ چلایا جاتا ہے اور رن آگے بڑھ جاتا ہے۔ بلک راستے پر، جہاں Brevo کا امپورٹ اینڈ پوائنٹ ایک ہی کال میں پورا صفحہ لیتا ہے، یہی جانچ درخواست بنانے سے پہلے ہر کلید کے لیے چلتی ہے۔ جس صفحے کی ہر کلید پہلے سے مکمل ہو، وہ کچھ نہیں بھیجتا۔
یہی پوری ترکیب ہے، اور یہ بتانا ضروری ہے کہ یہ کیوں کام کرتی ہے۔ کلید بیچ کے آغاز پر صفحے کے کرسر سے بنتی ہے، اس رن سے نہیں جو اتفاق سے چل رہا تھا۔ کریش، ساٹھ سیکنڈ بعد کی دوبارہ کوشش اور کل کا شیڈول شدہ رن، سب ایک ہی ریکارڈ کے لیے ایک ہی کلید بناتے ہیں۔ لیجر کو پروا نہیں کہ ان میں سے کون پوچھ رہا ہے۔
اب قیمت۔ لیجر سات دن بعد بھول جاتا ہے۔ کوڈ کا اپنا تبصرہ کہتا ہے کہ سات دن ایک تاخیر سے ہونے والی دوبارہ کوشش اور ایک مختصر بندش کا احاطہ کرتے ہیں، اور بس یہی اس کا دعویٰ ہے۔ اس سے پرانے کرسر سے ری پلے دوبارہ لکھتا ہے۔ اور جو رن سختی سے رک جائے، وہ انتظار کر سکتا ہے۔ رکے ہوئے رن کی لیز پندرہ منٹ تک برقرار رہتی ہے، اور شیڈول شدہ سنک میں جس رن کی لیز آزاد ہو اسے صاف کر کے دوبارہ شیڈول تبھی کیا جاتا ہے جب اسے شروع ہوئے ایک گھنٹے سے زیادہ ہو چکا ہو۔ Crusoe کا ڈیمو پندرہ منٹ سے کم میں واپس آ جاتا ہے۔ ہمارا ہمیشہ نہیں۔
ری اسٹارٹ کے دوران سنک کس کی ملکیت میں ہے
ایک وقت میں ایک ہی رن کسی سنک کا مالک ہوتا ہے۔ رن Redis میں اپنے ٹوکن کے ساتھ ایک لیز لیتا ہے، جس کی عمر پندرہ منٹ ہوتی ہے اور جو ہر پانچ منٹ پر تجدید ہوتی ہے۔ ہر چیک پوائنٹ سے پہلے وہ تصدیق کرتا ہے کہ لیز اب بھی اسی کے پاس ہے۔ اگر نہیں، تو وہ رک جاتا ہے۔ رن اس سادہ جملے کے ساتھ ریکارڈ ہوتا ہے جو صارف پڑھے گا: “The run lost its slot part-way through and stopped to avoid writing twice.” (رن درمیان میں اپنی جگہ کھو بیٹھا اور دو بار لکھنے سے بچنے کے لیے رک گیا۔) جو دوسرا رن کسی فعال مالک سے ٹکرائے، اس کی دوبارہ کوشش نہیں کی جاتی۔ وہ “Another run of this sync was already in progress” (اس سنک کا ایک اور رن پہلے سے جاری تھا) کے ساتھ ختم ہوتا ہے، اور اگلا شیڈول شدہ رن معمول کے مطابق شروع ہوتا ہے۔
درستی کی ذمہ داری بھی لکھی ہوئی ہے۔ ہر ناکامی کا کوڈ ایک جملے سے جڑا ہے کہ کیا ہوا، ایک جملے سے کہ آگے کیا کرنا ہے، اور ایک مالک سے: آپ یا Tajo۔ جو منزل ہر ریکارڈ مسترد کر دے کیونکہ میپنگ غلط ہے، وہ آپ کی ذمہ داری ہے۔ کھوئی ہوئی لیز ہماری ذمہ داری ہے۔ رن کا صفحہ اگلا قدم دکھاتا ہے؛ سنک بحالی گائیڈ بتاتی ہے کہ کون سی۔
یہاں تک آسان آدھا حصہ ہے۔ ایک کریش کی قیمت ایک ری پلے ہے اور کچھ بھی دو بار نہیں لکھا جاتا۔ باقی آدھا حصہ دو واقعات نے سکھایا۔
ناکامی کے بعد ناکامی
ایک سنک بار بار ناکام ہوا۔ کسی تیز لوپ میں نہیں: شیڈولر کے ہر وقفے میں ایک بار، رن کے بعد رن، ہر بار ایک ہی پیغام کے ساتھ کہ کسٹم آئی ڈی میں کولن نہیں ہو سکتا۔ رن کبھی منزل تک نہیں پہنچا۔ وہ قطار میں ڈالے جاتے ہوئے ہی رک گیا، کسی رنر کے دیکھنے سے پہلے، اس لیے رنر سے جڑے الرٹ کے پاس جڑنے کو کچھ تھا ہی نہیں۔
اس سلسلے پر کوئی نظر نہیں رکھ رہا تھا۔ پورا نتیجہ یہی ہے۔
حل ایک بریکر ہے۔ ہر ریکارڈ شدہ ناکامی کے بعد یہ سنک کی آخری تبدیلی کے بعد سے اس کے آخری پانچ مکمل رن پڑھتا ہے۔ اگر پانچوں غلطیاں ہوں تو یہ سنک کو روک دیتا ہے، circuit_breaker_tripped وجہ کے ساتھ ایک آڈٹ اندراج لکھتا ہے، اور ایک کریٹیکل الرٹ بھیجتا ہے۔ سلسلہ محفوظ رنز سے نکالا جاتا ہے، ورکر کے کسی کاؤنٹر سے نہیں۔ کسی بھی راستے سے ریکارڈ ہونے والی ناکامی شمار ہوتی ہے، اس قطار میں ڈالنے والی ناکامی سمیت جس سے یہ واقعہ ہوا۔ کوڈ کا تبصرہ کہتا ہے کہ یہ اس واقعے کو پانچویں رن پر روک دیتا۔ ایک کامیابی سلسلہ دوبارہ صفر کر دیتی ہے۔ سنک کو دوبارہ چالو کرنا بریکر کو پرانے اندراجات پر دوبارہ ٹرپ کرنے کے بجائے اسے دوبارہ تیار کر دیتا ہے۔ Shopify کنیکٹر گائیڈ یہی بات ایک سطر میں کہتی ہے: مسلسل پانچ ناکام رنز کے بعد سنک خود کو روک دیتا ہے اور اس کا صفحہ آخری غلطی دکھاتا ہے۔
بریکر جو کام نہیں کرتا وہ ہے کچھ ٹھیک کرنا۔ Crusoe نوڈ بدل دیتا ہے اور پوچھے بغیر جاب دوبارہ شروع کر دیتا ہے۔ Tajo رک کر پوچھتا ہے: رکا ہوا سنک تب تک رکا رہتا ہے جب تک کوئی شخص وجہ ٹھیک کر کے اسے دوبارہ شائع نہ کرے۔ یہ محتاط ڈیفالٹ جان بوجھ کر ہے: کسٹمر ریکارڈز میں لکھنے والے سنک کی خودکار دوبارہ کوشش بذاتِ خود ایک تحریر ہے۔
وہ خاموشی جو کسی نے نہیں دیکھی
اعتراض جائز ہے، اور یوں ہے: “پانچ ناکامیوں کے بعد رکنے والا بریکر دوسرا واقعہ بھی پکڑ لیتا۔ دوسرا نگران کیوں بنایا جائے؟” کیونکہ دوسرا واقعہ ناکامی جیسا نظر ہی نہیں آتا تھا۔ ایک لمبے عرصے تک ایک ورک اسپیس میں ایک فعال سنک، غلطی کے اندراجات کا بڑھتا ڈھیر اور کبھی ایک بھی کامیابی نہیں تھی، اور کسی چیز نے الرٹ نہیں دیا۔ ہر موجود سگنل کسی سرگرمی سے جڑا تھا: کوئی رن ناکام ہوا، کوئی webhook آیا، کوئی بجٹ عبور ہوا۔ صفر کامیابیاں کوئی واقعہ نہیں ہیں۔ یہ واقعے کی غیر موجودگی ہے، اور بریکر صرف تب چلتا ہے جب کوئی ناکامی ریکارڈ ہو۔ بند پڑا شیڈولر، پھنسی ہوئی قطار، کبھی شروع نہ ہونے والا ورکر: یہ کچھ ریکارڈ نہیں کرتے، اور بریکر کبھی نہیں جاگتا۔
ریل انجن کا ڈیڈ مین ہینڈل الٹے طریقے سے کام کرتا ہے۔ ڈرائیور کو اسے مسلسل دبائے رکھنا پڑتا ہے، اور خاموشی ٹرین روک دیتی ہے۔ سنک والا ورژن ہر گھنٹے میں ایک بار، ہر گھنٹے کے تیرہ منٹ بعد چلتا ہے۔ فعال سنک والی ہر ورک اسپیس سے یہ ایک سوال پوچھتا ہے: کیا پچھلے چوبیس گھنٹوں میں کوئی رن کامیاب ہوا؟ جس ورک اسپیس کا سب سے پرانا فعال سنک ایک دن سے کم پہلے چالو کیا گیا ہو، اسے چھوڑ دیا جاتا ہے؛ اسے ابھی کامیاب ہونے کے لیے ایک دن نہیں ملا۔ جو اس سے پرانی اور خاموش ہو، اسے ایک کریٹیکل الرٹ ملتا ہے۔ الرٹ بتاتا ہے کہ کون سی خاموشی ہے: رن ریکارڈ ہوئے مگر کوئی کامیاب نہیں، یا کوئی رن ریکارڈ ہی نہیں ہوا۔ یہ ہر واقعے پر ایک بار بجتا ہے۔ Redis میں ایک نشان اسے پہلے کامیاب رن تک بند رکھتا ہے، پھر صاف ہو جاتا ہے، تاکہ اگلا واقعہ دوبارہ الرٹ دے۔
دونوں نگران ایک ہی commit میں، واقعات کے بعد آئے۔ بریکر کا تبصرہ کہتا ہے کہ یہ پہلے واقعے کو پانچویں رن پر روک دیتا۔ ڈیڈ مین کا تبصرہ کہتا ہے کہ بہت پہلے چالو کیا گیا اور صفر رنز والا سنک لازماً الرٹ دے۔ جب ضرورت تھی تب ان میں سے کوئی موجود نہیں تھا۔ ہم نے انہیں بعد میں لکھا، اور دونوں واقعات فائل کے ہیڈر میں درج کیے تاکہ کوئی وجہ نہ بھولے۔
کیا بنا ہے، اور کیا نہیں
اس تحریر کے وقت تک جو بنا ہے:
- کرسر ہر صاف بیچ کے آخر میں محفوظ ہوتا ہے، اور کریش پر دوبارہ بھی۔
- ہر ریکارڈ کی ڈیلیوری کلید صفحے کے کرسر اور اس کی جگہ سے بنتی ہے، اور منزل کو ہر کال سے پہلے سات دن کے لیجر سے ملائی جاتی ہے۔
- ہر سنک کے لیے ایک لیز، جس کی عمر پندرہ منٹ ہے۔
- ہر رن کے لیے پانچ کوششیں، ساٹھ سیکنڈ سے شروع ہونے والے وقفے کے ساتھ۔
- ایک بریکر جو مسلسل پانچ ناکامیوں کے بعد سنک روک دیتا ہے اور وجہ ریکارڈ کرتا ہے۔
- چوبیس گھنٹے بغیر کامیابی کے گزرنے پر ہر گھنٹے چلنے والا الرٹ۔
جو نہیں بنا، اور جس پر بھروسہ کرنے سے پہلے جاننا ضروری ہے:
- ڈیڈ مین سنک کو نہیں بلکہ ورک اسپیس کو دیکھتا ہے۔ ایک صحت مند سنک اسی ورک اسپیس میں اپنے خاموش ساتھی کو چھپا دیتا ہے۔
- اس کا الرٹ Tajo کے آپریٹرز تک پہنچتا ہے: ایک لاگ لائن ہمیشہ، اور جہاں ترتیب دیا گیا ہو وہاں Sentry، ایک webhook یا ایک ای میل۔ یہ سنک کے صفحے پر ظاہر نہیں ہوتا۔ بریکر کا روکنا ظاہر ہوتا ہے۔
- رکے ہوئے سنک کو کوئی چیز دوبارہ شروع نہیں کرتی۔ ایک شخص کرتا ہے۔
- ہارڈ کِل کے بعد بحالی تیز نہیں ہے۔ لیز پندرہ منٹ تک برقرار رہ سکتی ہے اور صفائی ایک گھنٹہ انتظار کرتی ہے۔
- دونوں حدیں، پانچ ناکامیاں اور چوبیس گھنٹے، ڈیپلائمنٹ کی سیٹنگز ہیں۔ آپ انہیں ہر سنک کے لیے الگ سیٹ نہیں کر سکتے۔
تقریباً کامل مراحل کی لمبی زنجیر پھر بھی ناکام ہوتی ہے؛ نکلنے کا راستہ یہ ہے کہ آخری حالت طے کی جائے اور اس کی جانچ کی جائے۔ یہ مضمون اسی کا عملی آدھا حصہ ہے۔ طے کیجیے کہ ایک رکا ہوا رن پیچھے کیا چھوڑتا ہے، اور اس کچھ نہ ہونے کی جانچ کیجیے جو خاموشی پیچھے چھوڑتی ہے۔
Crusoe کا آخری جملہ یہ تھا کہ “ناکامیاں ناگزیر ہیں”۔ ہمارا ایک قدم آگے ہے۔ کریش آسان آدھا حصہ تھا، کیونکہ اس نے اندراجات چھوڑے۔ خاموشی وہ آدھا حصہ تھی جسے ہمیں ڈھونڈنے نکلنا پڑا۔
اکثر پوچھے گئے سوالات
جب ورکر کسی بیچ کے درمیان رک جائے تو چلتے ہوئے سنک کا کیا ہوتا ہے؟
کرسر اب بھی ادھورے بیچ کے آغاز پر ہوتا ہے، کیونکہ Tajo اسے صرف تب آگے بڑھاتا ہے جب کوئی بیچ صاف طور پر مکمل ہو جائے۔ اگلا رن وہی صفحہ دوبارہ پڑھتا ہے۔ ہر ریکارڈ ایک ڈیلیوری کلید رکھتا ہے جو صفحے کے کرسر اور اس پر ریکارڈ کی جگہ سے بنتی ہے، اور ایک لیجر ہر مکمل تحریر کو سات دن تک محفوظ رکھتا ہے، اس لیے پہلے سے لکھے گئے ریکارڈ منزل کو دوسری بار بھیجنے کے بجائے لیجر سے دوبارہ چلائے جاتے ہیں۔
دوبارہ چلایا گیا سنک ایک ہی کانٹیکٹ کو دو بار کیوں نہیں لکھتا؟
منزل کو ہر کال سے پہلے رن ریکارڈ کی ڈیلیوری کلید کو ایک لیجر سے ملاتا ہے۔ یہ کلید سنک، سورس، صفحے کے کرسر، صفحے پر جگہ اور خود ریکارڈ کا hash ہے، اس لیے کریش، ایک منٹ بعد کی دوبارہ کوشش اور اگلے دن کا شیڈول شدہ رن ایک ہی ریکارڈ کے لیے ایک ہی کلید بناتے ہیں۔ جو کلید سات دن کی مدت کے اندر مکمل کے طور پر نشان زد ہو، وہ دوبارہ نہیں بھیجی جاتی۔
سنک کے لیے ڈیڈ مین الرٹ کیا ہے؟
ایسی جانچ جو ناکامی پر نہیں بلکہ غیر موجودگی پر بجتی ہے۔ ہر گھنٹے Tajo ہر اس ورک اسپیس کو دیکھتا ہے جس میں کوئی فعال سنک ہو، اور الرٹ دیتا ہے اگر پچھلے چوبیس گھنٹوں میں کوئی رن کامیاب نہ ہوا ہو، اس صورت سمیت جب کوئی رن ریکارڈ ہی نہ ہوا ہو۔ یہ ہر واقعے پر ایک بار بجتا ہے اور پہلے کامیاب رن کے بعد دوبارہ تیار ہو جاتا ہے۔ یہ اس لیے موجود ہے کہ ناکامی کا الرٹ صرف وہی ناکامیاں دیکھ سکتا ہے جو ریکارڈ ہوئی ہوں۔