Warning: Undefined array key 0 in /var/www/tgoop/function.php on line 65

Warning: Trying to access array offset on value of type null in /var/www/tgoop/function.php on line 65
- Telegram Web
Telegram Web
رمان گرگ بیابان از هرمان هسه

قبل از هرچیزی عمیقا باور کردم که این کتاب رو خدا و شیطان باهم نوشتند

موضوع کتاب ارجاع به درون انسان هستش، خویشتن‌های درونی هر انسانی

اما بر خلاف خیلی از کتاب‌های دیگه به بخش تاریک و ترسناک درون انسان پرداخته و در تقابل روح پاک و پلید انسان و چگونه پیروز شدن پلیدی بر پاکی در درون می‌پردازد

درک سطر به سطر کتاب برام سخت بود


در یک کلام چنین شاهکار وحشتناکی رو تا کنون نخونده بودم، خوندنش رو به هرکسی توصیه نمیکنم، منتها اگر حس میکنید روحتون در بالاترین حالت پذیرش درونتون قرار داره بخونیدش

یک بخش از کتاب برای خودم خیلی ترسناک بود

#book

@code_crafters
👍6
CodeCrafters
4-الگوی Event Sourcing حالا تصور کنید یدیه دفترچه خاطرات دارید که هر چیزی تو زندگیت توناتفاق می‌افته رو توش می‌نویسیید: امروز چی خریدید، کجا رفتید، چی گفتی. اگه بخوادی یه روز خاص رو یادتون بیاد، فقط کافیه دفترچه رو باز کنید و اون صفحه رو بخونید. الگوی Event…
سری الگوهای طراحی میکروسرویس‌ها — بخش سوم
تو بخش اول، با مفاهیم پایه‌ی میکروسرویس‌ها آشنا شدیم و الگوهای رجیستری سرویس و مش سرویس رو بررسی کردیم و تو تو بخش دوم هم الگوهای مدار شکن و منبع‌یابی رویداد رو دیدیم که چطور به پایداری و تاریخچه‌نگاری سیستم کمک می‌کنن.


حالا تو بخش سوم، قراره با دو تا الگوی مهم دیگه آشنا بشیم: الگوی SAGA و الگوی API Gateway. این دو الگو بهمون کمک می‌کنن تا هماهنگی داده‌ها و دسترسی به سرویس‌ها رو تو سیستم‌های پخش‌شده بهتر مدیریت کنیم.

5. الگوی SAGA (SAGA Pattern)
الگوی SAGA یه روش کارآمد برای مدیریت هماهنگی داده‌ها تو تراکنش‌های پخش‌شده بین میکروسرویس‌هاست.
تو سیستم‌های سنتی، تراکنش‌ها با مدل ACID مدیریت می‌شن که تضمین می‌کنه همه‌چیز یا کامل انجام بشه یا اصلاً انجام نشه.
اما تو معماری میکروسرویس، که هر سرویس دیتابیس خودش رو داره، پیاده‌سازی این مدل خیلی سخته.
اینجاست که الگوی SAGA یه راه‌حل هوشمندانه ارائه می‌ده.

چطور کار می‌کنه SAGA؟
تو این الگو، یه تراکنش بزرگ به چند قدم کوچیک‌تر تقسیم می‌شه که هر کدومش رو یه سرویس انجام می‌ده.
هر قدم یه پیام یا رویداد منتشر می‌کنه که باعث فعال شدن قدم بعدی می‌شه.
اگه یه قدم به مشکل بخوره، یه سری عملیات جبرانی (Compensating Transactions) اجرا می‌شن تا وضعیت به حالت اولیه برگرده.

دو نوع هماهنگی در SAGA:
🔹 کروئوگرافی (Choreography):
هیچ هماهنگ‌کننده‌ی مرکزی نداریم. هر سرویس یه رویداد منتشر می‌کنه و بقیه سرویس‌ها خودشون به اون گوش می‌دن.
مثلاً سرویس سفارش یه رویداد «سفارش ثبت شد» می‌فرسته، سرویس انبار اینو می‌شنوه و موجودی رو کم می‌کنه.
این روش تو سیستم‌های ساده خوبه، ولی تو سیستم‌های بزرگ مدیریت سخت می‌شه.

🔹 ارکستراسیون (Orchestration):
اینجا یه سرویس مرکزی (Orchestrator) همه‌چیز رو مدیریت می‌کنه. مثلاً اول به سرویس سفارش می‌گه سفارش رو ثبت کن، بعد به سرویس پرداخت دستور می‌ده پول رو بگیره.
مدیریتش متمرکزه و برای سیستم‌های پیچیده بهتره، ولی نقطه‌ی شکست هم می‌تونه باشه.


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

چرا SAGA مهمه؟
تضمین هماهنگی داده‌ها تو سیستم‌های پخش‌شده
مدیریت درست خطاها با عملیات جبرانی
مناسب برای معماری‌های مدرن که نمی‌تونن از تراکنش‌های سنتی استفاده کنن



