मेरी ज़िंदगी की सबसे बड़ी मुसीबत: Rust में async और sync दोनों को सपोर्ट करना

Rust में synchronous और asynchronous code दोनों का समर्थन करना आधुनिक प्रोग्रामिंग की एक गहरी tension को उजागर करता है: जैसे ही कोई library async I/O अपनाती है, उसका “color” API में फैलने लगता है, जिससे simple, blocking interfaces चाहने वाले callers के लिए उपयोग कठिन हो जाता है। Commenters Rust ecosystem की तुलना Go, JavaScript, Python, और Zig जैसे languages से करते हैं, जहाँ ergonomics, performance, और runtime complexity के बीच अलग-अलग trade-offs पहले से ही baked in हैं। सुझाए गए workaround में अलग sync/async crates, `block_on` wrappers, sans-I/O designs, और effect systems शामिल हैं, लेकिन इनमें से कोई भी library authors के लिए maintenance और design burden को पूरी तरह समाप्त नहीं करता।

Rust लाइब्रेरी की परेशानी: sync और async दोनों का समर्थन

  • मुख्य समस्या: लाइब्रेरीज़ बिना कोड की नकल किए, feature-flag विस्फोट के बिना, या sync उपयोगकर्ताओं पर async runtime थोपे बिना sync और async दोनों APIs देना चाहती हैं।
  • Cargo feature नियम (“features must be additive”) परस्पर-अनन्य sync/async कॉन्फ़िगरेशन को awkward बना देते हैं।
  • दो crates (जैसे -sync और -async) या दो parallel code paths बनाए रखने की कोशिश की गई, लेकिन यह cumbersome निकला।
  • उपयोगकर्ताओं को भी यह पसंद नहीं कि किसी dependency ने async चुना, इसलिए उन्हें भी async में धकेल दिया जाए।

प्रस्तावित approaches

  • async core के ऊपर sync façade दिखाने के लिए dedicated thread में block_on का उपयोग करें; कई लोग इसे एक pragmatic compromise मानते हैं।
  • केवल async API रखें और sync users से कहें कि वे उस पर block करें, हालांकि इससे caller फिर भी “color” हो जाता है।
  • sync और async के लिए अलग crates या modules, जिनके naming conventions पर भी काफी bikeshedding होता है।
  • Sans-IO शैली: pure request/response types expose करें और caller को sync या async HTTP clients चुनने दें।
  • Macros / codegen (जैसे Python का unasync या Nim के “multisync”-जैसे विचार) से sync और async variants auto-generate करना।

Async बनाम sync: वैचारिक बहस

  • कुछ लोग async को “सुंदर” मानते हैं और complex state machines तथा high-concurrency I/O को व्यक्त करने का सबसे स्वाभाविक तरीका समझते हैं।
  • दूसरों को futures और state machines, कई workloads के लिए scoped threads की तुलना में कम स्वाभाविक लगते हैं।
  • कई लोग तर्क देते हैं कि async के लाभ तभी दिखते हैं जब कई tasks concurrently चल रहे हों; purely sequential code के लिए यह mental overhead जोड़ता है।
  • इस पर भी असहमति है कि क्या async concurrency bugs से बचाता है; कुछ लोग बताते हैं कि race conditions तब भी आ सकती हैं जब previously straight-line code में await जोड़ दिया जाए।

Cross-language comparisons

  • JS: async आसानी से integrate हो जाता है क्योंकि I/O हमेशा से callback-based और single-threaded था; sync के नीचे async को छिपाना फिर भी कठिन है।
  • Python: async नए patterns खोलता है, लेकिन asyncio को भारी और कभी-कभी simple threads से धीमा माना जाता है।
  • Go: एक single “green” concurrency model के लिए सराहा जाता है; इस पर बहस है कि क्या यह सचमुच function coloring से बचाता है या बस एक “color” को standardize करता है।
  • Haskell: green threads और async को ergonomically बेहतर माना जाता है; immutability concurrency के बारे में reasoning में मदद करती है।

Function coloring और runtimes

  • “Function coloring” को व्यापक रूप से मूल समस्या माना जाता है: async annotations call stacks और modules में viral तरीके से फैल जाती हैं।
  • Rust में built-in runtime का अभाव और Tokio/अन्य runtimes के बीच fragmentation friction बढ़ाते हैं (async traits, runtime coupling, cancellation semantics)।
  • कुछ लोग future solutions (keyword generics, effect systems, async-generic designs) की उम्मीद करते हैं, ताकि duplication कम हो और code runtime-agnostic बने।

Immutability, concurrency, और bugs

  • एक subthread तर्क देता है कि immutability, data races हटाकर, async/threads के साथ अच्छी तरह मेल खाती है; दूसरे जवाब देते हैं कि immutability को अक्सर जरूरत से ज़्यादा सराहा जाता है और यह complexity को update mechanisms पर शिफ्ट कर देती है।
  • कोई consensus नहीं है; प्रतिभागी concurrent correctness के लिए immutability को “silver bullet” मानने के पक्ष और विपक्ष में दोनों तरह के अनुभव साझा करते हैं।