6 पॉइंट द्वारा GN⁺ 2025-01-01 | 2 टिप्पणियां | WhatsApp पर शेयर करें
  • “let’s just” से शुरू होने वाले सिस्टम design प्रस्ताव आम तौर पर उम्मीद से ज़्यादा जटिल हो जाते हैं, और अच्छी architecture judgment काफी हद तक rule of thumb और context समझने पर निर्भर करती है
  • Plugin structure, API जोड़ना, और abstraction layers सुनने में सही लगते हैं, लेकिन असल में उन्हें behavioral compatibility, maintenance, security, performance, और ecosystem की ज़रूरतों को साथ-साथ संभालना पड़ता है
  • Asynchronous processing, access control, और data synchronization परिचित विषय लग सकते हैं, लेकिन product environment में ये reproduce करना मुश्किल bugs, security model redesign, और synchronization की कठिन समस्याओं तक आसानी से ले जाते हैं
  • Cross-platform और native escape शुरुआती सरल products में उपयोगी हो सकते हैं, लेकिन जब platform features और internal state अलग-अलग दिशाओं में बंटने लगते हैं, तो quality और consistency बनाए रखना मुश्किल हो जाता है
  • ये patterns हमेशा गलत नहीं हैं, लेकिन अधिकतर मामलों में इनकी ज़रूरत नहीं होती या इनके alternatives होते हैं; असफल होने की संभावना वाले approaches के बजाय समस्या को first principles से दोबारा हल करना चाहिए

“let’s just” खतरनाक क्यों है

  • “let’s just” के बाद आने वाला प्रस्ताव 10 में से 9 बार meeting room में सोचे गए अनुमान से कहीं ज़्यादा जटिल काम बन जाता है
  • Engineering में social science जैसा पहलू भी होता है, इसलिए क्या काम करेगा यह context-dependent होता है
  • जब कहा जाता है कि कोई approach काम नहीं करेगी, तो engineers इसे अक्सर तुरंत counterexample साबित करने की challenge की तरह ले लेते हैं
  • Engineering management और software architecture का बड़ा हिस्सा अनुभव से मिली rule of thumb और मुश्किल से सीखे गए lessons का मिश्रण है

“बस इसे plugin-able बना देते हैं”

  • जब एक implementation कम लगती है, तो उसी architecture में नई implementation जोड़ने से ऐसा लगता है कि API callers को बदले बिना improvements या नए features मिल जाएंगे
  • लेकिन “API header file या documentation नहीं, बल्कि behavior itself है”, इसलिए बस चल जाने लायक plugins लगभग नहीं होते
  • Modern software में plugin के सबसे करीब component device driver है
    • पहले drivers की behavior quality अच्छी नहीं थी, इसलिए वे अब acceptable नहीं रहे, या modern OS अपने खुद के drivers बनाने की दिशा में जा रहे हैं
  • सचमुच plugin-able structure बनाने के लिए default implementation के साथ-साथ दूसरी implementation भी design करनी पड़ती है, तभी कम से कम एक बार काम करने का proof मिलता है

“बस API जोड़ देते हैं”

  • Product या company के कुछ हद तक सफल होने के बाद अक्सर “platform बनकर developers को आकर्षित करना चाहिए” कहते हुए API जोड़ी जाती है
  • API provider को feature additions और compatibility·interoperability के बीच लगातार trade-off करना पड़ता है, और existing behavior व performance characteristics की वजह से बदलाव की freedom काफी घट जाती है
  • API होने का मतलब यह नहीं कि कोई उसे ज़रूर इस्तेमाल करना चाहेगा
    • नई API अक्सर तब बनती है जब product कोई capability चाहता है, लेकिन internally उसे पर्याप्त priority नहीं देता
    • Target market छोटा, vertical-specialized, या किसी specific domain तक सीमित होता है, और उम्मीद की जाती है कि external partners API के ज़रिए gap भर देंगे
    • ऐसे partners के अपने business और customers होते हैं, इसलिए वे किसी दूसरे product को extra अपनाकर problem solve करना नहीं चाह सकते
  • Platform बनना वास्तविक demand वाला बड़ा business है, और सिर्फ कुछ APIs देने से third parties के लिए economic foundation बन जाना दुर्लभ है