6. الگوی API Gateway (API Gateway Pattern)
الگوی API Gateway یه راه‌حل برای ساده‌سازی و مدیریت دسترسی به میکروسرویس‌هاست.

تو سیستم‌های پخش‌شده، معمولاً سرویس‌های زیادی وجود دارن که هر کدوم وظیفه خاصی دارن.
اگه کلاینت‌ها (مثلاً اپ موبایل یا وب) بخوان مستقیماً با هر سرویس ارتباط برقرار کنن، کار خیلی پیچیده می‌شه.
اینجاست که API Gateway وارد می‌شه و همه‌چیز رو ساده‌تر می‌کنه.

چطور کار می‌کنهAPI Gateway ؟
مثل یه دربان هوشمند جلوی سیستم می‌ایسته.
هر درخواستی که از سمت کاربر میاد، اول وارد API Gateway می‌شه، بعد اون تصمیم می‌گیره این درخواست باید به کدوم سرویس بره.

وظایف کلیدی API Gateway:
هدایت و تعادل بار (Routing and Load Balancing): درخواست‌ها رو بر اساس قوانین به سرویس درست می‌فرسته و با پخش بار بین نسخه‌های مختلف، سیستم رو پایدار نگه می‌داره.
ترجمه پروتکل (Protocol Translation): می‌تونه درخواست‌های HTTP رو به فرمت‌های دیگه (مثل gRPC) تبدیل کنه تا با سرویس‌های بک‌اند سازگار بشه.
تغییر درخواست (Request Transformation): درخواست‌ها و پاسخ‌ها رو بر اساس نیاز سرویس‌ها تغییر می‌ده، مثلاً پارامترها یا هدرها رو تنظیم می‌کنه.
کش کردن (Caching): با ذخیره داده‌ها، سرعت رو بالا می‌بره و بار رو از روی سرویس‌ها کم می‌کنه.
هدایت و تعادل بار (Load Balancing) بین چند سرور

یه مثال ساده:
فرض کنید یه اپلیکیشن خرید دارید.
به‌جای اینکه اپ مستقیماً با سرویس سفارش، پرداخت و ارسال ارتباط بگیره، همه درخواست‌ها می‌رن سمت API Gateway.
اونجا اول اعتبارسنجی انجام می‌شه، بعد درخواست به سرویس مربوطه فرستاده می‌شه، و اگه لازم باشه، جواب کش می‌شه تا سریع‌تر به دست کاربر برسه.

چرا API Gateway مهمه؟

دسترسی به سرویس‌ها رو متمرکز و ساده می‌کنه
امنیت و نظارت رو از یه نقطه انجام می‌ده
به مقیاس‌پذیری، پایداری و مانیتورینگ سیستم کمک می‌کنه


#microservice #design_patterns

@code_crafters
👍5
نوشتن یا بررسی یک نرم افزار رو از کجا شروع کنیم؟؟؟

سوالی که همیشه وجود داره حتی تو مصاحبه‌های استخدامی

گاها وقت‌ها حس میکنم اون چیزی که یاد میگیریم و راجبش میخونیم رو یجوری محدود میکنیم که واقعا از گزینه‌های بیشتری که بهمون میده رو فراموش میکنیم

یک نرم افزار از بیرون سه تا بخش داره

view
service
model

چرا میگیم این سه بخش و بالاتر گفتم محدود؟

دو شیوه توسعه نرم افزار مهم رو به یاد بیارید DDD و TDD علاوه بر اینکه این دو رویکرد تمام جنبه‌های خاص رو مورد پوشش قرار میدن موارد انتزاعی هم بهمون تدریس میکنن

که یکی از اونها سوال اولمون بود؟؟؟
از کجا شروع به نوشتن یا بررسی کنیم

در رویکرد DDD میگه اول سرویس‌هات رو بنویس و بعد لایه داده و ویوت رو مطابق با اون پیش ببر (در ابتدای نوشتن از فیک دیتا بهره ببر) چرا این رویکرد جالبه برامون، چون ما هیچ درکی از پیچیدگی نداریم و هیچ درکی هم از تمام نیازمندی داده هم نداریم، وقتی DDD میاد وسط هم پیچیدگیت مشخص میشه و هم درکت از نیازمندی داده، تو شروع پروژه کمتر مدلت رو لمس میکنی یا بهتره بگیم مدام و مدام مدل‌هات رو لمس نمیکنی و درکت از داده بیشتر میشه، این از اتلاف وقت و هزینه برای سازمان جلوگیری میکنه و بهمون میگه با چه چیزی قراره روبرو بشیم

