جنگولرن
3.81K subscribers
287 photos
74 videos
31 files
556 links
آموزش Django و بستگان
Download Telegram
وات ایز 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 operations using them without actually having to pull them out of the database into Python memory.
Django uses the F() object to generate an SQL expression that describes the required operation at the database level.

آخرش چی گفته؟ database level

این تابع برای مواقعی به درد میخوره که ممکنه همزمانی یا Concurrency پیش بیاد.
مثلا یه جایی میخواییم از انبار یه محصول کم کنیم، همزمان یه ریکوئست دیگه میاد که اونم میخواد کم کنه.
حالت عادی و بدون استفاده از F ، چون آبجکت توی مموری اومده و مثلا مقدار انبار 10 هست، هر دو از آبجکت توی مموری کم میکنن،
لذا انبار 9 میشه 😳
ولی با F مستقیم آپدیت روی رکورد زده میشه.

پیچوندمش؟ 😅 یه مثال:

فرض کن یه مدل داریم:
class Product(models.Model):
name = models.CharField(max_length=100)
stock = models.IntegerField(default=0)

حالا بخوایم یه محصول رو یه دونه کم کنیم:
product = Product.objects.get(id=1)
product.stock = product.stock - 1
product.save()

مشکل:
اگر دو درخواست هم‌زمان این کار رو بکنن، ممکنه هر دو یک مقدار قدیمی بخونن (مثلاً stock=10) و بعد از save، نتیجه بشه stock=9، در حالی که باید 8 می‌شد!
این همون مشکل همزمانی (Concurrency ) هست.

با F اینجوری میشه:
from django.db.models import F

Product.objects.filter(id=1).update(stock=F('stock') - 1)

اینجا F('stock') به دیتابیس می‌گه:
«به جای اینکه مقدار stock رو بیارم تو پایتون و دوباره بنویسم، مستقیماً در سطح دیتابیس مقدار فیلد رو یکی کم کن.»

این کار باعث می‌شه اتمیک (atomic) باشه و نیازی به lock دستی یا نگرانی از race condition نباشه.

راستی این lock باعث Deadlock نمیشه.
چون Deadlock وقتی پیش میاد که دو یا چند تراکنش هم‌زمان قفل منابع مختلف رو بگیرن و هرکدوم منتظر آزاد شدن قفل اونوری بمونن.
👍96🆒31
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.
👍84