مخازن تک: لطفا، باید

مخازن تک: لطفا، باید

ترجمه مقاله تهیه شده برای دانشجویان دوره "روش ها و ابزارهای DevOps" در پروژه آموزشی OTUS.

شما باید یک مخزن تک را انتخاب کنید زیرا رفتاری که در تیم های شما ترویج می کند، شفافیت و مسئولیت مشترک است، به خصوص با رشد تیم ها. در هر صورت، باید روی ابزارسازی سرمایه‌گذاری کنید، اما همیشه بهتر است رفتار پیش‌فرض، رفتاری باشد که در دستورات خود می‌خواهید.

چرا در این مورد صحبت می کنیم؟

مت کلاین مقاله را نوشت "Monorepos: لطفا این کار را نکنید!"  (یادداشت مترجم: ترجمه در هابره "Monorepositories: لطفا این کار را نکنید"). من مت را دوست دارم، به نظر من او بسیار باهوش است و باید دیدگاه او را بخوانید. او ابتدا این نظرسنجی را در توییتر منتشر کرد:

مخازن تک: لطفا، باید

ترجمه:
در این روز سال نو، من قصد دارم در مورد مضحک بودن monorepositories بحث کنم. 2019 بی سر و صدا شروع شد. با توجه به این موضوع، من یک نظرسنجی را به شما پیشنهاد می کنم. متعصبان بزرگ چه کسانی هستند؟ حامیان:
- مونورپو
- زنگ
- نظرسنجی نادرست / هر دو

پاسخ من این بود: "من به معنای واقعی کلمه هر دوی این افراد هستم." به جای صحبت در مورد اینکه Rust چگونه یک دارو است، بیایید ببینیم چرا فکر می کنم او در مورد monorepositories اشتباه می کند. کمی در مورد خودتان من مدیر ارشد فناوری Chef Software هستم. ما حدود 100 مهندس، یک پایه کد به 11-12 سال قبل و 4 محصول اصلی داریم. برخی از این کد در یک چند مخزن (موقعیت شروع من) و برخی در یک مخزن (موقعیت فعلی من) هستند.

قبل از شروع: هر استدلالی که در اینجا مطرح می کنم برای هر دو نوع مخزن اعمال می شود. به نظر من، هیچ دلیل فنی وجود ندارد که چرا باید یک نوع مخزن را بر دیگری انتخاب کنید. شما می توانید هر رویکردی را به کار ببرید. من خوشحالم که در مورد آن صحبت می کنم، اما علاقه ای به دلایل فنی مصنوعی ندارم که چرا یکی از دیگری برتر است.

من با قسمت اول نظر مت موافقم:

زیرا در مقیاس، یک مخزن مونور همان مشکلاتی را حل می‌کند که یک مخزن چندگانه حل می‌کند، اما در عین حال شما را مجبور می‌کند تا کد خود را به‌طور محکمی جفت کنید و به تلاش‌های باورنکردنی برای افزایش مقیاس‌پذیری سیستم کنترل نسخه‌تان نیاز دارد.

شما باید همان مشکلات را بدون توجه به انتخاب یک مخزن یا چند مخزن حل کنید. چگونه انتشارات را منتشر می کنید؟ رویکرد شما برای به روز رسانی چیست؟ سازگاری به عقب؟ وابستگی های متقابل پروژه؟ چه سبک های معماری قابل قبول است؟ چگونه زیرساخت ساخت و آزمایش خود را مدیریت می کنید؟ لیست بی پایان است. و با رشد همه آنها را حل خواهید کرد. پنیر رایگان وجود ندارد.

من فکر می‌کنم استدلال مت شبیه دیدگاه‌های مشترک بسیاری از مهندسان (و مدیران) است که من به آنها احترام می‌گذارم. این از منظر مهندس کار بر روی قطعه یا تیمی که روی قطعه کار می کند رخ می دهد. چیزهایی از این قبیل می شنوید:

  • پایگاه کد حجیم است - من به این همه آشغال نیازی ندارم.
  • تست کردن سخت تر است زیرا باید تمام این آشغال هایی را که به آنها نیاز ندارم آزمایش کنم.
  • کار با وابستگی های خارجی دشوارتر است.
  • من به سیستم های کنترل نسخه مجازی خودم نیاز دارم.

البته همه این نکات قابل توجیه است. این در هر دو مورد اتفاق می افتد - در polyrepository من آشغال های خودم را دارم، علاوه بر موارد مورد نیاز برای ساخت... ممکن است به آشغال های دیگری نیز نیاز داشته باشم. بنابراین من "به سادگی" ابزارهایی را ایجاد می کنم که کل پروژه را بررسی می کند. یا من یک مخزن جعلی با زیر ماژول ها ایجاد می کنم. ما می توانستیم تمام روز در این اطراف قدم بزنیم. اما من فکر می کنم استدلال مت دلیل اصلی را که من به شدت به نفع monorepository ورق زدم را از دست می دهد:

ارتباط را تحریک می کند و مشکلات را نشان می دهد

هنگامی که ما مخازن را جدا می کنیم، عملاً مشکل هماهنگی و شفافیت ایجاد می کنیم. این مربوط به طرز فکر ما در مورد تیم ها است (به ویژه طرز فکر اعضای فردی در مورد آنها): ما مسئول یک جزء خاص هستیم. ما در انزوای نسبی کار می کنیم. مرزها روی تیم من و مؤلفه (هایی) که روی آن کار می کنیم، ثابت شده است.

همانطور که معماری پیچیده تر می شود، یک تیم دیگر نمی تواند آن را به تنهایی مدیریت کند. تعداد بسیار کمی از مهندسان کل سیستم را در سر دارند. فرض کنید یک مؤلفه مشترک A را مدیریت می کنید که توسط تیم های B، C و D استفاده می شود. تیم A در حال بازسازی، بهبود API و همچنین تغییر پیاده سازی داخلی است. در نتیجه، تغییرات با عقب سازگار نیستند. چه توصیه ای دارید؟

  • همه جاهایی که از API قدیمی استفاده می شود را پیدا کنید.
  • آیا مکان هایی وجود دارد که نمی توان از API جدید استفاده کرد؟
  • آیا می توانید اجزای دیگر را تعمیر و تست کنید تا مطمئن شوید که خراب نمی شوند؟
  • آیا این تیم ها می توانند تغییرات شما را در حال حاضر آزمایش کنند؟

لطفاً توجه داشته باشید که این سؤالات مستقل از نوع مخزن هستند. شما باید تیم های B، C و D را پیدا کنید. باید با آنها صحبت کنید، زمان را پیدا کنید، اولویت های آنها را درک کنید. حداقل ما امیدواریم که شما این کار را انجام دهید.

هیچ کس واقعاً نمی خواهد این کار را انجام دهد. این بسیار کمتر از تعمیر API لعنتی سرگرم کننده است. همه چیز انسانی و کثیف است. در یک polyrepository، می‌توانید به سادگی تغییراتی ایجاد کنید، آن را به افرادی که روی آن مؤلفه کار می‌کنند (احتمالاً نه B، C یا D) برای بررسی بدهید و ادامه دهید. تیم های B، C و D فقط می توانند در حال حاضر با نسخه فعلی خود باقی بمانند. وقتی به نبوغ شما پی ببرند تجدید خواهند شد!

در monorepository، مسئولیت به طور پیش فرض جابجا می شود. تیم A جزء خود را تغییر می دهد و اگر مراقب نباشد، فوراً B، C و D را می شکند. این منجر به این می شود که B، C و D در درب A ظاهر شوند و از خود بپرسند که چرا تیم A مونتاژ را شکست. این به A می آموزد که آنها نمی توانند از لیست من در بالا بگذرند. آنها باید در مورد کاری که قرار است انجام دهند صحبت کنند. آیا B، C و D می توانند حرکت کنند؟ اگر B و C می توانند، اما D ارتباط نزدیکی با یک عارضه جانبی رفتار الگوریتم قدیمی دارد، چه می شود؟

سپس باید در مورد اینکه چگونه از این وضعیت خارج خواهیم شد صحبت کنیم:

  1. از چندین API داخلی پشتیبانی می‌کند و تا زمانی که D نتواند از آن استفاده نکند، الگوریتم قدیمی را به‌عنوان منسوخ علامت‌گذاری می‌کند.
  2. پشتیبانی از نسخه های چندگانه، یکی با رابط قدیمی، یکی با نسخه جدید.
  3. انتشار تغییرات A را تا زمانی که B، C و D بتوانند به طور همزمان آن را بپذیرند به تاخیر بیاندازید.

فرض کنید 1، چندین API را انتخاب کرده ایم. در این مورد ما دو قطعه کد داریم. قدیمی و جدید. در برخی شرایط بسیار راحت است. کد قدیمی را دوباره بررسی می‌کنیم، آن را به‌عنوان منسوخ علامت‌گذاری می‌کنیم و با تیم D بر سر یک برنامه حذف توافق می‌کنیم. اساساً برای مخازن پلی و مونو یکسان است.