تو روش TDD میگه بیا اول تست بنویس بعد حالا اون رو پاس کن، که از ویوهامون شروع میکنی، چه اتفاقی میافته؟؟؟
انتظارمون کاملا مشخص میشه و این منجر میشه ویوهای کامل و جامعتری داشته باشیم و بدونیم چی لازم داریم بابتش و باز همین منجر میشه کمتر مدل رو لمس کنی و تغییر بدی، انتظارت از خروجی کاملا مشخص هستش و بدهی فنی رو به حد مناسبی میرسونه که لازمه یک پروژه هستش، صرف زمان اولیه داره اما بازخورد دورنگر بهتری بهمون میده


این دو رویکرد منجر به برطرف کردن بدفهمی و کج فهمی‌های مدل سه لایه میشه و خب بسیار عالی

ولی از کجا بدونیم کدومش رو کجا بکار ببریم؟؟؟
اگه با یک سیستم دارای پیچیدگی روبرو هستید DDD
اگه با یک سیستم با اطمینان بالا روبرو هستید TDD



آیا رویکرد بهتری سراغ داریم؟؟؟
بله ترکیب این دو با هم

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


#DDD
#TDD

@code_crafters
👍53👎1
حضور CTEs در دیتابیس و محدودیت ormها

بیایید با یک مثال براتون توضیح بدم، یک پیچیدگی نسبتا معمولی در دیتابیس و کوئری‌ها


یک مدل رو تصور کنید که دوتا فیلد داره
class Model:
id: int(PK)
name: str
parent: FK(self, null)

در نگاه اول این یک مدل کاملا ساده هستش و کاملا هم درست فکر میکنید این یه مدل ساده و ابتدایی هستش، اما منطق تجاری؟؟؟

منطق تجاری از ما میخواد که در ازای یک کوئری تمام والد‌های اون object رو بدست بیاریم، تصور کنید که ریشه‌های تو در تو داخل مدل برای یک object حدود 100 والد وجود داره و برای یک object دیگه ممکنه 1000 والد وجود داشته باشه، منطق تجاری از ما خواسته والد هر آبجکتی که درخواست میشه از مدل رو هم بهش برگردونیم، در دید اول این یک مسئله ساده هستش اما یک منطق تجاری نسبتا پیچیده هستش

خود CTEs ها در دیتابیس چیه؟
بطور خلاصه یک‌نمای جدولی موقتی هستش که فقط و فقط در طول اجرای همون کوئری وجود دارند. داخل زبان کوئری با استفاده از With همراه با join و on ما یک ساختار درختی رو متصور میشیم و داده مدنظر خودمون رو ازش میکشیم بیرون. جدول موقت اولین گام برای ورود به ادمین پایگاه داده شدن هستش شاید تعجب کنید از این حرف ولی حقیقت داره، در مثال ما یک منطق نسبتا پیچیده مطرح شد (از نوع CTE بازگشتی) کاربرد اصلی CTE در تحلیل داده و مهندسی داده خودش رو نشون میده

چرا محدودیت در orm گفتیم؟؟
در orm ها موارد cte مطرح و پیاده سازی نشده چرا که دلیل اون این هستش که orm ها طراحی شدن بابت queryset های معمولی و نه بابت انجام کوئری‌های پیچیده، اینجاست که تو مثال بالا که مطرح کردیم اگه بخوایم از orm استفاده کنیم دچار محدودیت میشیم برای مثال اگه از prefetch استفاده کنیم محدود به انتخاب سطح میشیم بصورت دستی، اگه از زبان‌های برنامه نویسی بهره ببریم کارایی و کندی میاد سراغمون، به هر حال تصور درختی دیتابیسی که چندین میلیون رکورد داخلش هست کار راحتی نیستش، به اجبار باید سراغ CTEها بریم


واسه بچه‌هایی که با جنگو کار میکنند یکم تایم بزارید و django-cte و django-treebeard رو بخونید

کتابخونه‌های زیادی احتمالا پیدا بشه منتها این دوتا رو معرفی میکنم که بابت دو سناریوی مختلف مناسب هستند که خودتون بخونید راجبشون


#sql
#django

@code_crafters
4👍1
یو یو, ipfs چیست؟(InterPlanetary File System)
یک پروتکل غیرمتمرکز برای ذخیره‌سازی و شتراک‌گذاری داده‌هاست که با استفاده از آدرس‌دهی مبتنی بر محتوا (Content Addressing) و به روش p2p ، اطالاعت رو بین نودهای مختلف توزیع میکنه. برخلاف سیستم‌های متمرکز که به سرورهای خاص وابستن IPFS امکان دسترسی سریع‌تر، امن‌تر و مقاوم‌تر به داده‌ها را فراهم می‌کنه دقیقا مثل چیزی که در ساختار بیت کوین وجود داره.همه چیزو خود مردم مدیریت میکنند بدون وابستگی به دولت ها یا یک قدرت متمرکز.

تفاوت آدرس ها
امروزه وقتی یک دیتا رو ذخیره میکنیم یک URL منحصر به فرد داره که آدرس اون هست.
"C:\Program Files\Epic Games


