जहाँ रीबूट न हो सके: स्पेस सॉफ़्टवेयर की इंजीनियरिंग
स्पेस सॉफ़्टवेयर ग्रेसफ़ुली फ़ेल नहीं हो सकता। जानिए इंजीनियर ऐसे कोड कैसे लिखते हैं जहाँ एक बग का मतलब अरबों डॉलर का मिशन खोना हो सकता है।

आपका वेब सर्वर रात 3 बजे क्रैश होता है। Kubernetes उसे रीस्टार्ट कर देता है। यूज़र को एक पल के लिए एरर पेज दिखता है। किसी की नौकरी नहीं जाती। अब सोचिए आपका सर्वर मंगल की कक्षा में है, रीस्टार्ट में 45 मिनट लगते हैं (इस दौरान न एटीट्यूड कंट्रोल है, न थर्मल रेगुलेशन, न कम्युनिकेशन), 'यूज़र' एक 2.5 अरब डॉलर का अंतरिक्ष यान है, और कोई Kubernetes नहीं है — बस आपका कोड है और वह रेडिएशन-हार्डन्ड CPU जिस पर वह चल रहा है।
स्पेस सॉफ़्टवेयर ऐसी बाधाओं में चलता है जिनके सामने सामान्य सॉफ़्टवेयर इंजीनियरिंग बहुत आसान लगती है। आप हॉटफ़िक्स डिप्लॉय नहीं कर सकते। SSH करके लॉग नहीं देख सकते। लोड बढ़ने पर और सर्वर नहीं जोड़ सकते। लॉन्च से पहले हर लाइन सही होनी चाहिए, क्योंकि लॉन्च के बाद सॉफ़्टवेयर सालों या दशकों तक अकेला चलता है, ऐसे हार्डवेयर पर जो धीरे-धीरे रेडिएशन से खराब हो रहा है, और ऐसे कम्युनिकेशन लिंक पर जिसमें कई मिनट की देरी और किलोबिट-प्रति-सेकंड की बैंडविड्थ है।
वे बाधाएँ जो सब कुछ तय करती हैं
रेडिएशन। अंतरिक्ष में उच्च-ऊर्जा कण लगातार इलेक्ट्रॉनिक्स पर बरसते रहते हैं। एक अकेला कण मेमोरी में एक बिट पलट सकता है (जिसे सिंगल-इवेंट अपसेट, या SEU कहते हैं), कोई रजिस्टर करप्ट कर सकता है, या प्रोसेसर को लॉक कर सकता है। यह कोई दुर्लभ घटना नहीं है — LEO उपग्रहों में हर दिन हज़ारों बिट फ़्लिप होते हैं। स्पेस-ग्रेड हार्डवेयर में रेडिएशन-हार्डन्ड कॉम्पोनेंट इस्तेमाल होते हैं, जो धीमे, महंगे और कंज़्यूमर हार्डवेयर से कई पीढ़ी पीछे होते हैं। मंगल के Perseverance रोवर का प्रोसेसर RAD750 है — यह लगभग 200 MHz पर चलने वाले 1998 के PowerPC जैसा है।
कम्युनिकेशन में देरी। रेडियो से मंगल की दूरी ग्रहों की स्थिति के हिसाब से 4 से 24 मिनट है। बृहस्पति 33 से 54 मिनट दूर है। यह सिर्फ़ लेटेंसी का मामला नहीं है — इसका मतलब है कि अंतरिक्ष यान को किसी भी समस्या को कम से कम राउंड-ट्रिप टाइम तक खुद संभालना होगा, इससे पहले कि ग्राउंड कंट्रोल उसे देख भी सके, कमांड भेजना तो दूर की बात है। जब Voyager प्रोब पृथ्वी से 22 से ज़्यादा प्रकाश-घंटे दूर किसी गड़बड़ी से टकराए, तो सॉफ़्टवेयर लगभग दो दिन तक अपने फ़ैसले खुद लेता रहा।
भौतिक पहुँच नहीं। आप खराब कॉम्पोनेंट बदल नहीं सकते, RAM नहीं जोड़ सकते, या हार्ड ड्राइव नहीं बदल सकते। अगर मुख्य कंप्यूटर खराब हो जाए और बैकअप काम न करे, तो मिशन खत्म। हर फ़ेल्योर मोड लॉन्च से पहले सॉफ़्टवेयर में सोचकर रखना पड़ता है।
स्पेस कोड अलग कैसे है
स्पेस सॉफ़्टवेयर ऐसी तकनीकें इस्तेमाल करता है जिन्हें सामान्य सॉफ़्टवेयर डेवलपमेंट में बेहद ओवर-इंजीनियरिंग माना जाएगा।
ट्रिपल मॉड्यूलर रिडंडेंसी (TMR)। महत्वपूर्ण गणनाएँ तीन स्वतंत्र प्रोसेसरों पर तीन बार चलती हैं। एक वोटर तीनों नतीजों की तुलना करता है और बहुमत वाला जवाब लेता है। अगर किसी एक प्रोसेसर को रेडिएशन से गलत नतीजा मिल जाए, तो बाकी दो उसे मात दे देते हैं। कुछ सिस्टम और अधिक भरोसे के लिए पाँच कॉपी (पेंटुपल रिडंडेंसी) चलाते हैं।
मेमोरी स्क्रबिंग। एक बैकग्राउंड प्रोसेस लगातार मेमोरी पढ़ता है, उसे एरर-करेक्टिंग कोड (ECC) से जाँचता है, और सिंगल-बिट एरर को इकट्ठा होकर मल्टी-बिट, ठीक न हो सकने वाली गड़बड़ी बनने से पहले सुधार देता है। यह लगातार चलता है — मेमोरी का हर बाइट हर सेकंड कई बार जाँचा और सुधारा जाता है।
वॉचडॉग टाइमर। ये हार्डवेयर टाइमर हैं जिन्हें सॉफ़्टवेयर को नियमित रूप से रीसेट करना पड़ता है। अगर सॉफ़्टवेयर हैंग हो जाए (शायद रेडिएशन से होने वाले लॉकअप की वजह से), तो टाइमर खत्म होकर हार्डवेयर रीसेट ट्रिगर कर देता है। सॉफ़्टवेयर को ऐसे डिज़ाइन करना पड़ता है कि वह किसी भी बिंदु पर अचानक रीबूट होने के बाद भी बचा रहे — कोई भी गणना बीच में रुककर दोबारा शुरू हो सकती है।
// Simplified space software patterns
// Watchdog — must be kicked regularly or hardware resets
void main_loop(void) {
while (1) {
kick_watchdog(); // Reset the timer — we're alive
// All operations must complete within watchdog timeout
read_sensors();
kick_watchdog();
run_attitude_control();
kick_watchdog();
check_thermal_limits();
kick_watchdog();
process_ground_commands();
kick_watchdog();
}
}
// Critical value stored with redundancy
typedef struct {
int32_t value_a; // Primary copy
int32_t value_b; // Redundant copy
int32_t value_c; // Third copy for voting
} RedundantInt;
int32_t read_redundant(RedundantInt *r) {
// Majority vote — tolerates one corrupted copy
if (r->value_a == r->value_b) return r->value_a;
if (r->value_a == r->value_c) return r->value_a;
if (r->value_b == r->value_c) return r->value_b;
// All three differ — flag anomaly
raise_anomaly(MEMORY_CORRUPTION);
return r->value_a; // Best guess
}
टेस्टिंग ही असली प्रोडक्ट है
NASA की Jet Propulsion Lab का अनुमान है कि स्पेस सॉफ़्टवेयर की टेस्टिंग में कुल डेवलपमेंट प्रयास का 60-80% खर्च होता है। समय का 60% नहीं — कुल लागत का 60%। टेस्टिंग डेवलपमेंट से भी महंगी पड़ती है, क्योंकि उसे इस स्तर तक सही साबित करना होता है जहाँ सामान्य सॉफ़्टवेयर टेस्टिंग कभी नहीं पहुँचती।
हर कोड पाथ की टेस्टिंग होनी चाहिए। वेब डेवलपर्स जिस तरह 'हाई कोड कवरेज' की बात करते हैं, वैसा नहीं — बल्कि हर फ़ंक्शन में हर पाथ, जिसमें एरर पाथ, टाइमआउट पाथ और हार्डवेयर फ़ेल्योर संभालने वाले पाथ भी शामिल हैं। 100% ब्रांच कवरेज शुरुआती बिंदु है, लक्ष्य नहीं।
यूनिट टेस्ट से आगे, स्पेस सॉफ़्टवेयर से हार्डवेयर-इन-द-लूप टेस्टिंग होती है (असली फ़्लाइट हार्डवेयर पर असली सॉफ़्टवेयर चलाना, और अंतरिक्ष के माहौल की नकल करना), लंबी अवधि की स्ट्रेस टेस्टिंग (टाइमिंग पर निर्भर बग खोजने के लिए महीनों तक चलाना), और फ़ॉल्ट इंजेक्शन टेस्टिंग (जानबूझकर मेमोरी करप्ट करना, प्रोसेसर बंद करना और कम्युनिकेशन लिंक काटना, ताकि पक्का हो कि सॉफ़्टवेयर उबर जाता है)।
सबसे महत्वपूर्ण कॉम्पोनेंट्स के लिए फ़ॉर्मल वेरिफ़िकेशन का इस्तेमाल बढ़ रहा है। किसी खास इनपुट पर कोड के काम करने की जाँच करने के बजाय, फ़ॉर्मल वेरिफ़िकेशन गणितीय रूप से साबित करता है कि कोड सभी संभावित इनपुट के लिए काम करता है। यह महंगा और धीमा है, लेकिन जो कोड यान के attitude (दिशा) को नियंत्रित करता है या उसके प्रोपल्शन को संभालता है, उसके लिए यह खर्च जायज़ है।
फिर भी गड़बड़ी कहाँ होती है
इतनी सख़्ती के बावजूद स्पेस सॉफ़्टवेयर फ़ेल होता है। ये फ़ेल्योर सिखाने वाले हैं, क्योंकि ये दिखाते हैं कि सबसे सावधानी से की गई इंजीनियरिंग की भी सीमाएँ होती हैं।
- Mars Climate Orbiter (1999) इसलिए क्रैश हुआ क्योंकि एक टीम इंपीरियल यूनिट इस्तेमाल कर रही थी और दूसरी मीट्रिक। सॉफ़्टवेयर सही था — गलती स्पेसिफ़िकेशन में थी। कोई भी टेस्टिंग गलत स्पेसिफ़िकेशन को नहीं पकड़ सकती।
- Ariane 5 Flight 501 (1996) में विस्फोट हो गया, क्योंकि एक 64-बिट फ़्लोट को 16-बिट इंटीजर में बदला गया और वह ओवरफ़्लो हो गया। कोड Ariane 4 से दोबारा इस्तेमाल हुआ था, जहाँ वह वैल्यू कभी 16-बिट रेंज से बाहर नहीं जाती थी। कोड Ariane 4 के लिए सही था और Ariane 5 के लिए विनाशकारी रूप से गलत।
- Mars Polar Lander (1999) शायद इसलिए क्रैश हुआ क्योंकि लेग खुलने के दौरान सेंसर के कंपन को ज़मीन से संपर्क समझ लिया गया, और इंजन 40 मीटर की ऊँचाई पर बंद हो गए। यह एक टाइमिंग पर निर्भर सेंसर व्याख्या की समस्या थी, जिसे टेस्टिंग नहीं पकड़ पाई क्योंकि टेस्ट कंपन की विशेषताओं को पूरी तरह दोहरा नहीं पाया।
- Hubble के शुरुआती मिरर दोष (1990) सॉफ़्टवेयर बग नहीं था — मिरर गलत आकार में घिसा गया, क्योंकि एक गलत कैलिब्रेटेड टेस्टिंग इंस्ट्रूमेंट इस्तेमाल हुआ था। यानी टेस्टिंग टूल खुद बगी था।
सबमें एक समान बात: कोड अपने स्पेसिफ़िकेशन के हिसाब से सही था, लेकिन स्पेसिफ़िकेशन असलियत से मेल नहीं खाता था। इस तरह का बग रोकना सबसे मुश्किल है, क्योंकि यह मॉडल और दुनिया के बीच के अंतर में रहता है।
पृथ्वी का सॉफ़्टवेयर क्या सीख सकता है
हम में से ज़्यादातर लोग स्पेस सॉफ़्टवेयर नहीं लिखते। लेकिन इनमें से कुछ तरीके पृथ्वी पर भरोसेमंद सिस्टम बनाने में सीधे काम आ सकते हैं।
रीस्टार्ट के लिए डिज़ाइन करें। स्पेस सॉफ़्टवेयर मानकर चलता है कि उसे किसी भी समय रीबूट किया जा सकता है और उसे एक ज्ञात-सही स्थिति में वापस आना होगा। वेब सर्विसेज़ में भी यही गुण होना चाहिए — अगर आपका सर्वर क्रैश होकर रीस्टार्ट होता है, तो क्या वह बिना मैन्युअल हस्तक्षेप के वापस आ जाता है? क्या वह जहाँ छूटा था वहीं से प्रोसेसिंग शुरू करता है, या काम खो देता है? डिफ़ेंसिव इंजीनियरिंग पैटर्न जिन्हें स्पेस इंजीनियर अनिवार्य मानते हैं, वे वेब डेवलपमेंट में अक्सर वैकल्पिक माने जाते हैं, लेकिन उन्हें वैकल्पिक नहीं होना चाहिए।
सिर्फ़ हैप्पी पाथ नहीं, फ़ेल्योर मोड की टेस्टिंग करें। स्पेस सॉफ़्टवेयर टेस्टिंग में खास तौर पर फ़ेल्योर डाले जाते हैं: प्रोसेस बंद करना, मेमोरी करप्ट करना, नेटवर्क कनेक्शन गिराना, हर सिस्टम कॉल से एरर कोड लौटाना। ज़्यादातर वेब एप्लिकेशन टेस्टिंग इस पर ध्यान देती है कि फ़ीचर काम करते हैं या नहीं, इस पर नहीं कि सिस्टम फ़ेल्योर को सुंदरता से संभालता है या नहीं।
महत्वपूर्ण डेटा के लिए रिडंडेंसी। अगर आपका एप्लिकेशन ऐसा डेटा स्टोर करता है जिसे दोबारा बनाना महंगा है — वित्तीय रिकॉर्ड, यूज़र कंटेंट, कॉन्फ़िगरेशन स्टेट — तो उसे रिडंडेंट रूप में स्टोर करें और नियमित रूप से जाँचें। डेटाबेस रेप्लिकेशन सबसे स्पष्ट उदाहरण है, लेकिन एप्लिकेशन के भीतर की रिडंडेंसी (चेकसम, वैलिडेशन, समय-समय पर इंटेग्रिटी जाँच) वह करप्शन पकड़ती है जिसे रेप्लिकेशन आगे फैला देता है।
महत्वपूर्ण प्रोसेस के लिए वॉचडॉग। अगर कोई प्रोसेस हैंग नहीं होना चाहिए, तो उस पर नज़र रखें। सिर्फ़ 'प्रोसेस चल रहा है या नहीं' नहीं, बल्कि 'प्रोसेस आगे बढ़ रहा है या नहीं' भी देखें। ऐसे हेल्थ चेक जो जाँचें कि सिस्टम सच में काम कर रहा है — रिक्वेस्ट प्रोसेस हो रही हैं, स्टेट अपडेट हो रहा है, डेडलाइन पूरी हो रही हैं — वे उन फ़ेल्योर को पकड़ते हैं जो प्रोसेस-लेवल मॉनिटरिंग से छूट जाते हैं।
नया स्पेस सॉफ़्टवेयर
कमर्शियल स्पेस इंडस्ट्री (SpaceX, Rocket Lab, Planet) इनमें से कुछ परंपराओं को चुनौती दे रही है। SpaceX अपने Falcon 9 फ़्लाइट कंप्यूटर्स पर Linux और C++ इस्तेमाल करता है — पारंपरिक एयरोस्पेस मानकों के हिसाब से यह धर्मविरोधी माना जाता था। Planet Labs सैकड़ों छोटे उपग्रह चलाता है और उन्हें कस्टम हार्डवेयर के बजाय एक डिस्ट्रीब्यूटेड सिस्टम की तरह देखता है: अगर कोई उपग्रह फ़ेल हो जाए, तो पूरा कॉन्स्टेलेशन उसकी भरपाई कर देता है।
यह बदलाव एक बड़े सवाल की ओर इशारा करता है: आपको असल में कितनी भरोसेमंदी चाहिए? 2.5 अरब डॉलर का मंगल रोवर पाँच साल की टेस्टिंग को जायज़ ठहराता है। सैकड़ों में से एक, 5 लाख डॉलर का कम्युनिकेशन उपग्रह उससे बहुत कम को जायज़ ठहराता है। इंजीनियरिंग का तरीका जोखिम प्रोफ़ाइल के हिसाब से होना चाहिए, किसी और युग के लिए बनी परंपराओं को आँख मूँदकर नहीं मानना चाहिए।
लेकिन बजट चाहे जो हो, मूल सीख वही रहती है: जो सॉफ़्टवेयर डिप्लॉयमेंट के बाद फिज़िकली एक्सेस नहीं हो सकता, उसे उस सॉफ़्टवेयर से ज़्यादा भरोसेमंद होना होगा जिसे एक्सेस किया जा सकता है। चाहे आप अंतरिक्ष यान लॉन्च कर रहे हों, IoT फ़्लीट में डिप्लॉय कर रहे हों, या एज कंप्यूटिंग नेटवर्क चला रहे हों, सिद्धांत एक ही है — अगर आप SSH करके उसे ठीक नहीं कर सकते, तो सॉफ़्टवेयर को खुद उसे संभालना होगा। यह मानसिकता, समझदारी से लागू की जाए, हर सॉफ़्टवेयर को बेहतर बनाती है।