برای انتشار چندین نسخه، به یک شعبه نیاز داریم. اکنون دو جزء داریم - A1 و A2. تیم های B و C از A2 و D از A1 استفاده می کنند. ما نیاز داریم که همه مؤلفه‌ها آماده انتشار باشند، زیرا ممکن است قبل از اینکه D بتواند به جلو حرکت کند، به‌روزرسانی‌های امنیتی و رفع اشکال دیگر مورد نیاز باشد. در یک مخزن چندگانه، می‌توانیم این را در شاخه‌ای با عمر طولانی پنهان کنیم که حس خوبی دارد. در monorepository، کد را مجبور می‌کنیم که در یک ماژول جدید ایجاد شود. تیم D همچنان باید تغییراتی در مولفه "قدیمی" ایجاد کند. همه می توانند هزینه ای که ما می پردازیم را در اینجا ببینند - اکنون دو برابر بیشتر کد داریم، و هر گونه رفع اشکالی که برای A1 و A2 اعمال می شود باید برای هر دوی آنها اعمال شود. با رویکرد انشعاب در یک مخزن چندگانه، این در پشت گیلاس چیدن پنهان است. ما هزینه را کمتر می دانیم زیرا تکراری وجود ندارد. از نقطه نظر عملی، هزینه یکسان است: شما دو پایگاه کد تا حد زیادی یکسان را می سازید، آزاد می کنید و حفظ می کنید تا زمانی که بتوانید یکی از آنها را حذف کنید. تفاوت این است که با تک مخزن این درد مستقیم و قابل مشاهده است. این حتی بدتر است، و این خوب است.

بالاخره به نکته سوم رسیدیم. تاخیر در انتشار ممکن است تغییرات ایجاد شده توسط A زندگی تیم A را بهبود بخشد. مهم، اما فوری نیست. آیا می توانیم فقط تاخیر داشته باشیم؟ در یک polyrepository، این را فشار می دهیم تا آرتیفکت را پین کنیم. البته ما این را به تیم D می گوییم. فقط در نسخه قدیمی بمانید تا زمانی که به نتیجه برسید! این شما را آماده می کند تا نقش ترسو را بازی کنید. تیم A به کار بر روی جزء خود ادامه می دهد و این واقعیت را نادیده می گیرد که تیم D از یک نسخه قدیمی استفاده می کند (این مشکل تیم D است، آنها احمق هستند). در همین حال، تیم D در مورد نگرش بی دقت تیم A نسبت به ثبات کد، اگر اصلاً در مورد آن صحبت کنند، ضعیف صحبت می کند. ماه ها می گذرد در نهایت، تیم D تصمیم می گیرد به امکان به روز رسانی نگاه کند، اما A فقط تغییرات بیشتری دارد. تیم A به سختی به یاد می آورد که چه زمانی و چگونه D را شکستند. ارتقاء دردناک تر است و زمان بیشتری می برد. که آن را بیشتر در پشته اولویت می فرستد. تا روزی که در الف مشکل امنیتی داشته باشیم که مجبوریم شعبه بسازیم. تیم A باید به گذشته برگردد، نقطه ای را پیدا کند که D پایدار بوده، مشکل را در آنجا حل کند و آن را برای انتشار آماده کند. این انتخاب واقعی مردم است و بدترین انتخاب است. به نظر می رسد که هم برای تیم A و هم برای تیم D خوب است تا زمانی که بتوانیم یکدیگر را نادیده بگیریم.

در monorepository، سومی واقعاً یک گزینه نیست. شما مجبور هستید به یکی از دو روش با شرایط کنار بیایید. باید هزینه های داشتن دو شعبه انتشار را ببینید. یاد بگیرید که از خود در برابر به‌روزرسانی‌هایی که سازگاری قبلی را خراب می‌کنند محافظت کنید. اما مهمتر از همه: شما نمی توانید از داشتن یک مکالمه دشوار اجتناب کنید.

طبق تجربه من، وقتی تیم ها بزرگ می شوند، دیگر نمی توان کل سیستم را در ذهن داشت و این مهمترین بخش است. شما باید دید اختلاف را در سیستم بهبود بخشید. شما باید فعالانه تلاش کنید تا تیم ها به اجزای خود نگاه کنند و به کار تیم ها و مصرف کنندگان دیگر نگاه کنند.

بله، شما می توانید ابزارهایی ایجاد کنید که سعی در حل مشکل polyrepository دارند. اما تجربه من در آموزش تحویل مداوم و اتوماسیون در شرکت های بزرگ این را به من می گوید: رفتار پیش فرض بدون استفاده از ابزارهای اضافی، رفتاری است که انتظار دارید ببینید. رفتار پیش‌فرض یک polyrepository جداسازی است، این کل نکته است. رفتار پیش‌فرض یک مخزن تک، مسئولیت مشترک و شفافیت است، این کل نکته است. در هر دو مورد، من قصد دارم ابزاری ایجاد کنم که لبه های ناهموار را صاف کند. به‌عنوان یک رهبر، هر بار یک مخزن تکی انتخاب می‌کنم زیرا ابزارها باید فرهنگ مورد نظر من را تقویت کنند و فرهنگ از تصمیم‌های کوچک و کار روزانه تیم ناشی می‌شود.

فقط کاربران ثبت نام شده می توانند در نظرسنجی شرکت کنند. ورود، لطفا.

بزرگترین متعصبان چه کسانی هستند؟ حامیان:

  • مونورپو

  • زنگ

  • نظرسنجی نادرست / هر دو

33 کاربر رای دادند. 13 کاربر رای ممتنع دادند.

منبع: www.habr.com

اضافه کردن نظر