اما در ipfs آدرس دهی مبتنی بر content addtessing هست. به‌جای اشاره به مکان ذخیره‌سازی، داده‌ها با یک هش (Hash) منحصربه‌فرد که همیشه با Qm شروع میششن شناسایی میشن.
QmQ3hUpzcze4ASWwmo42M4ZG6ALYsqjY6wyw694vRbPtcV

این روش باعث میشه که اگر محتوای فایل تغییر کنه، هش اونم تغییر کنه. در نتیجه، داده‌ها قابل تأیید هستن و نمی‌شه اونا رو دستکاری کرد بدون اینکه کسی متوجه بشه.

چطور کار می‌کنه؟
وقتی فایلی رو در IPFS آپلود می‌کنید، اون به بخش‌های کوچک تقسیم و بین نودها پخش می‌شه. هر بخش یه هش داره و کل فایل با یک هش اصلی شناسایی می‌شه. برای دسترسی، فقط کافیه هش رو وارد کنید،

چرا IPFS مهمه؟

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

فارغ این از که ipfs تو شبکه‌های ویدئویی و استریم P2P یا میزبانی وبسایت ها یا بدیهی ترینش ذخیره داده کاربرد داره ,در DApps ههم خیلی کاربرد داره و با بلاکچین ادغام میشه(نقطه عطف🔥)
بلاکچین به تنهایی برای ذخیره‌سازی داده‌های بزرگ مثل تصاویر، ویدئوها یا اسناد مناسب نیست، چون هر نود در شبکه باید یک کپی از کل بلاکچین را نگه داره که این کار هزینه‌بر هستش و اون رو ناکارآمد میکنه. IPFS این مشکل راو به خوبی درک کرده و به راحتی میتونه این ضعف بلاکچین رو پوشش بده .،این ویژگی‌ها با اصول بلاکچین، یعنی امنیت، شفافیت و غیرمتمرکز بودن، هم جهت و هم راستا هست.

#ipfs
#web3

@code_crafters
🔥5
CodeCrafters
یو یو, ipfs چیست؟(InterPlanetary File System) یک پروتکل غیرمتمرکز برای ذخیره‌سازی و شتراک‌گذاری داده‌هاست که با استفاده از آدرس‌دهی مبتنی بر محتوا (Content Addressing) و به روش p2p ، اطالاعت رو بین نودهای مختلف توزیع میکنه. برخلاف سیستم‌های متمرکز که به سرورهای…
قسمت دوم: نودها سودشون چیه و پروژه‌های کریپتو چرا عاشقش شدن؟
خب، تا اینجا فهمیدیم IPFS چطوری داده‌ها رو بین نودهای شبکه پخش می‌کنه و چطور آدرس‌دهی‌ش مبتنی بر محتوا (Content Addressing) هست، اما سوال اصلی اینه:

نودها چجوری سود می‌کنن؟
نودها (همون کامپیوترهایی که داده‌ها رو نگه می‌دارن و بین همدیگه رد و بدل می‌کنن) تو IPFS یه چیزی بیشتر از یک نقش ساده دارن:

ذخیره‌سازی و اشتراک‌گذاری داده‌ها: نودها فایل‌ها رو نگه می‌دارن و وقتی کسی درخواست داد، سریع اون فایل رو ارسال می‌کنن.

پاداش برای سرویس‌دهی: پروژه‌های مبتنی بر IPFS، مخصوصاً تو دنیای کریپتو و Web3، معمولاً برای نودهایی که بیشتر و بهتر خدمات میدن پاداش میدن. یعنی هر چقدر یک نود داده‌ها رو سریع‌تر و مطمئن‌تر تحویل بده، سود بیشتری می‌بره.

استفاده از توکن‌ها: شبکه‌های ذخیره‌سازی غیرمتمرکز مثل Filecoin که بر پایه IPFS ساخته شده، به نودها توکن Filecoin میدن به عنوان پاداش. این توکن‌ها میشه در بازارهای کریپتو معامله کرد و سود واقعی ازشون گرفت.

چرا پروژه‌های بزرگ کریپتو مثل Chainlink و غیره IPFS رو انتخاب کردن؟
Chainlink و ذخیره‌سازی داده‌های اوراکل: Chainlink که نقش اوراکل‌های امن رو بازی می‌کنه، نیاز داره داده‌ها رو جایی امن، سریع و غیرمتمرکز ذخیره کنه. IPFS این امکان رو بهش میده تا داده‌ها رو بدون وابستگی به یک سرور خاص، بین هزاران نود توزیع کنه و تضمین کنه که داده‌ها دستکاری نشدن.

غیرمتمرکز بودن و امنیت: پروژه‌هایی که امنیت و اعتماد بالا براشون مهمه، به IPFS تکیه می‌کنن چون امکان سانسور و از بین رفتن داده تقریبا صفر میشه.

مقیاس‌پذیری: IPFS به دلیل ساختار توزیع‌شده، مقیاس‌پذیری خیلی بهتری نسبت به سیستم‌های سنتی ذخیره‌سازی داره. برای پروژه‌های کریپتو که روز به روز بزرگ‌تر میشن، این موضوع حیاتی محسوب میشه.