“एक और abstraction layer जोड़ते हैं”

  • Butler Lampson की बात “computer science की हर समस्या को एक और layer of indirection से हल किया जा सकता है” में वास्तविक सच्चाई है
  • Failure मुख्यतः दो तरीकों से दिखती है
    • बहुत जल्दी जोड़ी गई abstraction, वास्तविक use plan के बिना over-abstraction बनकर architecture में रह जाती है
    • बाद में जोड़ी गई abstraction maintenance, security, और performance optimization को बहुत जटिल बना सकती है
  • Windows NT में शुरुआत से ही कई over-abstractions थीं जो वास्तव में इस्तेमाल नहीं हुईं
  • Mac OS के evolution में ऐसी abstraction के उदाहरण थे जो शुरुआत में अजीब लगी, लेकिन दो releases बाद उपयोगी साबित हुई; फर्क plan के मौजूद होने का था
  • अगर post-facto abstraction सिर्फ कुछ code में इस्तेमाल होती है, तो नए abstraction का उपयोग न करने वाला code बढ़ जाता है और maintenance burden बढ़ता है

“इसे asynchronous बना देते हैं”

  • Computer science के शुरुआती लगभग 25 साल का बड़ा हिस्सा asynchronous behavior को समझने और implement करने की समस्या पर लगा
  • 1980s के graduate courses में dining philosophers, producer-consumer, sleeping barber जैसे topics पर काफी समय दिया जाता था
  • आज कई engineers data layer rules और web frameworks की वजह से async समस्याओं को काफी हद तक abstracted form में handle करते हैं
  • Framework या data layer के बाहर सीधे async को manage करने पर शुरुआत में सब ठीक लगता है, लेकिन एक साल बाद reproduce करना मुश्किल bugs सामने आ सकते हैं
  • बस यही उम्मीद की जा सकती है कि वह bug data corruption issue न हो

“Access control बाद में जोड़ देंगे”

  • Access control कहाँ होना चाहिए, यह theoretical debate का विषय था, लेकिन आज के systems लगातार attacks झेलते हैं, इसलिए environment कहीं ज़्यादा जटिल है
  • सब जानते हैं कि security शुरुआत से चाहिए, लेकिन market launch speed की वजह से बहुत कम systems access control और security model को शुरू से पूरी तरह design करते हैं
  • Customers और attackers के perspective से शुरुआत किए बिना product के लिए सही access control design बनाना मुश्किल है
  • Access control को बाद में चिपकाने वाला तरीका fail हो सकता है, या भविष्य में product को दोबारा लिखने की स्थिति ला सकता है
  • वह rewrite customers सहित सभी के लिए खराब experience बनता है

“Data synchronize कर लेते हैं”

  • कई devices, SaaS apps, और data stores वाले environment में “बस data synchronize कर लेते हैं” वाला प्रस्ताव अक्सर आता है
  • client/server और data synchronization के pioneer Ray Ozzie ने जिस तरह जोर दिया, synchronization एक कठिन समस्या है
  • Computer science में कठिन समस्या का मतलब ऐसी बहुत tricky challenges से है जिन्हें सिर्फ experience से ही सीखा जा सकता है
  • पूर्ण semantics और transactions वाले data store में भी synchronization कठिन है, और blob, unstructured data, data transformation जुड़ जाएं तो difficulty तेजी से बढ़ जाती है
  • Solution की नींव data synchronization पर रखना लगभग कभी desired choice नहीं होता, और सिर्फ synchronization पर अरबों डॉलर की companies मौजूद होने की वजह भी यही है

“Cross-platform बना लेते हैं”

  • Cross-platform लंबे समय से दोहराई जाने वाली debate है, और कोई न कोई कहता है कि उसका code अच्छी तरह काम करता है या Unity और games का उदाहरण देता है
  • जब आप कुछ cross-platform बनाने की बात करते हैं, तो असल में यह operating system, cloud provider, या browser में से कुछ बनाने का वादा करने जैसा है
  • Cross-platform दो cases में अच्छा काम करता है
    • जब platform नया और सरल हो, जैसे cloud सिर्फ compute और simple storage के level पर हो
    • जब application या product नया और सरल हो
  • जैसे ही आप underlying platform से अलग होने लगते हैं, या ऐसे features बनाने लगते हैं जो हर target platform पर बिल्कुल अलग रूप में express होते हैं, ये conditions टूट जाती हैं
  • Microsoft के लिए Mac के लिए Office और Windows के लिए Office को एक ही code से बनाना मुश्किल हो गया, इसलिए 1998 में उसने Office code fork कर दिया, और फिर वापस नहीं गया
  • Microsoft मूल रूप से cross-platform apps बनाने वाले business के रूप में मौजूद था, लेकिन वह तरीका उन दिनों अच्छा काम करता था जब OS API documentation करीब 100 pages की होती थी और हर OS CP/M से derived था
  • संबंधित लेख: Divergent Thoughts on Cross Platform

