Forwarded from نمای پشت صحنه
توی سیستم های توزیع شده همونطور که میدونید ما یه چیزی داریم به اسم load balancer که میاد جلوی سرورا قرار میگیره و request هایی که میان رو بین سرورا پخش میکنه. حالا چجوری و با چه منطقی پخش میکنه؟
اینا مرسوم ترین روش ها هستن حالا بسته به وضعیت میشه هر کدوم یا ترکیبی ازشون رو انتخاب کرد:
1️⃣ Round Robin
درخواستها یکی یکی و به ترتیب بین سرورها تقسیم میشن. ساده و رایج هست، ولی توان سرورها رو در نظر نمیگیره.
2️⃣ Weighted Round Robin
همون Round Robin ولی سرورهای قویتر درخواست های بیشتری میگیرن. اینطوری فشار متعادل تر پخش میشه.
3️⃣ Least Connections
هر درخواست جدید به سروری میره که کمترین Connection فعال رو داره. برای کارهایی که زمان پردازش متغیر دارن خیلی خوبه.
4️⃣ IP Hash
این روش میاد IP کاربر رو هش میکنه و توی رنج تعداد سرور ها میزاره مثلا۱۰ تا سرور داریم میشه ۱ تا ۱۰ و request های یک IP همیشه به یه سرور میرن . این روش برای Session ها یا وب اپلیکیشن هایی که state دارن مفیده.
5️⃣ Least Response Time
درخواستها به سمتی میرن که هم تعداد Connection کمتر باشه و هم response time سریع تر. مناسب برای سرویسهای حساس به Performance.
اینا مرسوم ترین روش ها هستن حالا بسته به وضعیت میشه هر کدوم یا ترکیبی ازشون رو انتخاب کرد:
1️⃣ Round Robin
درخواستها یکی یکی و به ترتیب بین سرورها تقسیم میشن. ساده و رایج هست، ولی توان سرورها رو در نظر نمیگیره.
2️⃣ Weighted Round Robin
همون Round Robin ولی سرورهای قویتر درخواست های بیشتری میگیرن. اینطوری فشار متعادل تر پخش میشه.
3️⃣ Least Connections
هر درخواست جدید به سروری میره که کمترین Connection فعال رو داره. برای کارهایی که زمان پردازش متغیر دارن خیلی خوبه.
4️⃣ IP Hash
این روش میاد IP کاربر رو هش میکنه و توی رنج تعداد سرور ها میزاره مثلا۱۰ تا سرور داریم میشه ۱ تا ۱۰ و request های یک IP همیشه به یه سرور میرن . این روش برای Session ها یا وب اپلیکیشن هایی که state دارن مفیده.
5️⃣ Least Response Time
درخواستها به سمتی میرن که هم تعداد Connection کمتر باشه و هم response time سریع تر. مناسب برای سرویسهای حساس به Performance.
👍12❤7
درمورد Descriptor چی می دونیم؟
چطوری میتوان رفتارهای ویژگیهای مرتبط به یک کلاس را مدیریت کرد؟ چطوری میتوانیم کاری کنیم که ویژگیهای متفاوت کلاسهای مختلف به شکلی یکسان مدیریت شوند؟
ما در حالت ساده هیچ کنترلی روی ویژگی (Attribute) هایی که یک کلاس دارد نداریم.
وقتی شما کلاسی دارید که یک ویژگی به نام x دارد، هنگام کار با نمونههای ساختهشده از این کلاس میتوان هر مقداری را به این ویژگی نسبت داد.
مثلاً فرضکنید که ما یک کلاس به نام Person داریم که مقدار سن شخص در آن نگهداری میشود:
حالا ما موقع ساخت یک نمونه از این کلاس میتوانیم «هرچیزی» را به آن نسبت بدهیم:
در حالت ساده ما هیچ کنترلی روی ویژگیها نداریم. پس تمام نمونههای بالا از نظر زبان پایتون درست هستند. امّا این مقادیر منطق برنامهی ما را خراب میکنند.
شما میتوانید برای اعتبارسنجی (Validation) مقادیر کدهای اضافیای را درون init قرار بدهید. امّا آن کدها دیگر تغییرات مقادیر را پس از ساخت شئ کنترل نمیکنند.
حتّی میتوانید متدهایی برای اعتبارسنجی درون کلاستان بگذارید. امّا این کار تنها استفاده از کدتان را برای دیگران سختتر میکند و همواره این احتمال وجود دارد که برنامهنویس فراموش کند که پس از هرتغییری در هر جای کد، آن متدها را فراخوانی کند.
از این مورد بگذریم.
فرضکنید که شما میخواهید یک ویژگی درون کلاس A همیشه عدد مثبت باشد. حالا در جای دیگر برنامه نیازدارید که چند ویژگی کلاس B هم درست همین خاصیّت را داشته باشند.
کلاسهای A و B هم هیچ ربط منطقیای ندارند و نمیتوان به مواردی مثل ارثبری حتّی فکر کرد.
عالی نبود اگر میشد کاری کرد که ویژگیهای کلاس های مختلف، بدون اینکه به هم ربطی پیدا کنند، به یک شکل مدیریت شوند؟
خب Descriptor پروتکلی است که همهی این کارها را برای ما میکند.
پروتکل Descriptor خیلی ساده است. هر کلاسی که حداقل یکی از متدهای: set، get یا delete را پیادهسازی کند یک Descriptor حساب میشود.
کاربردها و مثال های Descriptor رو خودتون بخونید.
از سایت علی حسینی کپی کردم. این لینک
میخوام یه قابلیت ساده که توی جنگو هست رو توضیح بدم.
اما قبلش اگه بدونیم Descriptor چیه، یادگرفتنش باحال تر میشه.
پس اگه عمری بود، بقیه در پست های بعدی...
اسپانسر این قسمت 👈 لینک
چطوری میتوان رفتارهای ویژگیهای مرتبط به یک کلاس را مدیریت کرد؟ چطوری میتوانیم کاری کنیم که ویژگیهای متفاوت کلاسهای مختلف به شکلی یکسان مدیریت شوند؟
ما در حالت ساده هیچ کنترلی روی ویژگی (Attribute) هایی که یک کلاس دارد نداریم.
وقتی شما کلاسی دارید که یک ویژگی به نام x دارد، هنگام کار با نمونههای ساختهشده از این کلاس میتوان هر مقداری را به این ویژگی نسبت داد.
مثلاً فرضکنید که ما یک کلاس به نام Person داریم که مقدار سن شخص در آن نگهداری میشود:
class Person:
def __init__(self, age):
self.age = age
حالا ما موقع ساخت یک نمونه از این کلاس میتوانیم «هرچیزی» را به آن نسبت بدهیم:
person1 = Person(10000)
person2 = Person(-10)
person3 = Person("I am not even an integer!")
در حالت ساده ما هیچ کنترلی روی ویژگیها نداریم. پس تمام نمونههای بالا از نظر زبان پایتون درست هستند. امّا این مقادیر منطق برنامهی ما را خراب میکنند.
شما میتوانید برای اعتبارسنجی (Validation) مقادیر کدهای اضافیای را درون init قرار بدهید. امّا آن کدها دیگر تغییرات مقادیر را پس از ساخت شئ کنترل نمیکنند.
حتّی میتوانید متدهایی برای اعتبارسنجی درون کلاستان بگذارید. امّا این کار تنها استفاده از کدتان را برای دیگران سختتر میکند و همواره این احتمال وجود دارد که برنامهنویس فراموش کند که پس از هرتغییری در هر جای کد، آن متدها را فراخوانی کند.
از این مورد بگذریم.
فرضکنید که شما میخواهید یک ویژگی درون کلاس A همیشه عدد مثبت باشد. حالا در جای دیگر برنامه نیازدارید که چند ویژگی کلاس B هم درست همین خاصیّت را داشته باشند.
کلاسهای A و B هم هیچ ربط منطقیای ندارند و نمیتوان به مواردی مثل ارثبری حتّی فکر کرد.
عالی نبود اگر میشد کاری کرد که ویژگیهای کلاس های مختلف، بدون اینکه به هم ربطی پیدا کنند، به یک شکل مدیریت شوند؟
خب Descriptor پروتکلی است که همهی این کارها را برای ما میکند.
پروتکل Descriptor خیلی ساده است. هر کلاسی که حداقل یکی از متدهای: set، get یا delete را پیادهسازی کند یک Descriptor حساب میشود.
کاربردها و مثال های Descriptor رو خودتون بخونید.
از سایت علی حسینی کپی کردم. این لینک
میخوام یه قابلیت ساده که توی جنگو هست رو توضیح بدم.
اما قبلش اگه بدونیم Descriptor چیه، یادگرفتنش باحال تر میشه.
پس اگه عمری بود، بقیه در پست های بعدی...
اسپانسر این قسمت 👈 لینک
👏6❤2👍2
جنگولرن
وات ایز F() expressions در جنگو 😁 جنگو در مورد تابع F توی داکیومنت میگه: An F() object represents the value of a model field, transformed value of a model field, or annotated column. It makes it possible to refer to model field values and perform database…
نکته ای از عثمان در مورد پست F
ی مورد دیگه که خود جنگو داره از F object استفاده میکنه زمانیه که شما سعی میکنی ی رکورد جدید توی تیبل ایجاد کنی که اگه همون موقع بدون کال کردن refresh_from_db بیای یکی از فیلدهای رکورد جدید رو تو ی کوئری یا ایجاد رکورد تو ی جدول دیگه استفاده کنی توی کوئری یا ترنزکشنت ORM میاد دقیقا به اسم همون فیلد ترجمه میکنه، مثال:
شما فکر کنید ی تیبل به اسم Stock دارید و ی تیبل دیگه به اسم StockLog
فیلدهای استاک:
quantity
quantity_allocated
فیلدهای استاک لاگ:
initial_quantity
final_quantity
حالا شما ی رکورد جدید تو تیبل استاک می سازید:
stock = Stock.objects.create(quantity=10, quantity_allocated=0)
و میای بعدش میگی:
StockLog.objects.create(initial_quantity=0, final_quantity=stock.quantity)
Orm -> insert into stocklog(initial_quantity, quantity) values(0, 10)
اینجا حتما باید حواست به رفرش قبل اساین باشه
ی مورد دیگه که خود جنگو داره از F object استفاده میکنه زمانیه که شما سعی میکنی ی رکورد جدید توی تیبل ایجاد کنی که اگه همون موقع بدون کال کردن refresh_from_db بیای یکی از فیلدهای رکورد جدید رو تو ی کوئری یا ایجاد رکورد تو ی جدول دیگه استفاده کنی توی کوئری یا ترنزکشنت ORM میاد دقیقا به اسم همون فیلد ترجمه میکنه، مثال:
شما فکر کنید ی تیبل به اسم Stock دارید و ی تیبل دیگه به اسم StockLog
فیلدهای استاک:
quantity
quantity_allocated
فیلدهای استاک لاگ:
initial_quantity
final_quantity
حالا شما ی رکورد جدید تو تیبل استاک می سازید:
stock = Stock.objects.create(quantity=10, quantity_allocated=0)
و میای بعدش میگی:
StockLog.objects.create(initial_quantity=0, final_quantity=stock.quantity)
Orm -> insert into stocklog(initial_quantity, quantity) values(0, 10)
اینجا حتما باید حواست به رفرش قبل اساین باشه
✍5🤔3❤1
چرا ذهن ما عاشق Abstraction زودهنگام است؟
خیلی وقتها در تیمهای نرمافزاری میبینیم که مهندسان خیلی زود به سراغ abstraction و generalization میروند. یعنی قبل از اینکه حتی نیاز واقعی شکل بگیرد، یک لایه انتزاعی طراحی میکنند تا برای آینده آماده باشند.
این رفتار بیدلیل نیست. ذهن ما از نظر تکاملی عادت دارد الگوها را سریع تشخیص دهد و تعمیم دهد. همین باعث شده است که حتی وقتی دو سناریوی مشابه میبینیم، ناخودآگاه به فکر ساختن یک راهحل عمومی میافتیم. در زندگی روزمره این توانایی به بقای ما کمک کرده، اما در دنیای نرمافزار همیشه مفید نیست.
مشکل اصلی اینجاست که وقتی زود abstraction بسازیم، سطح اشتباه را انتخاب میکنیم. نه آنقدر بالا که به درد بخورد، نه آنقدر دقیق که واقعاً نیاز را برطرف کند. نتیجه این میشود که کدی مینویسیم که پیچیدهتر از چیزی است که لازم داریم، و سرعت یادگیری و تغییر را پایین میآورد.
در عین حال، فرهنگ و فضای آموزشی هم این عادت را تقویت میکند. همه جا به ما گفتهاند تکرار بد است یا باید برای reuse طراحی کنی. در حالی که در بسیاری از موقعیتها بهترین کار این است که ابتدا با سادهترین راهحل شروع کنیم و بعد، وقتی چند بار نیاز تکرار شد و الگو روشن شد، سراغ abstraction برویم.
به جای پیشبینی آینده، باید برای تغییر آماده باشیم. به جای اینکه یک معماری عمومی از روز اول طراحی کنیم، بهتر است ساختار را طوری بچینیم که refactor راحت باشد. یعنی اول مسأله را حل کنیم، بعد اگر دیدیم الگو دارد تکرار میشود، abstraction را بسازیم.
آیا ما واقعاً میخواهیم برای آیندهای که هنوز نیامده هزینه بدهیم؟ یا میخواهیم امروز ساده شروع کنیم و اجازه بدهیم کد و معماری با واقعیت رشد کند؟
✍🏻 Kayvan Alimohammadi
خیلی وقتها در تیمهای نرمافزاری میبینیم که مهندسان خیلی زود به سراغ abstraction و generalization میروند. یعنی قبل از اینکه حتی نیاز واقعی شکل بگیرد، یک لایه انتزاعی طراحی میکنند تا برای آینده آماده باشند.
این رفتار بیدلیل نیست. ذهن ما از نظر تکاملی عادت دارد الگوها را سریع تشخیص دهد و تعمیم دهد. همین باعث شده است که حتی وقتی دو سناریوی مشابه میبینیم، ناخودآگاه به فکر ساختن یک راهحل عمومی میافتیم. در زندگی روزمره این توانایی به بقای ما کمک کرده، اما در دنیای نرمافزار همیشه مفید نیست.
مشکل اصلی اینجاست که وقتی زود abstraction بسازیم، سطح اشتباه را انتخاب میکنیم. نه آنقدر بالا که به درد بخورد، نه آنقدر دقیق که واقعاً نیاز را برطرف کند. نتیجه این میشود که کدی مینویسیم که پیچیدهتر از چیزی است که لازم داریم، و سرعت یادگیری و تغییر را پایین میآورد.
در عین حال، فرهنگ و فضای آموزشی هم این عادت را تقویت میکند. همه جا به ما گفتهاند تکرار بد است یا باید برای reuse طراحی کنی. در حالی که در بسیاری از موقعیتها بهترین کار این است که ابتدا با سادهترین راهحل شروع کنیم و بعد، وقتی چند بار نیاز تکرار شد و الگو روشن شد، سراغ abstraction برویم.
به جای پیشبینی آینده، باید برای تغییر آماده باشیم. به جای اینکه یک معماری عمومی از روز اول طراحی کنیم، بهتر است ساختار را طوری بچینیم که refactor راحت باشد. یعنی اول مسأله را حل کنیم، بعد اگر دیدیم الگو دارد تکرار میشود، abstraction را بسازیم.
آیا ما واقعاً میخواهیم برای آیندهای که هنوز نیامده هزینه بدهیم؟ یا میخواهیم امروز ساده شروع کنیم و اجازه بدهیم کد و معماری با واقعیت رشد کند؟
✍🏻 Kayvan Alimohammadi
✍5❤5👍1