پروژه‌های معروف دیگه که IPFS دارن استفاده می‌کنن:
ایک-Filecoin: شبکه ذخیره‌سازی غیرمتمرکز که با IPFS کاملا یکپارچه شده و توکن مخصوص به خودش رو داره.

دو-اArweave: پروتکلی برای ذخیره دائمی داده‌ها، که IPFS هم بهش کمک می‌کنه.

سه=Unstoppable Domains: استفاده از IPFS برای ساخت دامنه‌های وب غیرقابل سانسور.

چهار-Audius: پلتفرم موزیک غیرمتمرکز که IPFS رو برای نگهداری موزیک‌ها و داده‌ها استفاده می‌کنه.

#ipfs
#web3

@code_crafters
🔥7
Redirection - بخش اول

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

چرا از Redirection استفاده می‌کنیم؟
هدف اصلی Redirection سریع‌تر شدن ترنزکشن‌ها و کاهش زمان انتظار کاربر است. مثلا ممکن است درخواست کاربر به سروری نزدیک‌تر فرستاده شود تا با سرعت بیشتری پاسخ دریافت شود.

ریدایرکشن چگونه انجام می‌شود؟
ریدایرکشن می‌تواند در لایه‌های مختلفی انجام شود.
گاهی مرورگر طوری تنظیم می‌شود که درخواست را به یک پروکسی سرور بفرستد. گاهی هم DNS resolver آدرس یک سرور دیگر را ارائه می‌دهد. حتی در برخی موارد این روترها یا سوییچ‌ها هستند که مسیر پیام را مشخص می‌کنند. گاهی هم خود وب‌سرور تصمیم می‌گیرد پیام را به سرور مناسب‌تری منتقل کند.

HTTP Redirection
یکی از روش‌های رایج برای این موضوع، ارسال HTTP Redirection با کد ۳۰۲ است.
فرض کنید یک Load Balancer دارید که وظیفه‌اش تقسیم درخواست‌ها بین چند سرور است. کاربر A درخواست خود را به لود بالانسر می‌فرستد و پاسخ ۳۰۲ دریافت می‌کند که در آن آدرس سرور مناسب قرار دارد. حالا مرورگر باید درخواست را به این آدرس جدید ارسال کند.
این‌که لود بالانسر بر چه اساسی تصمیم‌گیری می‌کند، موضوعی‌ست که در آینده به آن خواهیم پرداخت.
البته یکی از مشکلات این روش، نیاز به ارسال چند درخواست برای رسیدن به سرور نهایی است که باعث افزایش تاخیر می‌شود.

DNS Redirection
زمانی که کاربر می‌خواهد به سایت codecrafters.ir دسترسی پیدا کند، DNS resolver باید این نام دامنه را به یک IP تبدیل کند. این IP می‌تواند از منابع مختلفی مثل مرورگر، DNS سرور شبکه یا منابع دیگر بیاید.
ما می‌توانیم DNS سرور را طوری تنظیم کنیم که هر بار IP متفاوتی ارائه دهد. این کار می‌تواند به روش ساده‌ای مثل round robin انجام شود یا با تحلیل متریک‌های پیچیده‌تر، تصمیم بهتری بگیرد.

در بخش بعدی به روش‌هایی مثل Anycast Addressing و IP-MAC Forwarding می‌پردازیم.

#http_guideline
@code_crafters
👍8
The_repository_pattern_via_CQRS_with_Python_Django_Elasticsearch.pdf
1.1 MB
پیاده‌سازی الگوی مخزن (Repository) از طریق CQRS با استفاده از Python-Django-ElasticSearch


#Django
#CQRS
#ElasticSearch

@code_crafters
11👎9
داشتم کتاب «طراحی برنامه‌های داده محور» رو میخوندم

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

یجای کتاب بحث راجب داده‌های کلید/مقدار هستش و یک موضوع جالبی مطرح کرد با این عنوان که شما اگه در کلیدی که درست می‌کنید (مثلا ۳۲ کاراکتر) اگه یکمقدار یکتا داشته باشید براتون کافیه تا بعدا هرجا خواستید با اون کلید کار کنید فقط مقدار یکتای اون رو صدا بزنید و داشته باشید


وقتی بهش فکر کردم دیدم همین رو تو پلتفرم‌های روزمرگی مورد استفاده خودمون هم دیدم (لاگ مربوط به گیت که فقط کافیه چند کاراکتر اولش رو بدونی، id مربوط به موجودیت‌های داخل داکر که بازم کافیه چند مقدار اولش رو بدونی، هم لاگ گیت و هم id موجودیت‌های داکر یک رشته حداقل ۶۴ کاراکتری هستند) این مقدار یکتا منجر میشه که هم سرعت کارمون بیشتر بشه هم کار کردن باهاش راحتتر باشه (واسه خودمون و سیستم)