“ज़रूरत पड़े तो native में escape कर लेंगे”

  • Cross-platform कम समय के लिए ही अच्छी तरह काम करता है, इसलिए frameworks और API abstractions अक्सर native escape देते हैं
  • इस idea का मतलब है कि platform evolve होने पर framework ने अभी expose नहीं किए features को सीधे native platform से call किया जाए
  • लेकिन abstraction देने वाले frameworks या APIs internal state या cache maintain करते हैं
  • Native platform को सीधे call करने से ऐसे data structures और state बदल जाते हैं जिनके बारे में framework को पता नहीं होता
  • कुछ frameworks escape code और framework के बीच data या state exchange करने की व्यवस्था देते हैं, लेकिन यह automatic memory management के दौर में malloc/free जैसी architecture को फिर से introduce करने जैसा समाधान है

चुन सकते हैं, लेकिन default नहीं

  • इन approaches पर हमेशा “नहीं” कहना ज़रूरी नहीं है
  • किसी specific context में ये तरीके काम कर सकते हैं
  • लेकिन अधिकतर मामलों में इन patterns की ज़रूरत नहीं होती या बेहतर रास्ते मौजूद होते हैं
  • High-failure-risk software patterns को पहले उठाने के बजाय समस्या को first principles से हल करना चाहिए

2 टिप्पणियां

 
ndrgrd 2025-01-02

