خب این پست یه توضیح خلاصه و جمع و جور بود.
تو پست های بعدی وارد عمق این داستان میشیم
تو پست های بعدی وارد عمق این داستان میشیم
🔥10
Forwarded from 👾 Geek Engineers ([ Taha. Dostifam ])
Cyrus: A high-performance, statically-typed, manually memory-managed and procedural programming language empowered by GCCJIT. Made with Rust 🦀.
برای حمایت از ما میتونید توی گیت هاب ⭐️ بدید که خیلی به دیده شدنش توی explore گیت هاب کمک میکنه. همینطور اگر با دوستاتون شیر کنید خیلی خوشحال میشیم =) ❤️🤌🏿
Community:
@cyrus_lang
GitHub:
https://github.com/cyrus-lang/Cyrus-Lang
برای حمایت از ما میتونید توی گیت هاب ⭐️ بدید که خیلی به دیده شدنش توی explore گیت هاب کمک میکنه. همینطور اگر با دوستاتون شیر کنید خیلی خوشحال میشیم =) ❤️🤌🏿
Community:
@cyrus_lang
GitHub:
https://github.com/cyrus-lang/Cyrus-Lang
❤15👍1
👾 Geek Engineers
Cyrus: A high-performance, statically-typed, manually memory-managed and procedural programming language empowered by GCCJIT. Made with Rust 🦀. برای حمایت از ما میتونید توی گیت هاب ⭐️ بدید که خیلی به دیده شدنش توی explore گیت هاب کمک میکنه. همینطور اگر با…
دوستان طاها واقعا خیلی سر این پروژه زحمت کشید به شخصه شاهدش بودم.
ازش حمایت کنید که خستگیش در بره 😊
ازش حمایت کنید که خستگیش در بره 😊
❤15
دلار ۹۰ هزار تومنی رو کجای دلمون بزاریم :)
هرچند توقعشو داشتم و احتمالا تا قبل عید ۱۰۰ تومنو رد میکنه. (مردم کاری از دستشون برنمیاد)
هرچند توقعشو داشتم و احتمالا تا قبل عید ۱۰۰ تومنو رد میکنه. (مردم کاری از دستشون برنمیاد)
💔28
سلام دوستان 👋
خب، خب، خب... همونطوری که میدونید (یا شاید هنوز نمیدونید 🌚)، همایش فرانت چپتر داره شروع میشه درسته که اسمش پیشوند "فرانت" داره، ولی خبر خوبش اینه که بچههای بکاند هم توش حضور دارن.
شخصاً کلی تعریفش رو شنیدم و به شدت پیشنهاد میکنم که شرکت کنید 🤩 (به فکر پیدا کردن کانکشن باشید بیشتر 🤫)
لینک ثبتنام ایونت 👇:
راستی، یه کد تخفیف ۱۲۳,۰۰۰ تومنی هم براتون گرفتم 😁
کد تخفیف:
Enjoy ❤️
➖➖➖➖➖➖➖➖➖
خب، خب، خب... همونطوری که میدونید (یا شاید هنوز نمیدونید 🌚)، همایش فرانت چپتر داره شروع میشه درسته که اسمش پیشوند "فرانت" داره، ولی خبر خوبش اینه که بچههای بکاند هم توش حضور دارن.
شخصاً کلی تعریفش رو شنیدم و به شدت پیشنهاد میکنم که شرکت کنید 🤩 (به فکر پیدا کردن کانکشن باشید بیشتر 🤫)
لینک ثبتنام ایونت 👇:
🔖 https://frontchapter.ir/event
راستی، یه کد تخفیف ۱۲۳,۰۰۰ تومنی هم براتون گرفتم 😁
کد تخفیف:
ninjalearn
Enjoy ❤️
#⃣ #event
➖➖➖➖➖➖➖➖➖
🥷 CHANNEL | GROUP
👌4❤2👍1👎1
Ninja Learn | نینجا لرن
خب خب خب دکوریتورها (Decorators) در پایتون: تغییر رفتار توابع و کلاسها 🐍 سلام دوستان امروز میخوایم در مورد یکی از ویژگیهای خیلی قوی و در عین حال جذاب پایتون صحبت کنیم: دکوریتورها. این قابلیت به شما اجازه میده تا بدون دست زدن به کد اصلی توابع یا کلاسها،…
میریم اینو کامل تر کنیم و به جزعیات بپردازیم :)
👍9
بعضی دوستان پیشنهاد دادن که کانال ادمین داشته باشه برای تولید محتوای بیشتر.
دیدم ایده بدی نیست.
هرکسی که دوست داره تو کانال تولید محتوا بکنه، درمورد موضوع:
یه پست بنویسه بفرسته به ایدی
@mohammad_strout
بررسی کنم (ساختار و کیفیتش مثل پستای خود کانال باشه)، بین کسایی که فرستادن یه نفر که بهتر بوده رو انتخاب میکنم ادمین کانال بشه و تو پستا کمک کنه.
➖➖➖➖➖➖➖➖➖
دیدم ایده بدی نیست.
هرکسی که دوست داره تو کانال تولید محتوا بکنه، درمورد موضوع:
ساختمان داده ها
یه پست بنویسه بفرسته به ایدی
@mohammad_strout
بررسی کنم (ساختار و کیفیتش مثل پستای خود کانال باشه)، بین کسایی که فرستادن یه نفر که بهتر بوده رو انتخاب میکنم ادمین کانال بشه و تو پستا کمک کنه.
#⃣ #notif
➖➖➖➖➖➖➖➖➖
🥷 CHANNEL | GROUP
👌8👍2
خب خب خب پشت صحنه دکوریتورها در پایتون: چه اتفاقی پشت پرده میافته؟ 🚀
تو پست قبلی یه نگاه کلی به دکوریتورها داشتیم و دیدیم چقدر میتونن کاربردی باشن. ولی بیاین یه کم عمیقتر بشیم و ببینیم وقتی یه دکوریتور روی تابع یا کلاس اعمال میشه، دقیقاً چه اتفاقی پشت صحنه رخ میده؟ حتی قبل از اینکه کد اجرا بشه.
1⃣ پایتون چطوری کد رو اجرا میکنه؟ 📜
قبل از اینکه بریم سراغ دکوریتورها، یه نکته مهم:
پایتون یه زبان مفسریه، یعنی خطبهخط کد رو اجرا میکنه. ولی قبل از اجرا، اول کد رو به بایتکد تبدیل میکنه و بعد اون رو میفرسته برای ماشین مجازی پایتون (PVM).
تو این فرآیند، هر تابع و کلاس یه آبجکت جداگانه توی حافظه میشه و همینجاست که دکوریتورها وارد عمل میشن 🚀
2⃣ دکوریتورها دقیقاً چیکار میکنن؟ 🔧
1⃣ وقتی @ میذاریم، واقعاً چی میشه؟
وقتی یه تابع رو با @my_decorator دکوریت میکنیم، پایتون پشت صحنه این کارو انجام میده:
میشه این:
یعنی تابع اصلی ساخته میشه، بعد به دکوریتور داده میشه و خروجی دکوریتور جایگزین تابع اصلی میشه. این اتفاق در لحظه تعریف تابع رخ میده، نه وقتی تابع اجرا میشه
2⃣ ترتیب اجرا چطوریه؟
وقتی دکوریتور روی تابع اعمال میشه:
پس، از این به بعد هر وقت تابع رو صدا بزنید، در واقع دارید خروجی دکوریتور رو اجرا میکنید، نه تابع اصلی رو
3⃣ چه بلایی سر تابع میاد؟ 🔍
1⃣ تابع اصلی تبدیل میشه به...
هر تابع تو پایتون یه آبجکته، پس دکوریتورها میتونن روش تغییرات زیادی بدن:
قبل از اجرا یه کار انجام بدن (مثلاً لاگ بگیرن).
تابع اصلی رو اجرا کنن.
بعد از اجرا هم یه کار دیگه انجام بدن (مثلاً خروجی رو دستکاری کنن).
یا حتی یه چیز کاملاً جدید برگردونن
در نتیجه، اسم تابع دیگه به اون چیزی که اول تعریف کردید اشاره نمیکنه، بلکه به خروجی دکوریتور اشاره داره.
2⃣ مشکل متادیتا و راهحل functools.wraps
یه مشکل اینه که دکوریتور باعث میشه اطلاعات تابع (مثل نام، توضیحات و...) از بین بره. برای حل این مشکل، باید از functools.wraps استفاده کنیم:
اینطوری، متادیتای تابع اصلی حفظ میشه وdoc __doc__ دسترسی داشت. 😎
3⃣ دکوریتورهای پشت سر هم (Chaining Decorators)
اگه چندتا دکوریتور رو روی یه تابع بذاریم، ترتیبش مهمه. به این مثال دقت کن:
اول decorator_b اجرا میشه و خروجیش میره تو decorator_a. پس ترتیب اجرا به این شکله:
پس، دکوریتوری که پایینتر نوشته شده، زودتر اجرا میشه 🔄
4⃣ پشت صحنه در زمان کامپایل و اجرا 🕒
1⃣ دکوریتور کی اجرا میشه؟
دکوریتورها همون موقعی که تابع یا کلاس تعریف میشه اجرا میشن، نه وقتی که تابع رو صدا میزنید. پس این کد:
در لحظهای که پایتون به این خط کد میرسه، my_decorator(my_func) اجرا میشه و خروجیش جایگزین my_func میشه.
2⃣ ذخیره تابع در فضای نام (Namespace Binding)
بعد از این فرآیند، اسم تابع به تابع دکوریتشده اشاره میکنه. پس اگه تابع اصلی رو نگه نداشته باشید، دیگه بهش دسترسی ندارید
3⃣ تأثیر روی بهینهسازی
چون دکوریتورها میتونن کد تابع رو تغییر بدن، ممکنه باعث بشن که بهینهسازیهایی که پایتون انجام میده، دیگه درست کار نکنه. برای مثال، اگه دکوریتور یه حلقه اضافه کنه یا اجرای تابع رو تغییر بده، بایتکد نهایی کاملاً متفاوت میشه.
5⃣ نکات مهم که باید رعایت کنید 💡
✅ از functools.wraps استفاده کنید
اگه دکوریتورتون متادیتای تابع رو تغییر میده، این کار باعث میشه اطلاعات تابع اصلی حفظ بشه.
✅ ترتیب دکوریتورها مهمه
اگه چند دکوریتور دارید، حتماً ترتیب اجرا رو بررسی کنید که به مشکل نخورید.
✅ موقع اشکالزدایی حواستون باشه
چون دکوریتورها موقع تعریف اجرا میشن، اگه کدتون مشکل داشته باشه، ممکنه سختتر اشکالزدایی بشه. پس بهتره با print یا لاگ گرفتن، مراحل اجرا رو چک کنید.
➖➖➖➖➖➖➖➖➖
تو پست قبلی یه نگاه کلی به دکوریتورها داشتیم و دیدیم چقدر میتونن کاربردی باشن. ولی بیاین یه کم عمیقتر بشیم و ببینیم وقتی یه دکوریتور روی تابع یا کلاس اعمال میشه، دقیقاً چه اتفاقی پشت صحنه رخ میده؟ حتی قبل از اینکه کد اجرا بشه.
1⃣ پایتون چطوری کد رو اجرا میکنه؟ 📜
قبل از اینکه بریم سراغ دکوریتورها، یه نکته مهم:
پایتون یه زبان مفسریه، یعنی خطبهخط کد رو اجرا میکنه. ولی قبل از اجرا، اول کد رو به بایتکد تبدیل میکنه و بعد اون رو میفرسته برای ماشین مجازی پایتون (PVM).
تو این فرآیند، هر تابع و کلاس یه آبجکت جداگانه توی حافظه میشه و همینجاست که دکوریتورها وارد عمل میشن 🚀
2⃣ دکوریتورها دقیقاً چیکار میکنن؟ 🔧
1⃣ وقتی @ میذاریم، واقعاً چی میشه؟
وقتی یه تابع رو با @my_decorator دکوریت میکنیم، پایتون پشت صحنه این کارو انجام میده:
@my_decorator
def func(...):
...
میشه این:
def func(...):
...
func = my_decorator(func)
یعنی تابع اصلی ساخته میشه، بعد به دکوریتور داده میشه و خروجی دکوریتور جایگزین تابع اصلی میشه. این اتفاق در لحظه تعریف تابع رخ میده، نه وقتی تابع اجرا میشه
2⃣ ترتیب اجرا چطوریه؟
وقتی دکوریتور روی تابع اعمال میشه:
تابع اصلی به عنوان یه آبجکت ساخته میشه.
دکوریتور اجرا میشه و تابع اصلی رو میگیره.
خروجی دکوریتور جایگزین تابع اصلی میشه.
پس، از این به بعد هر وقت تابع رو صدا بزنید، در واقع دارید خروجی دکوریتور رو اجرا میکنید، نه تابع اصلی رو
3⃣ چه بلایی سر تابع میاد؟ 🔍
1⃣ تابع اصلی تبدیل میشه به...
هر تابع تو پایتون یه آبجکته، پس دکوریتورها میتونن روش تغییرات زیادی بدن:
قبل از اجرا یه کار انجام بدن (مثلاً لاگ بگیرن).
تابع اصلی رو اجرا کنن.
بعد از اجرا هم یه کار دیگه انجام بدن (مثلاً خروجی رو دستکاری کنن).
یا حتی یه چیز کاملاً جدید برگردونن
در نتیجه، اسم تابع دیگه به اون چیزی که اول تعریف کردید اشاره نمیکنه، بلکه به خروجی دکوریتور اشاره داره.
2⃣ مشکل متادیتا و راهحل functools.wraps
یه مشکل اینه که دکوریتور باعث میشه اطلاعات تابع (مثل نام، توضیحات و...) از بین بره. برای حل این مشکل، باید از functools.wraps استفاده کنیم:
import functools
def log_calls(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
print(f"قبل از اجرای {func.__name__}")
result = func(*args, **kwargs)
print(f"بعد از اجرای {func.__name__}")
return result
return wrapper
اینطوری، متادیتای تابع اصلی حفظ میشه وdoc __doc__ دسترسی داشت. 😎
3⃣ دکوریتورهای پشت سر هم (Chaining Decorators)
اگه چندتا دکوریتور رو روی یه تابع بذاریم، ترتیبش مهمه. به این مثال دقت کن:
@decorator_a
@decorator_b
def func():
pass
اول decorator_b اجرا میشه و خروجیش میره تو decorator_a. پس ترتیب اجرا به این شکله:
func = decorator_b(func)
func = decorator_a(func)
پس، دکوریتوری که پایینتر نوشته شده، زودتر اجرا میشه 🔄
4⃣ پشت صحنه در زمان کامپایل و اجرا 🕒
1⃣ دکوریتور کی اجرا میشه؟
دکوریتورها همون موقعی که تابع یا کلاس تعریف میشه اجرا میشن، نه وقتی که تابع رو صدا میزنید. پس این کد:
@my_decorator
def my_func():
pass
در لحظهای که پایتون به این خط کد میرسه، my_decorator(my_func) اجرا میشه و خروجیش جایگزین my_func میشه.
2⃣ ذخیره تابع در فضای نام (Namespace Binding)
بعد از این فرآیند، اسم تابع به تابع دکوریتشده اشاره میکنه. پس اگه تابع اصلی رو نگه نداشته باشید، دیگه بهش دسترسی ندارید
3⃣ تأثیر روی بهینهسازی
چون دکوریتورها میتونن کد تابع رو تغییر بدن، ممکنه باعث بشن که بهینهسازیهایی که پایتون انجام میده، دیگه درست کار نکنه. برای مثال، اگه دکوریتور یه حلقه اضافه کنه یا اجرای تابع رو تغییر بده، بایتکد نهایی کاملاً متفاوت میشه.
5⃣ نکات مهم که باید رعایت کنید 💡
✅ از functools.wraps استفاده کنید
اگه دکوریتورتون متادیتای تابع رو تغییر میده، این کار باعث میشه اطلاعات تابع اصلی حفظ بشه.
✅ ترتیب دکوریتورها مهمه
اگه چند دکوریتور دارید، حتماً ترتیب اجرا رو بررسی کنید که به مشکل نخورید.
✅ موقع اشکالزدایی حواستون باشه
چون دکوریتورها موقع تعریف اجرا میشن، اگه کدتون مشکل داشته باشه، ممکنه سختتر اشکالزدایی بشه. پس بهتره با print یا لاگ گرفتن، مراحل اجرا رو چک کنید.
#⃣ #python #programming
➖➖➖➖➖➖➖➖➖
🥷 CHANNEL | GROUP
❤14👍6🔥3👎1👏1👌1
Ninja Learn | نینجا لرن
بعضی دوستان پیشنهاد دادن که کانال ادمین داشته باشه برای تولید محتوای بیشتر. دیدم ایده بدی نیست. هرکسی که دوست داره تو کانال تولید محتوا بکنه، درمورد موضوع: ساختمان داده ها یه پست بنویسه بفرسته به ایدی @mohammad_strout بررسی کنم (ساختار و کیفیتش مثل پستای…
خب یه دوست گرامی انتخاب شد
با تشکر از همگی
با تشکر از همگی
❤5
خب سلام دوستان رسیدیم به ساختمان داده ها؛ ساختار هایی که برای مدیریت داده ها خیلی کاربردی ان💡
همونطور که میدونید، داخل برنامه هامون نیاز داریم داده ها را به صورتی ذخیره و مدیریت کنیم که پردازش سریعتر و مصرف حافظه بهینه تر بشه.
🧱 چند نوع ساختمان داده داریم؟
به طور کلی به دو دسته تقسیم میشه:
1️⃣ ساختارهای اولیه (Primitive Data Types)
🔸پایه ای ترین نوع ذخیره داده ها مثل int ، float ، char و boolean
2️⃣ ساختارهای غیراولیه (Non-Primitive)
🔸برای مدیریت مجموعه های بزرگ و پیچیده داده ها استفاده میشن و عمدتا به دو گروه تقسیم میشن:
1️⃣ ساختارهای خطی (Linear):
🔸داده ها به صورت ترتیبی چیده میشن مثل: آرایه (Array)، پشته (Stack)، صف (Queue)، لیست پیوندی (Linked List).
2️⃣ ساختارهای غیرخطی (Non-Linear):
🔸داده ها به صورت سلسله مراتبی یا شبکه ای ذخیره میشن و از نمونه هاشون میشه به درخت (Tree)، گراف (Graph)، جدول هش (Hash Table) اشاره کرد
در پستهای آینده، هر یک از این ساختارها رو
ببیشتر بررسی میکنیم 🚀
اگر سوالی یا پیشنهادی دارید خوشحال میشم کامنت بگذارید! 💬
➖➖➖➖➖➖➖➖➖
همونطور که میدونید، داخل برنامه هامون نیاز داریم داده ها را به صورتی ذخیره و مدیریت کنیم که پردازش سریعتر و مصرف حافظه بهینه تر بشه.
به طور مثال میخوایم کاربران یک اپلیکیشن را مدیریت کنیم یا مسیرهای کوتاه تر بین دو شهر را در نقشه پیدا کنیم!🔍 ساختمان داده چه کاربردی داره؟
🔸اینجا ساختار مناسب خیلی میتونه مفید باشه! ✨
🔸کاهش زمان عملیات ها (مثل جستجو، افزودن یا حذف داده)
🔸بهینه سازی مصرف حافظه (ذخیره هوشمندانه داده ها بدون اتلاف فضا)
🧱 چند نوع ساختمان داده داریم؟
به طور کلی به دو دسته تقسیم میشه:
1️⃣ ساختارهای اولیه (Primitive Data Types)
🔸پایه ای ترین نوع ذخیره داده ها مثل int ، float ، char و boolean
این تایپ ها تشکیل دهنده پایه ساختمان داده های پیچیده تر هستن!
2️⃣ ساختارهای غیراولیه (Non-Primitive)
🔸برای مدیریت مجموعه های بزرگ و پیچیده داده ها استفاده میشن و عمدتا به دو گروه تقسیم میشن:
1️⃣ ساختارهای خطی (Linear):
🔸داده ها به صورت ترتیبی چیده میشن مثل: آرایه (Array)، پشته (Stack)، صف (Queue)، لیست پیوندی (Linked List).
و از کاربرد هاشون میشه به مدیریت صف پیامها، ذخیره اطلاعات کاربران به ترتیب ثبتنام اشاره کرد.
2️⃣ ساختارهای غیرخطی (Non-Linear):
🔸داده ها به صورت سلسله مراتبی یا شبکه ای ذخیره میشن و از نمونه هاشون میشه به درخت (Tree)، گراف (Graph)، جدول هش (Hash Table) اشاره کرد
و نمونه کاربرد هاشون هم پیدا کردن کوتاه ترین مسیر در نقشه (با گراف)، جستجوی سریع در دیکشنری (با درخت دودویی) هست.
در پستهای آینده، هر یک از این ساختارها رو
ببیشتر بررسی میکنیم 🚀
اگر سوالی یا پیشنهادی دارید خوشحال میشم کامنت بگذارید! 💬
#️⃣ #data_structure #programming
➖➖➖➖➖➖➖➖➖
🥷 CHANNEL | GROUP
👍10❤6
خب خب خب جلوگیری از Race Condition در جنگو با select_for_update 🔒🚀
توی این پست در مورد Race Condition صحبت کردیم و گفتیم چطور ممکنه چندتا درخواست همزمان بیان و دیتا رو خراب کنن. حالا بریم ببینیم جنگو چه ترفندهایی برای کنترل این مشکل داره و چطور میتونیم از select_for_update استفاده کنیم.
مشکل چیه؟ 🤔
فرض کن یه سیستم بانکی داری و کاربرا دارن پول جابهجا میکنن. حالا دو نفر همزمان میخوان از حسابشون پول بردارن و موجودی حساب فقط 100 تومنه. اگه این درخواستها بدون قفل کردن دیتا پردازش بشن، ممکنه هر دو برداشت موفق بشن و سیستم بدهکار بشه 😬
چطوری select_for_update مشکل رو حل میکنه؟ 🔐
وقتی از select_for_update استفاده میکنی، رکورد دیتابیس قفل میشه تا هیچ درخواست دیگهای نتونه همزمان تغییرش بده. این یعنی هر درخواستی که بعد از اولین درخواست بیاد، باید منتظر بمونه تا قفل آزاد بشه و بعد پردازش بشه.
مثال 1: جلوگیری از برداشت همزمان از حساب بانکی 🏦
✅ این کد مطمئن میشه که وقتی یه درخواست داره موجودی رو چک میکنه و کم میکنه، هیچ درخواست دیگهای همزمان وارد عمل نشه.
مثال 2: انتقال وجه بین دو حساب 💳
حالا یه چالش سختتر انتقال پول از یه حساب به حساب دیگه. باید هر دو حساب همزمان قفل بشن تا مشکلات همزمانی پیش نیاد.
✅ اینجا هر دو حساب رو قفل میکنیم تا حتی اگه دو درخواست انتقال پول به صورت همزمان بیاد، هیچکدوم نتونن وسط کار رو همدیگه تأثیر بذارن.
چندتا نکته 🚀
🔹 انتخاب نوع قفل (select_for_update(nowait=True))
اگه بخوای درخواستهای معطل رو سریع رد کنی، میتونی nowait=True بذاری که اگه رکورد قفل بود، درخواست جدید منتظر نمونه و مستقیم خطا بده.
☝️ این باعث میشه که اگه رکورد قفل باشه، جنگو بلافاصله یه DatabaseError بده و منتظر نمونه.
🔹 قفل کردن رکوردها بدون مسدود کردن خواندن (select_for_update(skip_locked=True))
اگه درخواستهای زیادی داری و نمیخوای که یک درخواست کل سیستم رو بلاک کنه، میتونی از skip_locked=True استفاده کنی که درخواستهای دیگه بتونن رکوردهای آزاد رو پردازش کنن.
☝️ این کار باعث میشه که اگه یه رکورد قفل بود، درخواست بیخیال اون رکورد بشه و فقط رکوردهایی که قفل نیستن رو انتخاب کنه.
🔹 مدیریت تایماوت قفل (set statement_timeout)
اگه نمیخوای که درخواستها مدت زیادی بلاک بشن، توی PostgreSQL میتونی یه تایماوت برای قفل تعیین کنی:
☝️ این یعنی اگه یه درخواست بیشتر از ۵ ثانیه قفل بمونه، بهش خطا داده میشه و میره بیرون.
جمعبندی ✍
select_for_update یکی از قویترین ابزارها برای جلوگیری از Race Condition توی جنگوئه. مهمترین نکاتش اینان:
✅ قفل کردن رکوردهای دیتابیس موقع آپدیت برای جلوگیری از دستکاری همزمان
✅ استفاده از nowait=True برای جلوگیری از انتظار بیش از حد
✅ استفاده از skip_locked=True برای رد کردن رکوردهای قفلشده و ادامه پردازش.
➖➖➖➖➖➖➖➖➖
توی این پست در مورد Race Condition صحبت کردیم و گفتیم چطور ممکنه چندتا درخواست همزمان بیان و دیتا رو خراب کنن. حالا بریم ببینیم جنگو چه ترفندهایی برای کنترل این مشکل داره و چطور میتونیم از select_for_update استفاده کنیم.
مشکل چیه؟ 🤔
فرض کن یه سیستم بانکی داری و کاربرا دارن پول جابهجا میکنن. حالا دو نفر همزمان میخوان از حسابشون پول بردارن و موجودی حساب فقط 100 تومنه. اگه این درخواستها بدون قفل کردن دیتا پردازش بشن، ممکنه هر دو برداشت موفق بشن و سیستم بدهکار بشه 😬
اینجا همون جاییه که select_for_update میاد وسط و دیتا رو از فاجعه نجات میده.
چطوری select_for_update مشکل رو حل میکنه؟ 🔐
وقتی از select_for_update استفاده میکنی، رکورد دیتابیس قفل میشه تا هیچ درخواست دیگهای نتونه همزمان تغییرش بده. این یعنی هر درخواستی که بعد از اولین درخواست بیاد، باید منتظر بمونه تا قفل آزاد بشه و بعد پردازش بشه.
مثال 1: جلوگیری از برداشت همزمان از حساب بانکی 🏦
from django.db import transaction
from myapp.models import Account
def withdraw_money(account_id, amount):
with transaction.atomic(): # شروع تراکنش
account = Account.objects.select_for_update().get(pk=account_id) # قفل کردن رکورد
if account.balance >= amount:
account.balance -= amount
account.save()
print("برداشت موفقیتآمیز بود!")
else:
print("موجودی کافی نیست!") # جلوگیری از برداشت بیش از حد
✅ این کد مطمئن میشه که وقتی یه درخواست داره موجودی رو چک میکنه و کم میکنه، هیچ درخواست دیگهای همزمان وارد عمل نشه.
مثال 2: انتقال وجه بین دو حساب 💳
حالا یه چالش سختتر انتقال پول از یه حساب به حساب دیگه. باید هر دو حساب همزمان قفل بشن تا مشکلات همزمانی پیش نیاد.
from django.db import transaction
from myapp.models import Account
def transfer_money(from_id, to_id, amount):
with transaction.atomic():
accounts = Account.objects.select_for_update().filter(pk__in=[from_id, to_id]).order_by("id")
sender = accounts[0]
receiver = accounts[1]
if sender.balance >= amount:
sender.balance -= amount
receiver.balance += amount
sender.save()
receiver.save()
print("انتقال وجه موفقیتآمیز بود!")
else:
print("موجودی کافی نیست!") # جلوگیری از انتقال اشتباه
✅ اینجا هر دو حساب رو قفل میکنیم تا حتی اگه دو درخواست انتقال پول به صورت همزمان بیاد، هیچکدوم نتونن وسط کار رو همدیگه تأثیر بذارن.
چندتا نکته 🚀
🔹 انتخاب نوع قفل (select_for_update(nowait=True))
اگه بخوای درخواستهای معطل رو سریع رد کنی، میتونی nowait=True بذاری که اگه رکورد قفل بود، درخواست جدید منتظر نمونه و مستقیم خطا بده.
account = Account.objects.select_for_update(nowait=True).get(pk=1)
☝️ این باعث میشه که اگه رکورد قفل باشه، جنگو بلافاصله یه DatabaseError بده و منتظر نمونه.
🔹 قفل کردن رکوردها بدون مسدود کردن خواندن (select_for_update(skip_locked=True))
اگه درخواستهای زیادی داری و نمیخوای که یک درخواست کل سیستم رو بلاک کنه، میتونی از skip_locked=True استفاده کنی که درخواستهای دیگه بتونن رکوردهای آزاد رو پردازش کنن.
account = Account.objects.select_for_update(skip_locked=True).get(pk=1)
☝️ این کار باعث میشه که اگه یه رکورد قفل بود، درخواست بیخیال اون رکورد بشه و فقط رکوردهایی که قفل نیستن رو انتخاب کنه.
🔹 مدیریت تایماوت قفل (set statement_timeout)
اگه نمیخوای که درخواستها مدت زیادی بلاک بشن، توی PostgreSQL میتونی یه تایماوت برای قفل تعیین کنی:
SET statement_timeout = '5s';
☝️ این یعنی اگه یه درخواست بیشتر از ۵ ثانیه قفل بمونه، بهش خطا داده میشه و میره بیرون.
جمعبندی ✍
select_for_update یکی از قویترین ابزارها برای جلوگیری از Race Condition توی جنگوئه. مهمترین نکاتش اینان:
✅ قفل کردن رکوردهای دیتابیس موقع آپدیت برای جلوگیری از دستکاری همزمان
✅ استفاده از nowait=True برای جلوگیری از انتظار بیش از حد
✅ استفاده از skip_locked=True برای رد کردن رکوردهای قفلشده و ادامه پردازش.
#️⃣ #python #programming #db
➖➖➖➖➖➖➖➖➖
🥷 CHANNEL | GROUP
1👍20🔥4❤2👌1
Ninja Learn | نینجا لرن
خب خب خب جلوگیری از Race Condition در جنگو با select_for_update 🔒🚀 توی این پست در مورد Race Condition صحبت کردیم و گفتیم چطور ممکنه چندتا درخواست همزمان بیان و دیتا رو خراب کنن. حالا بریم ببینیم جنگو چه ترفندهایی برای کنترل این مشکل داره و چطور میتونیم از…
خیلی وقت بود پست جنگو نداشته بودیم 😬
👏10
🎥
داستان فیلم 🎬
پیشنهاد میکنم ببینید :)
➖➖➖➖➖➖➖➖➖
The social network
داستان فیلم 🎬
ـ“The Social Network” داستان تأسیس شبکه اجتماعی فیسبوک توسط مارک زاکربرگ و چالشهایی که در مسیر این راه با آن مواجه شد را روایت میکند. فیلم به نمایش مسائل حقوقی، درگیریها و کشمکشهای شخصی در مسیر ساخت یکی از بزرگترین شبکههای اجتماعی دنیا میپردازد.
پیشنهاد میکنم ببینید :)
#️⃣ #movie
➖➖➖➖➖➖➖➖➖
🥷 CHANNEL | GROUP
❤7👍2🤣2
Ninja Learn | نینجا لرن
🎥 The social network داستان فیلم 🎬 ـ“The Social Network” داستان تأسیس شبکه اجتماعی فیسبوک توسط مارک زاکربرگ و چالشهایی که در مسیر این راه با آن مواجه شد را روایت میکند. فیلم به نمایش مسائل حقوقی، درگیریها و کشمکشهای شخصی در مسیر ساخت یکی از بزرگترین…
یکی از دلایلی که پیشنهادش میکنم اینه که نشون میده مارک زاکر برگ چه ادم دزد و مزخرفیه.
👍15
جنگو کنده، پس نباید استفاده کنیم؟ 🙂↔️
یکی از بحثهای همیشگی توی گروه های جنگو اینه که "جنگو کنده، پس بریم سمت FastAPI یا Go یا ...". این حرفو زیاد شنیدم، خودمم یه زمانی فکر میکردم سرعت، همهچیزه ولی بیاین یه بار منطقی بررسی کنیم، بدون تعصب.
چرا میگن جنگو کنده؟
خب راستشو بخواین، جنگو واقعا کنده (نسبت به فریمورکهای async بیس مثل FastAPI و زبانهای کامپایلری مثل Go که توی I/O bound حرف اولو میزنن). ولی چرا؟
جنگو سینکروسه 🥸
جنگو از اساس برای وباپلیکیشنهای سنتی طراحی شده(طبیعیم هست چون ۲۰ سال پیش ساخته شد اون موقع مفهومی به اسم async به این صورت نبود).
ولی فریمورکهایی مثل FastAPI میتونن همزمان چند درخواست رو مدیریت کنن (به لطف async).
Overhead بالای ORM 🏋️♂️
ORM جنگو سنگینه. هر کوئری که میزنی، کلی پردازش اضافه انجام میده تا کارتو راحت کنه، ولی همین باعث میشه کندتر از ORMهای سبکتر باشه.
Middleware و Request Cycle پیچیدهتره 🌀
جنگو یه سری پردازشهای اضافه برای هر درخواست انجام میده (مانند middleware ها، سیگنالها، template rendering و ...)، که باعث میشه به طور طبیعی کمی کندتر باشه.
پس چرا بازم از جنگو استفاده کنیم؟
حالا که جنگو کنده، یعنی نباید سمتش بریم؟ نه بابا بذار تجربه خودمو بگم.
1⃣ سرعت، همیشه مهمترین فاکتور نیست
اکثر پروژهها، گلوگاه سرعت، فریمورک نیست، بلکه دیتابیس، شبکه، و لاجیکهای بیزینسی هستن. یه اپلیکیشن CRUD ساده که روزی ۱۰۰۰ تا درخواست داره، با FastAPI یا جنگو، تفاوت محسوسی نداره.
2⃣ توسعه سریعتر = زمان و پول بیشتر
جنگو کلی چیز آماده داره. سیستم مدیریت کاربر، فرمها، ORM، ادمین پنل، و کلی ماژول دیگه. این یعنی تو به جای ساختن همهچی از صفر، فقط تمرکزت روی بیزینس لاجیکه. توسعه سریعتر = هزینه کمتر.
3⃣ امنیت، یکپارچگی، و قابلیت اطمینان
جنگو به طور پیشفرض مقاوم در برابر حملات XSS، CSRF، SQL Injection و غیرهست. ولی FastAPI؟ باید خودت امنیت رو درست کنی و Middleware بنویسی، که اگه اشتباه کنی، فاجعه میشه
کی بریم سمت FastAPI یا Go یا هرچیز سریع؟
1⃣ وقتی واقعا به Async نیاز داری
اگه داری یه چتاپ، وبساکت، یا یه سیستم پردازش سنگین با درخواستهای همزمان بالا مینویسی، FastAPI و Go گزینههای بهتری هستن.
2⃣ وقتی هر میلیثانیه مهمه
توی سرویسهای real-time مثل سیستمهای تریدینگ، گیمینگ، یا پردازش داده سنگین، Go و Rust گزینههای بهتری هستن، چون کامپایل میشن و خیلی سریعتر از پایتون اجرا میشن.
پس چی کار کنیم؟
سرعت، همه چیز نیست، بلکه بستگی داره که چه چیزی برات مهمتره و نیاز داری بهش
➖➖➖➖➖➖➖➖➖
یکی از بحثهای همیشگی توی گروه های جنگو اینه که "جنگو کنده، پس بریم سمت FastAPI یا Go یا ...". این حرفو زیاد شنیدم، خودمم یه زمانی فکر میکردم سرعت، همهچیزه ولی بیاین یه بار منطقی بررسی کنیم، بدون تعصب.
چرا میگن جنگو کنده؟
خب راستشو بخواین، جنگو واقعا کنده (نسبت به فریمورکهای async بیس مثل FastAPI و زبانهای کامپایلری مثل Go که توی I/O bound حرف اولو میزنن). ولی چرا؟
جنگو سینکروسه 🥸
جنگو از اساس برای وباپلیکیشنهای سنتی طراحی شده(طبیعیم هست چون ۲۰ سال پیش ساخته شد اون موقع مفهومی به اسم async به این صورت نبود).
ولی فریمورکهایی مثل FastAPI میتونن همزمان چند درخواست رو مدیریت کنن (به لطف async).
Overhead بالای ORM 🏋️♂️
ORM جنگو سنگینه. هر کوئری که میزنی، کلی پردازش اضافه انجام میده تا کارتو راحت کنه، ولی همین باعث میشه کندتر از ORMهای سبکتر باشه.
Middleware و Request Cycle پیچیدهتره 🌀
جنگو یه سری پردازشهای اضافه برای هر درخواست انجام میده (مانند middleware ها، سیگنالها، template rendering و ...)، که باعث میشه به طور طبیعی کمی کندتر باشه.
پس چرا بازم از جنگو استفاده کنیم؟
حالا که جنگو کنده، یعنی نباید سمتش بریم؟ نه بابا بذار تجربه خودمو بگم.
1⃣ سرعت، همیشه مهمترین فاکتور نیست
اکثر پروژهها، گلوگاه سرعت، فریمورک نیست، بلکه دیتابیس، شبکه، و لاجیکهای بیزینسی هستن. یه اپلیکیشن CRUD ساده که روزی ۱۰۰۰ تا درخواست داره، با FastAPI یا جنگو، تفاوت محسوسی نداره.
2⃣ توسعه سریعتر = زمان و پول بیشتر
جنگو کلی چیز آماده داره. سیستم مدیریت کاربر، فرمها، ORM، ادمین پنل، و کلی ماژول دیگه. این یعنی تو به جای ساختن همهچی از صفر، فقط تمرکزت روی بیزینس لاجیکه. توسعه سریعتر = هزینه کمتر.
3⃣ امنیت، یکپارچگی، و قابلیت اطمینان
جنگو به طور پیشفرض مقاوم در برابر حملات XSS، CSRF، SQL Injection و غیرهست. ولی FastAPI؟ باید خودت امنیت رو درست کنی و Middleware بنویسی، که اگه اشتباه کنی، فاجعه میشه
کی بریم سمت FastAPI یا Go یا هرچیز سریع؟
1⃣ وقتی واقعا به Async نیاز داری
اگه داری یه چتاپ، وبساکت، یا یه سیستم پردازش سنگین با درخواستهای همزمان بالا مینویسی، FastAPI و Go گزینههای بهتری هستن.
2⃣ وقتی هر میلیثانیه مهمه
توی سرویسهای real-time مثل سیستمهای تریدینگ، گیمینگ، یا پردازش داده سنگین، Go و Rust گزینههای بهتری هستن، چون کامپایل میشن و خیلی سریعتر از پایتون اجرا میشن.
پس چی کار کنیم؟
اگه سرعت برات مهمه: Go بزن Java بزن یا ...
اگه یه API سبک و سریع لازم داری: FastAPI بزن
اگه میخوای سریع یه اپلیکیشن کامل و امن بالا بیاری: Django بهترین گزینهست
سرعت، همه چیز نیست، بلکه بستگی داره که چه چیزی برات مهمتره و نیاز داری بهش
خوشحال میشم نظرتون رو بشنوم
تو کامنتای همین پست بگید 👇
#️⃣ #programming #django #backend
➖➖➖➖➖➖➖➖➖
🥷 CHANNEL | GROUP
👍32❤4