یادمه یبار یکی از بچه‌ها یکی از مشکلاتی که داشتند تو سیستمشون و راجبش باهم صحبت کردیم این بود که کلید ۶۴ کاراکتری رو داخل ردیس ذخیره کرده بودن که از طریق اون به یکسری اطلاعات برسند که مورد استفاده در کل سیستم بود، و خب جستجوی یک مقدار ۶۴ کاراکتری در بین هزارتا کلید با یک مقدار یکتای ۷ کاراکتری خیلی متفاوت هستش

حتی همین ایده کثیف هم برای توکن‌های بزرگ احراز هویت بشدت کاربردی هستش و کار رو برامون راحت تر میکنه، انگار که یک پوینتر مستقیم به اون توکن داریم همیشه و فرقی نمیکنه این توکن در ردیس باشه یا در دیتابیس یا هرجایی دیگه، پوینتر ما همیشه برامون مستقیم به اون توکن اشاره میکنه

بحث جایی جذاب میشه که شما با این پوینتر حتی میتونید کارهای خلاقانه و کثیفی انجام بدید مثه چی؟؟؟ تصور کنید که برنامه شما از لحاظ امنیتی حساس هستش و میخواید فقط در یک لحظه یک حساب کاربری در یک دستگاه هویتش مشخص باشه و ورود کرده باشه، شما دیگه لازم نیست بیاید یک جدول بسازید و کلی منطق بنویسید که این رو مدیریت کرده باشید، کافیه که یک الگوی یکسان برای تولید پوینتر داشته باشید که به راحتی از طریق اون بتونید این موضوع رو مدیریت کنید و تمام

@code_crafters
3
فردوی خفته‌ای بودم
در شبی تاریک و جنگ زده
و تو به تحریک خصمانه بدخواهانمان
عمیقترین نگاه‌های سنگرشکنت را
مخفیانه با شبح چشم‌هایت
سوی قلب من انداختی
عمق من را شکافتی
و من چه بیصدا
در لحظه‌ای غفلت انگیز
و بی دفاع در مقابل تو
از درون فرو ریختم
بگذار روشنایی بیاید
آنگاه که
از این شب تاریک گذر کنیم
و این جنگ میان من و تو به پایان برسد
با دیده خدایان از آسمان
نظاره کن و بنگر
چگونه رنگ باختم
سیما به دگرگونی گرفتم
حفره‌های روی تن من را
که یادگار از تو بجا مانده
و خوشنودی بیگانگان از این تنش را
چه ساده بودم من
که از تووه ستیزه جو
صلح میخواستم
تو بگو
بعد من و شکستن احساس من
با نگاه‌های سنگین مردمان این شهر چه میکنی؟؟؟
🤡9💔5🔥1
بچه‌ها دستم خورد با اکانت ادمین گروه رو پاک کردم

راهی واسه برگردوندنش هست؟؟؟
🤣19🔥1💔1
خب میتونید برگردید

ولی منتها شماره کسی رو نتونم ببینم ریموش میکنم
🍌13🙏2😁1
تو ادامه خوندن کتاب «طراحی برنامه‌های داده محور» به بحث race conditions رسیدم و دو نوع اون رو مطرح کرد (skew, phantom) بحث جایی شدت میگیره که بخوایم از طراحی سیستم‌های توزیع شده استفاده کنیم (بصورت partitioningو node شده)

در بحث skew دو نوع متفاوت داریم

clock skew:
بطور صریح اون رو مشکلات همزمانی صدا می‌زنیم، تصور کنید که چند نود دیتابیس ما در چند منطقه زمانی مختلف قرار دارن (یا به هر دلیل دیگه زمان بندیشون یکسان و هماهنگ نیست بین nodeها)
تصور کنید تایم پزشک برای ساعت ۱۰:۳۰ رو میخوایم رزرو کنیم
نود اول ساعت ده میخواد رزرو کنه (تایم داخلی سیستمش ساعت ۱۰ هستس)
نود دوم در همون موقع میخواد رزو کنه (تایم داخلی سیستمش ساعت ۱۰ و یک ثانیه هستش)
هردو تراکنش انجام میشه بابت ناهماهنگی زمانی و رزرو ساعت ۱۰:۳۰ دقیقه دوتا مشتری داره

data skew:
بطور صریح نابرابری توزیع بهش میگیم، جایی رخ میده که ما دو شیفت برای رزرو داریم و هر شیفت روی پارتیشن جداگانه (یک و دو) ذخیره میشه شیفت اول مشتری بیشتری داره نسبت به شیفت دوم بابت همین تراکنش‌های شیفت اول با کندی بیشتر و سنگینی روبرو میشه


در بحث phantoms هم زمان روی داد
phantom read ، write skew
رخ میده


نود اول دفعه اول چک‌ میکنه و موقع چک دوم میبینه یکسری دیتا دیگه اضافه یا حذف شدن در این بازه و محاسبات (مقادیر موجودیت‌ها تغییر کرده در این بازه)