प्लग के मामले में सबसे ज़रूरी बात यह है कि इंटरफ़ेस को डिज़ाइन करते समय केवल अनिवार्य व्यवहारों को जितना संभव हो उतना छांटकर रखा जाए.
अगर इंटरफ़ेस को बस मौजूदा कोड की मोटी-मोटी संरचना उठाकर बना दिया जाए, तो वह स्वाभाविक रूप से उस implementation से बंधा हुआ एक अनावश्यक इंटरफ़ेस बन जाता है, लेकिन ऐसे मामले वाकई बहुत आम हैं...

 
GN⁺ 2025-01-01
Hacker News टिप्पणियां
  • ऐसे ideas की समस्या idea में उतनी नहीं होती, जितनी उसके आगे लगने वाले “बस कर देते हैं” वाले approach या expectations में होती है
    मसलन, अगर “बस API जोड़ देते हैं” कहकर API को product की “बस एक feature” की तरह देखा जाए, तो इसकी success rate “बस UI जोड़ देते हैं” जैसी ही होगी
    अच्छा UI बनाने के लिए सावधानी और गहराई चाहिए, और उस क्षेत्र के experts भी चाहिए
    product के किसी दूसरे interface के साथ अलग व्यवहार करने की कोई वजह नहीं है; मुद्दा यह नहीं कि idea खराब है या अच्छा, बल्कि यह है कि यह ऐसा काम है जिसे बस यूं ही नहीं करना चाहिए

    • मेरी पिछली job में एक rule था
      “बस” कहने की इजाजत केवल उस developer को थी जिस पर वाकई उसे काम करने लायक बनाने की जिम्मेदारी हो; अगर कोई दूसरा developer यह कहता, तो माना जाता कि वह खुद उस काम को लेने के लिए volunteer कर रहा है
      हमारे लिए यह rule अच्छा काम करता था
    • सही है। API जोड़ते समय “बस” जैसी कोई चीज नहीं होती
      API को ठीक से बनाने में काफी design और complexity लगती है
      अगर design अच्छा न हो, तो client को वह call कई बार करनी पड़ सकती है जो एक बार में होनी चाहिए थी, या API इतनी confusing हो सकती है कि उसे गलत call कर दिया जाए या बिल्कुल इस्तेमाल न किया जा सके
      authentication और authorization भी चाहिए, इसलिए OAuth2 setup करना होगा या कम से कम secure API token बनाना, store करना और verify करना होगा
      data को भी सुरक्षित तरीके से handle करना होगा, और performance खराब हो तो database load के नीचे दब सकता है
      caching जोड़ने पर cache invalidation और cache support के लिए servers/processes की complexity बढ़ जाती है
      rate limiting न हो तो कमजोर client API पर लगातार requests मार सकता है, और documentation खराब हो तो API व्यावहारिक रूप से बेकार है
      कुछ मामलों में कई languages के लिए SDK भी देने पड़ सकते हैं, और अच्छे error messages न हों तो first-time users को पता ही नहीं चलेगा कि call fail क्यों हुई
    • ज्यादातर professional advice dating advice जैसी होती है
      लोग अपने साथ जो गलत हुआ उसे generalize कर देते हैं, लेकिन जब तक situation बहुत मिलती-जुलती और व्यक्ति वही जैसा न हो, वह लगभग वैसी की वैसी लागू नहीं होती
      जो advice लगातार सही रहती है, वह “सोच-समझकर विचार करो, सही काम करने की कोशिश करो, और results पर वापस नजर डालो” जैसी इतनी general होती है कि लगभग बेकार हो जाती है
      ऐसी बातों से blog posts या books अच्छी तरह नहीं बिकतीं
    • presales नाम की job शायद लगभग पूरी तरह “बस” शब्द की वजह से मौजूद है
      क्योंकि जब iceberg का बाकी हिस्सा पानी से बाहर उठाना शुरू किया जाए, तो यह देखना पड़ता है कि customer डर न जाए
    • सही है। लेख की positioning अगर “system ideas को बस काम करा देने के लिए असल में क्या-क्या चाहिए” होती, तो वह कहीं बेहतर होता
      तब यह संभव/असंभव का सवाल नहीं, बल्कि success और failure के तरीकों पर लेख बनता
      जरूरी details पता चलने पर, यह जाने बिना कि हम क्या नहीं जानते, “बस” कहना भी मुश्किल हो जाता है
      हालांकि DSL के बारे में मैं लगभग 100% सहमत हूं
      यह अनावश्यक और cute बनने की कोशिश वाली complexification के करीब है, और इसे बनाने की योग्यता शायद उसी व्यक्ति में होनी चाहिए जिसने एक successful programming language बनाई हो, गलतियों को ध्यान में रखते हुए उसका दूसरा edition या दूसरी language तक update की हो, और फिर भी कई चीजों में गलत निकला हो
  • (1) DSL कभी-कभी बहुत अच्छी तरह काम करते हैं। https://www.jooq.org/ देखें
    (2) Elastic Load Balancer एक control loop है जो workload पर प्रतिक्रिया देता है, और इस तरह की चीज़ें पहले से ही सामान्य तकनीक बन चुकी हैं
    (3) ज़्यादातर industries में under-provisioning बहुत आम है। https://erikbern.com/2018/03/27/waiting-time-load-factor-and... और https://www.amazon.com/Goal-Process-Ongoing-Improvement/dp/0... देखें
    (4) anomaly detection बाकी बिंदुओं की तरह मूल रूप से distributed systems की समस्या नहीं है, लेकिन जो व्यक्ति एक बार बुरी तरह झुलस चुका हो उसे इसकी ज़रूरत महसूस हो सकती है
    यह बौद्धिक रूप से भी कठिन क्षेत्र है
    पहली बार जिस algorithm ने मुझे कुछ हद तक smart लगा था, वह https://scikit-learn.org/1.5/modules/outlier_detection.html#... था, और कभी-कभी यह चमत्कार की तरह काम करता है
    2018 में इस्तेमाल किए जाने वाले CNN-based embeddings के साथ text पर लगाने पर यह ठीक बैठा था, लेकिन SBERT में मेरी बिल्कुल किस्मत नहीं चली

    • मैंने दो DSL लिखे हैं, जिनमें से एक team के साथ बनाया था, और मेरी नज़र में दोनों सफल रहे
      उन्होंने समस्या हल की और किसी ने गाली नहीं दी
      सबसे अहम कारण शायद यह था कि दोनों छोटे थे
      दोनों बहुत मिलते-जुलते थे और code भी reuse हुआ था
      एक विशाल forms को validate करने वाले rules लिखने के लिए था, और दूसरा form responses के आधार पर decision rules लिखने के लिए
      अच्छा DSL उन लोगों को सक्षम बना देता है जो पहले वह काम नहीं कर पाते थे
      समय बचाने के लिए बनाया गया DSL उपयोगी होने की संभावना कहीं कम रखता है, क्योंकि असल में वह समय बचाएगा ही इसकी संभावना कम होती है
      दोनों मामलों में जटिल domain behavior को program के अंदर लाना था
      इसलिए या तो programmer को domain सिखाना पड़ता है, या programmer और domain expert को साथ बैठाना पड़ता है, या domain expert को programming सिखानी पड़ती है
      अगर काम बहुत है, तो domain expert के हाथ में ताकत देना आकर्षक लगता है
      programmer दूसरा काम कर सकता है और feedback loop भी छोटा हो जाता है
      अगर domain गहरा है तो आप programmer को school भेजकर सीखवाना नहीं चाहेंगे, और अगर domain उथला है तो कोई सस्ता व्यक्ति भी उसे संभाल सकता है
      DSL के साथ बड़ा cognitive burden आता है
      हालांकि अगर विकल्प पूरा programming language सीखना हो, तो यह ज़्यादा तर्कसंगत हो जाता है
      समय बचाने वाला DSL वह मामला है जहां code लिखना जानने वाला व्यक्ति कम code लिखना चाहता है, लेकिन बचत छोटी होती है इसलिए आम तौर पर यह खास नहीं होता
      फिर जब programmer को कुछ बदलना हो, तो सहज code के बजाय उसे इस पूरे DSL को सीखना या याद करना पड़ता है
      और सरल rule of thumb यह है कि programmers के लिए DSL, non-programmers के लिए DSL की तुलना में अच्छा idea होने की संभावना कम रखता है
    • jOOQ एक disaster है और मैं इसे किसी को recommend नहीं करूंगा
      SQL query लिखकर DataGrip जैसे tool में test करने के बाद, उसे DSL में बदलने का तरीका समझने में घंटों लग जाते हैं
      JSON expressions जैसी “exotic” SQL features इस्तेमाल करें तो समस्या और बिगड़ जाती है
      debugging का flow बन जाता है: “generated SQL print करो, उसे DataGrip जैसी जगह में copy-paste करो, query tune करो, फिर उसे वापस DSL में फिट करने का तरीका खोजो”
      यह जबरदस्त समय की बर्बादी है
      jOOQ का मुख्य selling point type-safe queries है, लेकिन IntelliJ ने code के अंदर string SQL को real data के against validate करना शुरू किया तो इसकी अहमियत खत्म हो गई
      SQL को सीधे edit करना और database पर तुरंत test करना बस बेहतर flow है
      jOOQ, DSL पर मूल लेख की दलील को और मजबूत करता है
    • regular expressions जैसी चीज़ों को छोड़कर मैंने अच्छा DSL नहीं देखा, और उनके बारे में भी सुना है कि बहुत लोग भाषा से ही नाखुश हैं
      खराब या लगभग असफल माने जा सकने वाले popular DSL examples में HCL, E4X, XUL, Common Lisp की string formatting language आदि शामिल हैं
      HCL Terraform की configuration language है, और यह साफ था कि variables की संख्या के हिसाब से मिलते-जुलते equipment provision करने की बहुत आम समस्या को शुरुआत से handle नहीं किया गया था
      बाद में features जोड़ने की कोशिशें भी अटपटी थीं और समस्या को पूरी तरह हल नहीं कर पाईं
      E4X XML पर काम करने के लिए JavaScript DSL था, जिसने simple cases में XML काम को ज़्यादा concise तरीके से व्यक्त करने दिया, लेकिन जल्दी ही यह punctuation की दीवार जैसा पढ़ने में मुश्किल हो सकता था
      Microsoft के LINQ की तरह, यह लेखक को बिल्कुल नहीं बताता था कि अंदरूनी code की computational complexity कितनी है
      आखिरकार इस DSL का इस्तेमाल करने वाला code अक्सर कम concise लेकिन analyze करने में आसान तरीके से फिर से लिखा जाता था
      XUL Firefox browser chrome extensions के लिए UI language थी, और Firefox extensions बनाने के उद्देश्य के लिए ठीक थी
      लेकिन Firefox इसे enterprise internal applications की base technology के रूप में भी बेचना चाहता था, और उस क्षेत्र में यह बहुत कमज़ोर थी
      simple कामों के लिए कई hacks और workarounds की ज़रूरत पड़ती थी
      Common Lisp की string formatting language भी इसी तरह छोटी समस्याओं के लिए ठीक है, लेकिन scalable नहीं है
      कुछ formatting समस्याओं के लिए बेहद अजीब solutions चाहिए होते हैं या शुरुआत से ही कोई जवाब नहीं होता, और format को recursively call करने वाला code देखकर सच में चिढ़ होती है
      कुल मिलाकर, इस approach की सबसे आम समस्या यह है कि यह तदर्थ है और अच्छी तरह scale नहीं करती
      जल्द ही आप ऐसी समस्या से टकराते हैं जिसे ठीक से हल नहीं किया जा सकता, और DSL में लिखे बड़े programs को संभालना अक्सर एक nightmare होता है
    • DSL से नफरत देखकर हर बार मैं हैरान होता हूं, फिर समझ आता है कि लोग DSL सामान्य रूप से नहीं, बल्कि वे DSL जिन्हें शुरुआत से खुद लिखना पड़ता है उनकी आलोचना कर रहे हैं
      Lisp के ऊपर DSL रखें तो आपको base language नहीं, सिर्फ domain logic लिखना पड़ता है
      ज़्यादातर काम पहले ही हो चुका होता है, और language पहले दिन से उपयोगी होती है
      Lisp के ऊपर hosted DSL के रूप में बनाया जाए तो यह सच में इस्तेमाल हो सकता है; फिर पता नहीं लोग नई language बिल्कुल scratch से क्यों बनाते हैं और उसे मुरझाकर मरते हुए क्यों देखते हैं
    • DSL autocomplete-capable IDE और तेज़ या तुरंत feedback loop होने पर अच्छी तरह काम करते हैं
  • इन सभी आइटम्स के बहुत सारे success cases हैं
    “लगभग” शब्द को बच निकलने का रास्ता बनाना मुश्किल है
    यह बस निराशावाद और थकी हुई cynicism जैसा दिखता है
    मैं उस भावना को समझता हूँ और खुद भी महसूस कर चुका हूँ, और कभी-कभी जोशीले engineer से खराब idea छोड़वाना मुश्किल होता है
    लेकिन यह माहौल मुझे हानिकारक लगता है

    • मुझे लगता है यह बस “इन चीज़ों को सही से बनाना या प्रभावी ढंग से deploy करना दिखने से ज्यादा tricky है” को ज़्यादा engagement वाला, कहें तो clickbait अंदाज़ में कहने जैसा है
    • ऐसे कई “success” cases के पीछे उस idea की सारी failures संभालने वाली battle-hardened engineers की team होती है
      infinity या max/min boundaries तक runaway हो जाने वाले control loops, distributed failures से recover न कर पाने वाले caches, live migration के दौरान corrupt state, असुविधाजनक क्षणों में overload पैदा करने वाले bursts, दुनिया भर की holidays के बारे में बताने वाले fake anomaly-detection alerts जैसी चीज़ें
      उन सभी ideas के नीचे complexity की ऐसी उलझन होती है जिसे लगभग हर कोई कम आँकता है
    • मोटे तौर पर सहमत हूँ
      यह उन system ideas की list है जो पहले सोचने से ज्यादा कठिन हैं, और जिन्हें गंभीरता से लेना चाहिए, हल्के में नहीं
      “अच्छा दिखता है लेकिन लगभग कभी काम नहीं करता” से धुंधला-सा मिलता-जुलता लगता है, लेकिन details में बिल्कुल अलग है
      अगर इसे कठिन problem मानकर उसी हिसाब से invest किया जाए, तो इसका ठीक से काम करना एक सामान्य रूप से हासिल किया जा सकने वाला outcome है
      अगर यह बाद में जोड़ा गया feature हो या भोलेपन में आसान समझ लिया जाए, तो अक्सर गलत हो जाता है
    • मुझे यह “निराशावाद और थकी हुई cynicism” जैसा नहीं पढ़ता
      यह मुझे engineers के premature optimization में उलझने की कहानी लगती है, जबकि business benefit नहीं होता
      industry में यह सचमुच बहुत फैला हुआ है, क्योंकि redundantly auto-scaling spaceship design और build करना मज़ेदार है, जबकि कुछ घंटों में deploy हो सकने वाला backup तैयार कर लेने और servers को 200% over-provision करने से cost दसवें हिस्से से भी कम रह सकती है
      ऐसे ideas कभी-कभी valid होते हैं, लेकिन तब जब उनकी जरूरत पड़ चुकी हो
      initial product stage में इन्हें पहले से design करके डालने वाली बात नहीं है
      इन implementations जिन scale, availability और complexity को solve करना चाहती हैं, उनकी सच में जरूरत बहुत कम products को होती है
    • Steven शायद यह नहीं कह रहे कि ये चीज़ें impossible हैं, बल्कि यह कि ये कठिन हैं और असामान्य रूप से अक्सर ठीक से नहीं निकलतीं
  • यहाँ बहुत से लोग exceptions को अलग करने वाला कोई नाज़ुक judgment function खोजने की कोशिश कर रहे लगते हैं, जबकि सच में बात आसान है
    ये ideas मैं करूँ तो शानदार हैं, और मुझसे पहले वाला मूर्ख करे तो कभी intended तरीके से काम नहीं करते

    • बिल्कुल यही बात लगती है
      और कभी-कभी वह पहले वाला मूर्ख कुछ महीने पहले का मैं ही होता हूँ
  • मैं इसमें Domain-Driven Design भी जोड़ना चाहूँगा
    application को business structure से match कराने की कोशिश में business design को freeze कर देना disaster का formula है
    छोटा या ठहरा हुआ business हो तो शायद problem महसूस न हो
    लेकिन business सफल हो या grow करे, तो आप जल्द ही regret करेंगे कि आपने बेहद descriptive नामों वाले ऐसे domains बनाने की कोशिश की जो पहले से outdated work practices से बंधे हैं
    इसके बजाय दशकों से proven तरीके के अनुसार functional layers के around design करना, और business logic को जितना हो सके configuration, database rows और user workflows में रखना कहीं ज्यादा flexible है

    • दोनों विकल्पों पर पछतावा होगा
      Domain-Driven Design की pitfalls के रूप में outdated language और नए experiments के लिए low code/system reusability बताई गई, लेकिन उल्टा, business logic को configuration और workflows वगैरह में हर जगह डालने वाला highly abstract design भी तभी flexible होता है जब पूरी organization उस abstraction, configuration और अनगिनत combinations को काफी अच्छी तरह समझती हो
      वे combinations तेज़ी से maze की तरह explode होते हैं और ऐसी unknown, unexpected behavior पैदा करते हैं जिस पर लोग निर्भर होने लगते हैं
      नए developers की onboarding और dev teams बदलने की cost भी संभालना मुश्किल हो जाता है
      organization दो अलग-अलग languages बोलने लगती है
      ऊपर से simple दिखने वाली अधिकांश feature requests या तो abstraction तोड़ने पर विशाल system redesign बन जाती हैं, या “अभी के लिए इस abstraction को बस hack कर दो ताकि यह ज्यादा safe और छोटा change लगे” बन जाती हैं
      पहला विकल्प हमेशा बहुत कठिन होता है, भले ही आपके पास पूरे system के behavior और codebase को पूरी तरह समझने वाले बेहतरीन engineers और शानदार engineering practices/processes हों, और इसमें महीनों या सालों लग सकते हैं
      दूसरा ज्यादा बार होता है, और इसलिए “highly abstracted, functional-layered, config-driven और emergent business logic वाले” projects शुरुआत में perfect और flexible दिखते हैं, लेकिन आखिर में “ये आखिर है क्या” बन जाते हैं
      system implement हो जाने के बाद वही emergent business logic वह language बन जाती है जो हर कोई बोलता है
      अगर organization दो-तीन ऐसी languages बोलती है जिनमें बिल्कुल मेल नहीं बैठ सकता, तो बहुत दर्द होता है, और जब तक आपके पास कई लोग न हों जो ऊपर-नीचे और आसपास उनके बीच fluently translate कर सकें, आपको लगेगा कि domain को ज्यादा करीब से express करना चाहिए था
    • “impossible states को unrepresentable बनाओ” भी इसमें शामिल है
      अगर आप कोई state type में represent न हो सके ऐसा design करते हैं, तो आपको भरोसा होना चाहिए कि उस design के पूरे lifetime में वह state सचमुच impossible state ही रहेगी
  • load पर react करने वाले control loop वाले item को मैं ठीक से समझ नहीं पा रहा
    यह अनगिनत systems का basic और fundamental building block है
    1800s के steam engines या 1900s के Victrola record players में लगे centrifugal governor भी load-reactive control loops हैं
    पूरी electronics load-reactive control loops का जाल है, और car automatic transmission भी ऐसा ही है

    • आम problem यह है कि signal को पर्याप्त समझे बिना control loop जोड़ दिया जाता है, या दूसरे control loops को ध्यान में रखे बिना जोड़ा जाता है
      CPU utilization एक दिलचस्प example है
      उदाहरण के लिए आप cross-region load balancer को process-internal load shedding से लड़ते देख सकते हैं
      क्योंकि load balancer का signal load shedding को reflect नहीं करता, या गलत तरीके से reflect करता है
      एक और problem यह है कि service-local result को optimize करने की कोशिश करने वाला control loop overall result को नुकसान पहुँचाता है
      कुल मिलाकर, मेरे हिसाब से कम संख्या में control loops को high-impact जगहों पर रखना बेहतर है
    • पूरी तरह clear नहीं है, लेकिन शायद खास तौर पर CPU load की बात हो सकती है
      CPU load में कुछ problems हैं, जैसा https://arxiv.org/abs/2312.10172 में बताया गया है
  • इन समस्याओं में एक common pattern है
    ये सभी orthogonal concerns हैं, जो programmers के परिचित sequential data processing programming model पर constraints जोड़ते हैं
    हर बार कोई constraint जोड़ने पर, बाद के सभी developers को उस system में आगे development करते समय लगातार और चीज़ों के बारे में सोचना पड़ता है
    system के over-constrained हो जाने और ऐसी स्थिति में फँस जाने की संभावना रहती है जहाँ कुछ constraints हटाए बिना आगे बढ़ना मुश्किल हो जाता है
    असंभव न भी हो, तो धीमा हो जाता है
    क्योंकि developer को हर बार सोचना पड़ता है कि नया feature पहले से support करने का वादा किए गए API, security, synchronization, latency, दूसरे platforms, और native code के साथ कैसे interact करेगा
    इसलिए इन सभी properties को support करना संभव भी है
    उदाहरण के लिए, अगर transparent data synchronization को platform का core value proposition बनाया जाए, तो आगे की सारी development पहले उसे support करेगी और उन्हीं constraints के भीतर possible feature set को evolve करेगी
    हो सकता है वह feature set users की ठीक-ठीक चाहत जैसा न हो, लेकिन वही इसका supported scope है
    product उन customers को आकर्षक लगेगा जिनके लिए खरीद निर्णय में यह property पहली प्राथमिकता है

  • मैंने कई DSLs, P2P cache, और mixed parallelism इस्तेमाल करने वाले projects किए हैं, और वे सभी काम करते थे
    उन्हें बनाना भी सच में बहुत मज़ेदार था
    एक exception छोड़कर, वे अच्छे investments थे
    P2P cache की ज़रूरत नहीं थी, इसलिए अंत में उससे खास return नहीं मिला
    इसलिए यह कहना कि ऐसी चीज़ें लगभग कभी काम नहीं करतीं, साफ़ तौर पर गलत है
    ये complex हैं, लेकिन वह complexity ऐसी functionality लाती है जिसे दूसरे तरीकों से पाना मुश्किल है
    P2P cache वाले example से मिला lesson यह है कि पहले यह पक्का कर लेना चाहिए कि उस functionality की वाकई ज़रूरत है या नहीं

  • इनमें से काफी ideas को सफलतापूर्वक execute कर चुका हूँ, इसलिए यह थोड़ा अजीब पढ़ा जाता है

    • या तो आपको सचमुच बहुत अच्छी तरह पता है कि आप क्या कर रहे हैं, या फिर सचमुच बिल्कुल नहीं पता—इनमें से एक ही बात है
  • “बस data sync कर देते हैं” मेरे हिसाब से कठिन दिनों के मौजूद होने की वजह है
    मैंने बहुत सारे systems देखे हैं जिनमें “internet scale” जैसी चीज़ को ध्यान में रखकर queues और event processing वगैरह जोड़ दिए गए, जबकि असली natural scope उस threshold से कहीं कम होता है
    ऐसी teams या तो भोली होती हैं, या worst case में engineering न जानने वाली management का फायदा उठाकर मज़े के लिए इन समस्याओं से खेलने का पैसा जुटा रही होती हैं

    • “बस data sync कर देते हैं” मुझे ऐसा लगा जैसे एक तरफ read और दूसरी तरफ write करते हुए भोलेपन से उम्मीद की जा रही हो कि दो sources of truth अलग-अलग नहीं होंगे
      इसे सही ढंग से करना हो तो queues और event processing अनिवार्य हैं