نود اول چک می‌کنه میبینه رزرو خالیه و موجود، جواب رو برمیگردونه و تو این بازه تصمیم گیری نود دوم میاد میبینه رزرو خالی هستش و رزرو رو ثبت میکنه، نود اول برمیگرده و میبینه تو همین بازه کم رزرو خالی نیست (این رو تو سایتهای پرداخت سهمیه‌ها بشدت میبینیم که معمولا با برگشت پول و تراکنش به مبدا صورت میگیره و هندلش میکنن)


نحوه مقابله و هندل کردنشون چجوریه بیایم از select for update یا redis تو پروژه ازش استفاده کنیم


@code_crafters
4🔥1
در ادامه کتاب «طراحی برنامه‌های داده محور» و موضوع race conditions ها که بالاتر گفتیم دو رویکرد عمده دیگه در داخل دیتابیس‌ها هستش که داخل کتاب مطرح شده

read commit
این رویکرد به ما میگه که باید آخرین تغییرات ثبت شده رو بخونیم و اطمینان از این بابت انجام بدیم که dirty read ها خونده نمیشن در پاسخ به کوئری ها، در پستگرس این رویکرد بصورت پیش فرض فعال هستش و کار میکنه یعنی خود پستگرس این اطمینان رو بهمون میده تغییرات ثبت شده نهایی رو بهمون برمیگردونه (داخل جنگو وقتی commit=False میزنی در واقع dirty read تولید کردی و اگه خوندنی از دیتابیس در اون لحظه صورت بگیره پستگرس خروجی رو شامل این نمیکنه)

اما تو این سطح از کار (read commit اطمینان میده بهمون که dirty read نداشته باشیم) ما یه مشکل داریم اونم (phantom read) non repeatable read ها هستش، یعنی اگه در لحظه خوندن کامیت ثبت شده یک کوئری هم ثبت بشه متاسفانه خروجی شما شامل این تغییرات این کوئری نمیشه اصلا


snapshot isolation
در این سطح در هر کوئری در لحظه اجرا یک تصویر ثابت از دیتابیس بهش میدیم
بابت جلوگیری از مسئله بالا (phantom read) ما سراغ snapshot و ارتقا سطح serializable level در دیتابیس میریم و با فعال کردن repeatable read میایم و مانع این موضوع phantom read میشیم، تو حالت snapshot ما تضمین میکنیم در طول انجام عملیات‌های زمانبر مانند olap کوئری‌ها از یک تصویر از یک سطح دیتابیس بخونن و تا زمان اتمام این حالت باقی بمونه برامون و اگه ناهماهنگی در سطح رکورد ببینه با استفاده از مکانیسم rollback مانع خطا در خروجی میشه، اما این سطح از ایزوله سازی نمیتونه مانع write skew (تو آپدیت های بعدی در کوئری‌های بعدی ممکنه تصویر ما حاوی تغییراتی شده باشه) بشه بابت همین باید سطح ایزوله کردن رو بالا ببریم


serializable isolation
در این سطح از دیتابیس یک تصویر ثابت از دیتابیس به همه کوئری‌ها میدیم
در مشکل بالاتر که گفتیم write skew ما سطح serializable level رو می‌زاریم روی serializable و این بالاترین سطح ایزوله کردن در دیتابیس هستش و مانع این نوع race condition و مابقی خطاهای دیگه در طول این پست میشه (همه رو برامون هندل میکنه-phantom,write,commit,lost update-) تضمین میکنه در یک olap طولانی یک تصویر کامل از دیتابیس داشته باشیم حتی اگر هر چقدر هم زمان کوئری‌ها طول بکشه، تصور کنید دوتا کوئری سنگین زمانبر داریم و ممکنه در مابین این دو کوئری یک write بخواد صورت بگیره اینجا پستگرس با استفاده از مکانیسم conflict detection تشخیص میده تعارض در داده‌های ما بین دو کوئری هستش و rollback میزنه و اطمینان میده که تصاویر یکسانی برای هردو کوئری هست تا خروجی یکسان باشه و بصورت سریالی پشت سرهم (هیچ کویری دیگری بین این دوتا) صورت نگرفته


@code_crafters
3
در ادامه کتاب «طراحی برنامه‌های داده محور» در بخش race conditions کتاب یک الگوی دیگری برای رفع شرایط مسابقه رو هم بررسی میکنه (two-phace locking) یا به اختصار 2PL که البته این رویکرد منسوخ شده اما منتها جهت درک بهتره دو سطح serializable در snapshot کمک کننده هستش

2PL
رویکرد با قفل کردن در دیتابیس عمل میکنه، این الگو بشدت بدبین هستش و هر وقت صورت بگیره دوتا قفل انجام میده بک قفل اشتراکی برای خوندن و بک قفل انحصاری برای نوشتن و تراکنش‌ها رو در صف انتظار قرار میده تا زمانیکه قفل باز بشه (در صورت نیاز کل دیتابیس رو یکجا و به یک صورت قفل میکنه)، موجب کندی و تاخیر شدید در پاسخ به کوئری‌ها میشه و دیتابیس رو از هرگونه عملی محروم میکنه تا کوئری فعال کننده قفل تموم بشه و دیتابیس رو آزاد کنه، تصور کنید که select for update رو روی کل موجودیت دیتابیس اجرا کردید، اما تمام شرایط مسابقه رو هندل میکنه کامل (phamtom read, lost update, write skew, dirty data)، این رویکرد هم کوئری‌ها رو بصورت سریالی انجام میده (انگار که چند کوئری بزرگ و طولانی پشت سرهم اجرا شدن)


snapshot isolation
در رویکرد سطح ایزوله با repeatable read و فعال کردن اون (در اجرای هر کوئری یه تصویر ثابت در ابتدا به کوئری میدیم) ما مشکل phamtom read رو بر طرف میکنیم منتها با مشکل write skew روبرو بودیم، اگه در بدنه atomic بیایم از select for update استفاده کنیم مشکل write skew برطرف میشه منتها مشکل اساسی تر این هستش که تعارض رو فقط برای ردیف اعلام شده بر روی اون انجام میده نه کل دیتابیس و تداخل داده در ردیف‌هایی که قفل روی اون‌ها صورت نگرفته شکل میگیره و write skew همچنان پابرجا هستش

serializable snapshot isolation
یا به اختصار SSI بهش میگیم، رویکرد خوشبینانه در برخورد با اتفاقات داره، دیتابیس رو قفل نمیکنه بلکه یک تصویر ثابت به کوئری میده و مابقی کوئری‌های دیگه اگه خوندن باشن رو باز میزاره جهت اجرا و کوئری‌های نوشتن رو چک میکنه با روش (conflict detection) اگه تداخل باشه لغو و roll back میزنه و در غیر این صورت اجرا میشه، کوئری‌ها رو به شکل سریالی اجرا میکنه و هیچ قفلی روی دیتابیس نمیزاره تو حالت partitioning به خوبی کار میکنه و مناسب کوئری‌های سبک و پرفورمنس عالی برای اونها داره (پرفورمنس بشدت وابسته به رفتار مهندسی نرم افزار در پروژه می باشد) جالبه که در برخورد با conflict detection سخت برخورد نمیکنه (با استفاده از MVCC در پستگرس) تراکنش‌هارو در حد نیاز و کم بررسی میکنه و این عامل پرفورمنس داخلش هستش


یه نکته جالب هم بگم سریالی برخورد کردن با داده خودش یه مفهوم بزرگی هستش که کمک میکنه تا داده رو در یک ترد و یک پردازنده عملیات روش انجا بدیم ایده اصلی redis از این مفهوم و برپایه اون استوار هستش

@code_crafters
7
فیلم نهنگ آرنوفسکی


آرنوفسکی یکی از کارگردان‌های متفکر هستش و بشدت ذهن پویا و فعالی داره


داخل فیلم مدام و مدام آرنوفسکی یه داستانی رو بازگو میکنه که خیلی عمیق هستش

راجب ناخدایی که اتفاقی با یکنفر آشنا میشه و متوجه حضور یک نهنگ در دریا میشه و ناخدا با تصور اینکه با کشتن نهنگ زندگیش بهتر میشه اما غافل از اینکه کشتن نهنگ یعنی پایان زندگی خودش

چه چیزی تو ته این داستان نهفته که آرنوفسکی مدام و مدام تاییدش میکنه، وقتی زندگیت رو صرف چیزی میکنی (هر چیزی) در واقع داری زندگیت رو نابود میکنی، نمیسازیش

ته ماجرا میبینی به چیزی که میخواستی ممکنه رسیده باشی اما زندگیت رفته واقعا و برنمیگرده

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

واقعیت زندگی دردناکتر ازون چیزی هست که بخوای بابتش (یا حتی بابت همه چیزش از بین بره یا فدا کنی) عمر میگذره و در دوران پیری خسته میشی، از خود زندگی که نتونستی بهش برسی و پی ببری بهش


تمام زندگی ما در یک توهم بزرگ و عمیق فرو رفته و در غفلتی بزرگتر پیچیده شده

به نهنگ زندگیتون فکر کنید
👍6
اصول_طراحی_نرم_افزار_و_مدیریت_کامپوننت_ها_1404.pdf
1.3 MB
اصول مهندسی نرم افزار
ساخت، ترکیب، اجرا، پایداری
همراه با مثال پایتون


@Code_Crafters
5
دوچرخه و پارک ملت


آرنجم یکم اذیتم میکنه و دوچرخه رو هم باید ببرم سرویس کنن (ولی در کل دوتامون بهتریم و دوباره شروع کردیم، جاهای نرفته رو رفتن)


سکوت خوبی داره اینجا و عالیه بابت کتاب خوندن
7🤣3
2025/07/12 20:02:39
Back to Top
HTML Embed Code: