<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>نوشته های مهدی امیری متین</title><link>https://virgool.ir/feed/@m.amirimatin</link><description>برنامه نویس وب و اندروید</description><language>fa</language><pubDate>2026-11-10 22:34:04</pubDate><image><url>https://files.virgool.ir/upload/users/28461/avatar/jAsv9E.png</url><title>مهدی امیری متین</title><link>https://virgool.ir/@m.amirimatin</link></image><item><title>معرفی فریم‌ورک Superpowers: متدولوژی مهندسی نرم‌افزار و مهارت‌های عامل‌محور برای Coding Agents</title><link>https://virgool.ir/@m.amirimatin/معرفی-فریم-ورک-superpowers-متدولوژی-مهندسی-نرم-افزار-و-مهارت-های-عامل-محور-برای-coding-agents-tkrtjr1kujae</link><description>با فراگیر شدن ایجنت‌های هوشمند برنامه‌نویسی نظیر Claude Code، OpenAI Codex، Cursor، Devin و OpenCode، سرعت تولید کد توسط هوش مصنوعی به سطحی فراتر از تصور رسیده است. اما هر مهندس نرم‌افزار با‌تجربه‌ای می‌داند که «سرعت در نوشتن کد» لزوماً به معنای «کیفیت در مهندسی نرم‌افزار» نیست.در عمل، زمانی که یک تسک پیچیده یا مبهم را به یک Coding Agent می‌سپارید، مدل معمولاً بلافاصله و با عجله شروع به دستکاری فایل‌ها می‌کند؛ بدون اینکه ابعاد مسئله را به درستی تحلیل کرده باشد، تست‌های اعتبارسنجی بنویسد یا تغییرات را در محیطی ایزوله پیش ببرد. نتیجه این رویکرد تکانشی (Impulsive Coding)، شکستن رفتارهای قبلی سیستم (Regressions)، ایجاد بدهی فنی سنگین و اعلام پیروزی‌های کاذب («من باگ را حل کردم!» در حالی که هیچ شواهدی وجود ندارد) خواهد بود.پروژه متن‌باز و بسیار محبوب Superpowers (با بیش از ۲۷۰ هزار ستاره در گیت‌هاب که توسط جسی وینسنت / Jesse Vincent و تیم Prime Radiant توسعه داده شده است) پاسخی مهندسی به این چالش است. Superpowers یک کتابخانه کد یا SDK معمولی نیست؛ بلکه یک متدولوژی کامل مهندسی نرم‌افزار (Software Development Methodology) و چارچوب مهارت‌های ترکیب‌پذیر (Composable Skills) است که رفتار ایجنت‌ها را از حالت «کدنویسی عجولانه» به سمت «طراحی سقراطی، برنامه‌ریزی اتمیک، TDD سخت‌گیرانه، بازبینی چندمرحله‌ای و تایید مبتنی بر شواهد» هدایت می‌کند.۱. مسئله‌ای که Superpowers حل می‌کند: چرا پرامپت‌نویسی معمولی کافی نیست؟بسیاری از توسعه‌دهندگان تلاش می‌کنند با نوشتن پرامپت‌های طولانی در فایل‌های system instructions یا AGENTS.md رفتار مدل را کنترل کنند. اما در پروژه‌های بزرگ با چندین مرحله کار، مدل‌ها به سادگی دستورالعمل‌های طولانی را فراموش کرده یا آن‌ها را نادیده می‌گیرند.Superpowers این چالش را با تبدیل عادات مهندسی به سیستم‌های رفتاری و مهارت‌های اجباری (Mandatory Skills) حل می‌کند:جلوگیری از کدنویسی قبل از تفکر (No Code Before Design): ایجنت وادار می‌شود پیش از دست زدن به کد، از طریق گفتگو و پرسش‌گری (Brainstorming)، مشخصات فنی و معماری را شفاف و تاییدیه انسانی دریافت کند.پایبندی عملی به TDD واقعی (Strict RED ➔ GREEN ➔ REFACTOR): تست‌ها پیش از پیاده‌سازی نوشته می‌شوند؛ اگر ایجنتی کدی را بدون تست قبلی بنویسد، فریم‌ورک آن را وادار به حذف کد و نوشتن تست شکست‌خورده می‌کند.توسعه ایزوله با Git Worktrees: جلوگیری از آلوده شدن شاخه اصلی کاری و امکان کار هم‌زمان روی چندین فیچر بدون تداخل.حفظ تمرکز با تفویض به Subagentها: شکستن کارهای بزرگ به گام‌های ۲ تا ۵ دقیقه‌ای و اجرای هر تسک توسط یک عامل فرعی با کانتکست تمیز و تازه.ارائه شواهد به جای ادعا (Evidence over Claims): ایجنت مجاز نیست صرفاً بگوید «کار تمام شد»؛ بلکه باید لاگ اجرای موفق تست‌ها و خروجی‌های ملموس را به عنوان سند ارائه دهد.۲. کالبدشکافی معماری سه لایه‌ای فریم‌ورکاز منظر معماری سیستم، Superpowers بر پایه سه لایه به هم پیوسته بنا شده است:┌────────────────────────────────────────────────────────────────────────┐&#xA;│ 1. Behavioral Layer (لایه رفتار: مهارت‌های ترکیب‌پذیر تفکر و تصمیم‌گیری)   │&#xA;│    [brainstorming]  [systematic-debugging]  [writing-skills]           │&#xA;├────────────────────────────────────────────────────────────────────────┤&#xA;│ 2. Process Layer (لایه فرآیند: زنجیره اجرای متدولوژی ۷ مرحله‌ای SDLC)     │&#xA;│    Design ➔ Worktree ➔ Plan ➔ Subagents ➔ TDD ➔ Review ➔ Finish       │&#xA;├────────────────────────────────────────────────────────────────────────┤&#xA;│ 3. Harness Integration Layer (لایه اتصال به زیرساخت ایجنت‌ها)          │&#xA;│    Claude Code │ OpenAI Codex │ Cursor │ Devin │ OpenCode │ Antigravity│&#xA;└────────────────────────────────────────────────────────────────────────┘&#xA;لایه رفتار (Behavioral Layer): مجموعه‌ای از اسکیل‌های مستقل است که نحوه تحلیل و گام‌های فکری مدل را در مواجهه با مسائلی نظیر دیباگ، ریفکتورینگ یا دریافت فیدبک استانداردسازی می‌کند.لایه فرآیند (Process Layer): یک زنجیره مهندسی غیرقابل‌شکست است؛ برای مثال تا زمانی که مرحله طراحی به تایید کاربر نرسد، ورود به مرحله برنامه‌ریزی غیرممکن است.لایه اتصال (Harness Layer): بسته‌بندی‌های اختصاصی افزونه (Plugin) برای هر کدام از کلاینت‌های مطرح AI Agent که اسکیل‌ها را به صورت خودکار در هوک‌های آغاز نشست فعال می‌کنند.۳. چرخه ۷ مرحله‌ای متدولوژی توسعه نرم‌افزار در Superpowersچرخه حیات توسعه فیچر در Superpowers شامل ۷ مرحله متوالی و سیستماتیک است:مرحله ۱: طوفان فکری و طراحی سقراطی (brainstorming)هنگامی که نیاز جدیدی مطرح می‌شود، ایجنت به جای کدنویسی فوری وارد گفتگوی تعاملی می‌شود. ابهامات را می‌پرسد، گزینه‌های مختلف معماری را با مزایا و معایب بررسی می‌کند، طراحی نهایی را در بخش‌های کوچک و خوانا ارائه می‌دهد و پس از تایید نهایی کاربر، سند طراحی را ذخیره می‌کند.مرحله ۲: ایزولاسیون محیط با Git Worktree (using-git-worktrees)پس از تایید طراحی، ایجنت یک شاخه کاری جدید و مجزا در قالب Git Worktree می‌سازد. پکیج‌ها را نصب کرده و مطمئن می‌شود که سوئیت تست‌های فعلی پروژه پاس می‌شوند (Clean Baseline Verification) تا باگ‌های قبلی با تغییرات جدید اشتباه گرفته نشوند.مرحله ۳: نگارش برنامه‌ریزی اتمیک (writing-plans)سند طراحی به وظایف بسیار ریز و اتمیک (Bite-sized Tasks با بازه اجرایی ۲ تا ۵ دقیقه) شکسته می‌شود. هر وظیفه دارای مسیرهای دقیق فایل‌ها، کد کامل پیشنهادی و نحوه دقیق تست و راستی‌آزمایی است؛ برنامه‌ای چنان دقیق که حتی یک مهندس تازه‌کار بدون اطلاع قبلی از پروژه نیز می‌تواند آن را پیاده کند.مرحله ۴: توسعه با عامل‌های فرعی (subagent-driven-development)ایجنت مادر برای اجرای هر گام برنامه، یک Subagent تازه با حافظه خالی ایجاد می‌کند تا از سرریز پنجره کانتکست (Context Bloat) جلوگیری شود. هر وظیفه پس از پیاده‌سازی، تحت بازبینی دو مرحله‌ای قرار می‌گیرد:انطباق کامل با نیازمندی‌ها (Spec Compliance)کیفیت و ساختار کد (Code Quality)مرحله ۵: چرخه آزمون‌محور واقعی (test-driven-development)در طول پیاده‌سازی، قانون سخت‌گیرانه RED ➔ GREEN ➔ REFACTOR اجرا می‌شود:RED: نوشتن یک تست واحد که شکست می‌خورد و مشاهده اجرای شکست آن.GREEN: نوشتن حداقل کد لازم برای پاس شدن همان تست.REFACTOR: پاکسازی و بهینه‌سازی ساختار کد بدون تغییر در رفتار تست‌ها.قانون طلایی: هر کدی که قبل از تست نوشته شده باشد، باید حذف شود!مرحله ۶: درخواست بازبینی کد (requesting-code-review)بین مراحل و پیش از نهایی‌سازی، تغییرات با چک‌لیست‌های پیشرفته بازبینی می‌شوند. ایرادات بر اساس سطح اهمیت (Critical، Major، Minor) دسته‌بندی شده و وجود باگ‌های حیاتی مانع از ادامه کار می‌شود.مرحله ۷: تایید و بستن شاخه توسعه (finishing-a-development-branch)تمام تست‌های سرتاسری پروژه اجرا می‌شوند. گزینه‌های مختلف شامل ادغام مستقیم (Merge)، ایجاد Pull Request یا نگهداری شاخه به کاربر پیشنهاد داده شده و در نهایت محیط Worktree به صورت خودکار پاکسازی می‌شود.۴. اصول و فلسفه بنیادین Superpowersاصل مهندسی مفهوم و نحوه اعمال در فریم‌ورک Test-Driven Development تست‌ها همیشه قبل از کد نوشته می‌شوند؛ تست فقط برای تایید نیست، بلکه ابزار طراحی است. Systematic over Ad-hoc حل مسئله و عیب‌یابی بر اساس فرآیند گام‌به‌گام و ریشه‌یابی، نه حدس‌های تصادفی. Complexity Reduction تمرکز شدید بر اصول YAGNI (به آن نیاز نخواهی داشت) و DRY جهت پرهیز از کدهای پیچیده و اضافه. Evidence over Claims ارائه مدارک و شواهد قطعی (اجرای تست‌ها، لاگ خروجی) پیش از اعلام اتمام موفق کار.۵. جعبه‌ابزار مهارت‌های شاخص (Skills Library)علاوه بر زنجیره اصلی، Superpowers کتابخانه‌ای از مهارت‌های تخصصی را ارائه می‌دهد:systematic-debugging: فرآیند ۴ مرحله‌ای دیباگ سیستماتیک شامل بازتولید پایدار، ردیابی علت ریشه‌ای در پشته فراخوانی، دفاع در عمق و اصلاح دقیق بدون ایجاد رگرسیون.verification-before-completion: وادار ساختن ایجنت به اجرای تست مستقل از شواهد پیشین قبل از بسته شدن تسک.dispatching-parallel-agents: اجرای هم‌زمان وظایف مستقل توسط چندین عامل به صورت موازی جهت تسریع چشمگیر توسعه.writing-skills: فرآیند استاندارد ساخت مهارت‌های جدید برای ایجنت به همراه فریم‌ورک ارزیابی و تست رفتار اسکیل‌ها.۶. راهنمای نصب و راه‌اندازی در ابزارهای مختلف (Installation Guide)فریم‌ورک Superpowers برای تمامی محیط‌های شاخص هوش مصنوعی به عنوان پلاگین رسمی عرضه شده است:۱. نصب در Claude Code# از طریق مارکت‌پلیس رسمی آنتروپیک&#xA;/plugin install superpowers@claude-plugins-official&#xA;&#xA;# یا از طریق مارکت‌پلیس پروژه&#xA;/plugin marketplace add obra/superpowers-marketplace&#xA;/plugin install superpowers@superpowers-marketplace&#xA;۲. نصب در OpenAI Codex CLI و Appدر ترمینال Codex CLI دستور /plugins را تایپ کرده، عبارت superpowers را جستجو و گزینه Install Plugin را انتخاب کنید.۳. نصب در Cursorدر پنل Agent ادیتور Cursor دستور زیر را وارد نمایید:/add-plugin superpowers&#xA;۴. نصب در Antigravityagy plugin install https://github.com/obra/superpowers&#xA;۵. نصب در سایر ابزارهاDevin CLI: devin plugins install obra/superpowersGemini CLI: gemini extensions install https://github.com/obra/superpowersOpenCode: مطابق راهنمای .opencode/INSTALL.md در ریپازیتوری پروژه.GitHub Copilot CLI: copilot plugin install superpowers@superpowers-marketplace۷. چه زمانی باید از Superpowers استفاده کرد؟ (سناریوها و ملاحظات)سناریوهای طلایی برای استفاده:توسعه قابلیت‌های جدید (New Features): زمانی که نیازمندی‌ها چندوجهی هستند و نیازمند شفاف‌سازی معماری پیش از کدنویسی است.ریفکتورینگ‌های سنگین و حساس: زمانی که تغییر ساختار نباید هیچ‌یک از رفتارهای قبلی سیستم را تخریب کند.پروژه‌های تیمی بزرگ: جهت یکپارچه‌سازی متدولوژی کدنویسی بین اعضای مختلف تیم و ایجنت‌های متنوع.رفع باگ‌های پیچیده و ریشه‌ای: جهت جلوگیری از پچ‌های سطحی و حدسی.چه زمانی مناسب نیست؟Superpowers عمداً یک متدولوژی سخت‌گیرانه و فرآیندگرا است. برای ویرایش‌های بسیار ساده نظیر اصلاح یک غلط املایی، تغییر یک خط استایل CSS یا کانفیگ‌های تک‌خطی، اجرای تمام ۷ مرحله SDLC باعث ایجاد سربار فرآیندی غیرضروری می‌شود.۸. جدول مقایسه: توسعه سنتی با ایجنت‌ها در برابر متدولوژی Superpowersویژگی رویکرد معمولی (Raw Agent / Prompting) با متدولوژی Superpowers برخورد اولیه با مسئله کدنویسی فوری و بر اساس فرضیات ذهنی مدل طراحی سقراطی، شفاف‌سازی و تایید کاربر محیط توسعه اعمال مستقیم روی شاخه کاری جاری ایزولاسیون کامل با Git Worktrees استراتژی تست بدون تست یا نوشتن تست‌های تشریفاتی در پایان الزام به TDD واقعی (RED-GREEN-REFACTOR) مدیریت کانتکست یک ترِد طولانی همراه با سرریز حافظه تقسیم کار به Subagents با حافظه تمیز سطح اطمینان از نتیجه ادعای مدل بر مبنای توهمات زبانی ارائه شواهد عینی لاگ و پاس شدن تست‌ها سازگاری ابزاری وابسته به ابزار خاص پشتیبانی یکپارچه از Claude، Codex، Cursor و...۹. جمع‌بندی و نتیجه‌گیریپروژه Superpowers نقطه عطفی در بلوغ ابزارهای Agentic AI به شمار می‌رود. این فریم‌ورک ثابت می‌کند که ارتقای کیفیت کدهای تولیدشده توسط هوش مصنوعی، نیازمند مدل‌های زبانی بزرگتر نیست؛ بلکه نیازمند نظم و متدولوژی مهندسی نرم‌افزار در نحوه تفکر و اجرای ایجنت‌ها است.با استفاده از Superpowers، دستیار کدنویسی شما دیگر یک ماشین تولید حدسی کد نخواهد بود؛ بلکه مانند یک مهندس ارشد و با‌انضباط، پروژه‌های نرم‌افزاری شما را از مرحله تفکر تا استقرار هدایت خواهد کرد.✍️ درباره نویسنده:برای مطالعه مقالات تخصصی بیشتر در حوزه‌های SRE، دیتابیس، زیرساخت و خودکارسازی کدنویسی، می‌توانید به وب‌سایت من به نشانی amirimatin.ir مراجعه کنید.</description><category>مهدی امیری متین</category><author>مهدی امیری متین</author><pubDate>Mon, 31 Aug 2026 11:51:09 +0330</pubDate></item><item><title>معرفی CodeSearch: موتور جستجوی معنایی و هیبریدی کد برای ایجنت‌های هوش مصنوعی (Claude Code، Codex CLI و OpenCode)</title><link>https://virgool.ir/@m.amirimatin/معرفی-codesearch-موتور-جستجوی-معنایی-و-هیبریدی-کد-برای-ایجنت-های-هوش-مصنوعی-claude-code-codex-cli-و-opencode-o8oswzaupb7k</link><description>با ظهور و تکامل دستیاران خودکار کدنویسی و ابزارهای مبتنی بر Agentic AI نظیر Claude Code، OpenAI Codex CLI، OpenCode و Cursor، سبک توسعه نرم‌افزار دستخوش تحولی بنیادین شده است. در این پارادایم نوین، ایجنت‌های هوشمند دیگر فقط یک مدل تکمیل کد درون ادیتور نیستند؛ بلکه مستقیماً به محیط ترمینال، سیستم فایل و مخازن کد دسترسی داشته و وظایف پیچیده‌ای نظیر ریفکتورینگ گسترده، کشف باگ‌های ساختاری و توسعه ماژول‌های جدید را بر عهده می‌گیرند.اما در پروژه‌های واقعی و انترپرایز با صدها هزار خط کد و چندین مونو‌ریپو (Monorepo) یا سرویس مجزا، این ایجنت‌ها بلافاصله با یک گلوگاه اساسی مواجه می‌شوند: ناتوانی ابزارهای سنتی مثل grep یا ripgrep در درک معنایی معماری پروژه و پدیده‌ای موسوم به Context Bloat (انفجار مصرف توکن).در این مقاله، به کالبدشکافی و راهنمای جامع ابزار متن‌باز و قدرتمند CodeSearch می‌پردازیم؛ یک سرور محلی Model Context Protocol (MCP) توسعه‌یافته با زبان Rust که با ترکیب جستجوی برداری (Vector Search) و متنی (BM25)، موتور نحو درختی (Tree-sitter AST) و ناوبری نمادها (Symbol Navigation)، تجربه کاربری ایجنت‌های هوش مصنوعی را به سطحی بالاتر ارتقا می‌دهد.۱. چرا ابزارهای سنتی (grep و find) برای ایجنت‌های AI شکست می‌خورند؟بسیاری از دستیاران هوش مصنوعی به صورت پیش‌فرض برای کاوش در پروژه‌ها از دستورات خط فرمانی مانند grep، ripgrep یا find استفاده می‌کنند. این رویکرد در محیط‌های عملیاتی با چالش‌های زیر روبرو است:عدم درک مفاهیم انتزاعی و مترادف‌ها (Synonym Blindness): اگر شما از ایجنت بخواهید «نحوه مدیریت نرخ درخواست‌ها (Rate Limiting) را پیدا کن»، ابزار grep به دنبال رشته تحت‌اللفظی rate_limiting می‌گردد. اگر نام تابع در پروژه throttleRequests یا TokenBucketFilter باشد، نتیجه صفر خواهد بود.پدیده Context Bloat و هدررفت فاحش توکن: هنگامی که grep فایل‌های احتمالی را برمی‌گرداند، ایجنت چاره‌ای جز خواندن کل محتوای فایل‌ها (cat file.ts) ندارد. خواندن چندین فایل چندصدخطی تنها برای یافتن یک تابع ۲۰ خطی، پنجره کانتکست مدل را اشباع کرده، هزینه‌های API را به شدت افزایش می‌دهد و باعث کاهش دقت (Hallucination) مدل می‌شود.محدودیت‌های راهکارهای ابری و گراف‌های سنگین: ابزارهای Code-Graph ابری یا پایگاه‌های داده برداری سنگین معمولاً نیازمند کارت گرافیک اختصاصی (GPU)، کانتینرهای داکر حجیم، ارسال کدهای محرمانه به سرورهای ثالث و تنظیمات شبکه پیچیده هستند که در محیط‌های محلی و پروکسی‌های انترپرایز با چالش جدی مواجه می‌شوند.۲. معرفی CodeSearch: معماری و نحوه عملکرد زیر کاپوت (Under the Hood)پروژه CodeSearch یک سرور مستقل، سبک و فوق‌سریع بر پایه پروتکل MCP است که به صورت ۱۰۰٪ محلی و آفلاین روی CPU اجرا می‌شود. این ابزار از هیچ سرویس کلودی یا مدل ران‌تایم خارجی استفاده نمی‌کند و تمام فرآیند ایندکسینگ و بازیابی را در کسری از ثانیه انجام می‌دهد.ارکان اصلی معماری CodeSearch:بازیابی هیبریدی (Hybrid Retrieval with RRF):کدسرچ برای هر کوئری دو استراتژی مجزا را به صورت موازی اجرا می‌کند:Dense Retrieval (برداری): تولید امبدینگ‌های متراکم با استفاده از مدل‌های بهینه روی CPU (مانند FastEmbed با موتور ONNX Runtime نظیر nomic-embed-text-v1.5 یا bge-small-en-v1.5) و ذخیره در شاخص برداری arroy (موتور جستجوی نزدیک‌ترین همسایگی ANN توسعه داده شده توسط تیم Meilisearch) روی پایگاه‌داده حافظه‌محور LMDB.Sparse Retrieval (متنی): جستجوی متنی پیشرفته بر اساس الگوریتم محبوب BM25 از طریق موتور قدرتمند Tantivy به همراه پشتیبانی از عبارات باقاعده (Regex) و تطابق دقیق شناسه‌ها.ترکیب رتبه‌بندی با Reciprocal Rank Fusion (RRF): نتایج بازیابی متنی و برداری با الگوریتم RRF ترکیب می‌شوند تا بالاترین دقت بازیابی معنایی و ساختاری حاصل شود.قطعه‌بندی هوشمند با درخت نحو (Tree-sitter AST Chunking):برخلاف سیستم‌های سنتی RAG که فایل‌ها را بر اساس تعداد خطوط تصادفی (مثلاً هر ۱۰۰ خط) برش می‌زنند، CodeSearch با استفاده از گرامر Tree-sitter ساختار واقعی کد در بیش از ۱۷ زبان برنامه‌نویسی را تحلیل می‌کند. قطعات (Chunks) دقیقاً بر مبنای توابع، کلاس‌ها، متدها، بلوک‌های مارک‌داون یا سلول‌های ژوپیتر ساخته می‌شوند.طراحی بهینه بر اساس صرفه‌جویی در توکن (Token-Efficient Design):به صورت پیش‌فرض نتایج جستجو در حالت فشرده (compact=true) شامل شناسه قطعه (chunk_id)، مسیر فایل، شماره خطوط و امضای متد بازگردانده می‌شوند. ایجنت پس از ارزیابی متادیتا، تنها در صورت نیاز واقعی بدنه کد را با ابزار get_chunk دریافت می‌کند.پشتیبانی بومی از چند مخزن (Multi-Repo &amp; Federation):قابلیت مدیریت ده‌ها پروژه به صورت هم‌زمان، گروه‌بندی مخازن و اتصال توزیع‌شده به سرورهای راه دور (Peer Federation) از طریق HTTPS و احراز هویت Bearer Token.۳. ابزارهای ۵ گانه سرور MCP کدسرچ (Core Tools Reference)سرور CodeSearch مجموعه‌ای از ابزارهای استاندارد MCP را در اختیار مدل‌های هوش مصنوعی قرار می‌دهد:نام ابزار MCP نوع کاربرد ورودی‌های کلیدی خروجی و رفتار search جستجوی معنایی یا متنی query, mode, filter_path, language, compact ترکیب Vector + BM25 در حالت Semantic یا جستجوی Tantivy در حالت Literal find ناوبری و ردیابی نمادها symbol, kind (definition / usages / imports / dependents) یافتن تعاریف، مصارف و ارتباطات میان فایل‌ها explore کاوش ساختاری فایل target, kind (outline / similar) دریافت لیست تمام توابع و کلاس‌های یک فایل یا یافتن چانک‌های مشابه get_chunk خواندن قطعه کد مشخص chunk_id, context_lines, project فراخوانی متن دقیق کد بر اساس شناسه بازگشتی با حداقل مصرف توکن find_impact تحلیل اثر تغییرات (Call Sites) symbol_name, file, line ردیابی تمامی نقاط فراخوانی با پروتکل SCIP (ویژه C# و TypeScript) status وضعیت ایندکس و متادیتا kind (index / projects) اطلاعات سلامت ایندکس، زبان‌های پشتیبانی‌شده و لیست ریپوها۴. راهنمای نصب و راه‌اندازی (Installation &amp; Setup)روش اول: دانلود باینری‌های از پیش کامپایل‌شدهمی‌توانید آخرین نسخه اجرایی را متناسب با سیستم‌عامل خود مستقیماً از بخش Releases گیت‌هاب CodeSearch دانلود کرده و در مسیر $PATH قرار دهید:# دانلود نسخه لینوکس x86_64&#xA;curl -sL https://github.com/flupkede/codesearch/releases/latest/download/codesearch-linux-x86_64.tar.gz | tar xz&#xA;chmod +x codesearch&#xA;sudo mv codesearch /usr/local/bin/&#xA;&#xA;# بررسی نسخه&#xA;codesearch --version&#xA;روش دوم: کامپایل از سورس کد (Rust &amp; Cargo)در صورتی که ابزارهای توسعه زبان Rust را روی سیستم دارید:# کلون و کامپایل نسخه Release&#xA;git clone https://github.com/flupkede/codesearch.git&#xA;cd codesearch&#xA;cargo build --release&#xA;&#xA;# انتقال باینری به مسیر اجرایی&#xA;sudo cp target/release/codesearch /usr/local/bin/&#xA;۵. نحوه ایندکس کردن پروژه‌ها (Project Indexing)فرایند ایندکس‌گذاری در کدسرچ به صورت محلی و با سرعت خیره‌کننده انجام می‌شود.۱. ایندکس یک پروژه جاری (Single Repo)وارد دایرکتوری پروژه مورد نظر خود شوید و دستور زیر را اجرا کنید:cd /path/to/my-project&#xA;&#xA;# ثبت و ایندکس‌گذاری کامل مخزن&#xA;codesearch index add&#xA;دستور فوق پروژه را در فایل کانفیگ ~/.codesearch/repos.json ثبت کرده و پایگاه‌داده شاخص را ایجاد می‌کند.۲. انتخاب مدل امبدینگ (Embedding Model)به صورت پیش‌فرض مدل nomic-embed-text-v1.5 با کیفیت و سرعت عالی استفاده می‌شود. در صورت تمایل می‌توانید مدل مورد نظر را مشخص کنید:codesearch index --model nomic-embed-text-v1.5&#xA;۳. مدیریت فایل‌های نادیده‌گرفته‌شده (.codesearchignore)مشابه .gitignore، می‌توانید فایلی با نام .codesearchignore در ریشه مخزن بسازید تا دایرکتوری‌های بیلد، لاگ‌ها یا داکیومنت‌های حجیم ایندکس نشوند:# .codesearchignore&#xA;dist/&#xA;build/&#xA;coverage/&#xA;*.min.js&#xA;legacy/&#xA;۶. اتصال به ایجنت‌های هوش مصنوعی (MCP Integration)کدسرچ می‌تواند به دو شیوه در اختیار ایجنت‌ها قرار گیرد:حالت محلی (Local Stdio Mode): اجرای مستقیم codesearch mcp به عنوان یک ساب‌پراسس توسط کلاینت.حالت سرور مرکزی (Serve HTTP Mode): اجرای دائم codesearch serve با داشبورد TUI و پشتیبانی هم‌زمان از چندین مخزن.۱. اتصال در Claude Code و Claude Desktopفایل تنظیمات MCP کلاینت کلود را در مسیر ~/.config/claude-code/config.json (یا claude_desktop_config.json) باز کرده و سرور کدسرچ را اضافه کنید:{&#xA;  &#34;mcpServers&#34;: {&#xA;    &#34;codesearch&#34;: {&#xA;      &#34;command&#34;: &#34;codesearch&#34;,&#xA;      &#34;args&#34;: [&#34;mcp&#34;]&#xA;    }&#xA;  }&#xA;}&#xA;اگر سرور چندمخزنه را از قبل با دستور codesearch serve اجرا کرده‌اید، از آرگومان کلاینت استفاده کنید:{&#xA;  &#34;mcpServers&#34;: {&#xA;    &#34;codesearch&#34;: {&#xA;      &#34;command&#34;: &#34;codesearch&#34;,&#xA;      &#34;args&#34;: [&#34;mcp&#34;, &#34;--mode&#34;, &#34;client&#34;]&#xA;    }&#xA;  }&#xA;}&#xA;۲. اتصال در OpenCodeدر فایل ~/.config/opencode/config.json:{&#xA;  &#34;mcp&#34;: {&#xA;    &#34;codesearch&#34;: {&#xA;      &#34;type&#34;: &#34;local&#34;,&#xA;      &#34;command&#34;: [&#34;codesearch&#34;, &#34;mcp&#34;],&#xA;      &#34;enabled&#34;: true&#xA;    }&#xA;  }&#xA;}&#xA;یا اتصال از طریق ریموت HTTP در حالت Serve:{&#xA;  &#34;mcp&#34;: {&#xA;    &#34;codesearch&#34;: {&#xA;      &#34;type&#34;: &#34;remote&#34;,&#xA;      &#34;url&#34;: &#34;http://127.0.0.1:39725/mcp&#34;,&#xA;      &#34;enabled&#34;: true&#xA;    }&#xA;  }&#xA;}&#xA;۳. اتصال در Codex CLI و Cursorدر ادیتور Cursor یا محیط‌های مشابه، می‌توانید در بخش MCP Servers دستور codesearch mcp را اضافه کنید. همچنین جهت ملزم کردن مدل به استفاده از این موتور به جای ابزارهای کند، دستورالعمل زیر را در فایل AGENTS.md یا .cursorrules پروژه قرار دهید:# Agent Code Search Policy&#xA;- For finding implementations, tracing flows, or symbol usages, always prefer `codesearch` MCP tools (`search`, `find`, `explore`, `get_chunk`).&#xA;- Avoid running raw `grep` or full-file reads unless dealing with trivial single-line edits or exact literal matches in a single known file.&#xA;- When calling `search`, inspect metadata with `compact=true` first, then fetch exact code chunks via `get_chunk(chunk_id)`.&#xA;۷. حالت Serve Mode و مانیتورینگ چندمخزنه (Multi-Repo Hub)برای تیم‌های توسعه و محیط‌های چندسرویسی، اجرای کدسرچ در حالت سرور مستقل بهترین بازدهی را دارد:codesearch serve&#xA;این فرمان یک رابط کاربری ترمینالی جذاب (Ratatui TUI Dashboard) را باز می‌کند که وضعیت شاخص مخازن، تعداد چانک‌ها، ترافیک کوئری‌ها و وضعیت واچرهای فایل را به صورت لایو نمایش می‌دهد.┌── CodeSearch Hub (Port 39725) ────────────────────────────────────────────────────────┐&#xA;│ [auth-service]      Indexed: 1,420 chunks  │ Watcher: Active   │ RAM: 142 MB           │&#xA;│ [payment-gateway]   Indexed: 3,890 chunks  │ Watcher: Active   │ RAM: 210 MB           │&#xA;│ [frontend-core]     Indexed: 5,120 chunks  │ Watcher: Idle     │ RAM: 180 MB           │&#xA;├───────────────────────────────────────────────────────────────────────────────────────┤&#xA;│ Active Queries: 2 | Total Invocations: 1,489 | Cache Hit Rate: 94.2%                  │&#xA;└───────────────────────────────────────────────────────────────────────────────────────┘&#xA;گروه‌بندی مخازن (Repo Groups)می‌توانید مخازن مرتبط را در گروه‌های اختصاصی دسته‌بندی کنید تا ایجنت بتواند در سطح کل یک دامنه کسب‌وکار به جستجو بپردازد:# ایجاد گروه میکرو‌سرویس‌های مالی&#xA;codesearch group add fin-services auth-service payment-gateway billing-api&#xA;&#xA;# جستجوی معنایی هم‌زمان در تمام سرویس‌های مالی&#xA;codesearch search &#34;handle idempotent refund&#34; --group fin-services&#xA;۸. مقایسه جامع: ابزارهای جستجوی سنتی، پلتفرم‌های ابری و CodeSearchشاخص فنی دستورات سنتی (grep / rg) ابزارهای ابری و گراف‌های سنگین CodeSearch MCP درک معنایی کانسپت‌ها ندارد (فقط تطابق رشته) دارد کامل (ترکیب Vector ANN + BM25) سرعت پاسخ‌دهی بسیار بالا متغیر (وابسته به شبکه و ابر) فوق‌العاده بالا (زیر ۲۰ میلی‌ثانیه) مصرف منابع سیستم بسیار کم سنگین (GPU / چند گیگابایت رم) بسیار سبک (CPU Only / چندصد مگابایت) میزان مصرف توکن ایجنت بسیار زیاد (بارگذاری کل فایل) متوسط حداقلی با مکانیزم compact و get_chunk امنیت و حریم خصوصی ۱۰۰٪ محلی نیازمند خروج کد از زیرساخت ۱۰۰٪ محلی، ایزوله و آفلاین پروتکل ارتباطی Stdio CLI API اختصاصی پروتکل استاندارد MCP۹. جمع‌بندی و نتیجه‌گیری عملیاتیورود به عصر توسعه مبتنی بر ایجنت (Agentic Software Development) نیازمند بازطراحی ابزارهای پیرامونی هوش مصنوعی است. تکیه بر دستورات دهه‌های گذشته نظیر grep، پتانسیل مدل‌های زبانی را در گرداب مصرف بیهوده توکن و گمراهی در معماری غرق می‌کند.ابزار CodeSearch با بهره‌گیری از قدرت و حافظه امن زبان Rust، ترکیب هوشمندانه پایگاه داده برداری متراکم و شاخص متنی BM25 و انطباق کامل با پروتکل استاندارد MCP، زیرساختی ایده‌آل، رایگان و بدون دغدغه ابری را برای توسعه‌دهندگان و معماران نرم‌افزار فراهم ساخته است.✍️ درباره نویسنده:برای مطالعه مقالات تخصصی بیشتر در حوزه‌های SRE، دیتابیس، لینوکس و ابزارهای Agentic AI، می‌توانید به وب‌سایت من به نشانی amirimatin.ir مراجعه کنید.</description><category>مهدی امیری متین</category><author>مهدی امیری متین</author><pubDate>Mon, 31 Aug 2026 11:12:05 +0330</pubDate></item><item><title>کالبدشکافی Binary Log در MySQL: از شاه‌کلید رپلیکیشن تا فاجعه دیسک در سرورهای Standalone</title><link>https://virgool.ir/@m.amirimatin/کالبدشکافی-binary-log-در-mysql-از-شاه-کلید-رپلیکیشن-تا-فاجعه-دیسک-در-سرورهای-standalone-wnio2ln5y4jk</link><description>در معماری پایگاه‌داده‌های مبتنی بر MySQL و MariaDB، لاگ دودویی یا Binary Log (Binlog) یکی از حیاتی‌ترین اجزای سیستم ذخیره‌سازی و پایداری داده‌ها محسوب می‌شود. اما این ابزار قدرتمند مانند یک شمشیر دو لبه عمل می‌کند؛ اگر به درستی درک و پیکربندی نشود، می‌تواند پایگاه‌داده پروداکشن شما را با بحران‌های خاموش نظیر پر شدن ناگهانی دیسک (Disk Space Outage) و گلوگاه‌های مرگبار I/O روبه‌رو کند.در این مقاله، معماری درونی Binlog، نقش آن در رپلیکیشن و ریکاوری، خطرات آن در دیتابیس‌های مستقل (Standalone) و مجموعه تنظیمات بهینه‌سازی عملیاتی را بررسی می‌کنیم.۱. باینری لاگ (Binlog) دقیقاً چیست و چگونه کار می‌کند؟بر خلاف Redo Log که یک لاگ فیزیکی با بافر چرخشی (Circular Buffer) ویژه موتور ذخیره‌سازی InnoDB جهت تضمین ویژگی‌های ACID و بازیابی پس از کرش (Crash Recovery) است، Binary Log در لایه سرور MySQL (بالاتر از Storage Engine) قرار دارد.باینری لاگ تمامی تغییرات روی داده‌ها (DML نظیر INSERT، UPDATE، DELETE) و تغییرات ساختاری پایگاه‌داده (DDL نظیر CREATE TABLE، ALTER TABLE) را به صورت ترتیبی و رویدادمحور ثبت می‌کند.فرآیند Two-Phase Commit (2PC)برای جلوگیری از هرگونه عدم تطابق بین داده‌های ذخیره‌شده روی دیسک و لاگ‌های ارسالی به رپلیکاها، MySQL از مکانیزم XA Two-Phase Commit میان InnoDB و Binlog استفاده می‌کند:Prepare Phase: تغییرات در Redo Log نوشته شده و وضعیت آن روی PREPARED قرار می‌گیرد.Binlog Write &amp; Fsync: تراکنش در باینری لاگ نوشته شده و با دستور fsync روی دیسک پایدار می‌شود.Commit Phase: موتور InnoDB تراکنش را در Redo Log به حالت COMMITTED تغییر می‌دهد.۲. نقش حیاتی Binlog در کلاسترهای رپلیکیشن (Replication)در سناریوهای Master-Replica (Source-Replica)، باینری لاگ موتور محرک همگام‌سازی است:Binlog Dump Thread: روی سرور سورس اجرا شده و با رسیدن هر رویداد جدید به باینری لاگ، آن را از طریق سوکت شبکه به رپلیکا ارسال می‌کند.I/O Thread: روی سرور رپلیکا رویدادها را دریافت کرده و در فایلی محلی به نام Relay Log ذخیره می‌کند.SQL Thread (یا Worker Threads در MTS): رویدادها را از Relay Log خوانده و روی داده‌های محلی رپلیکا اعمال می‌نماید.فرمت‌های مختلف باینری لاگSTATEMENT: فقط متن کوئری SQL لاگ می‌شود. (حجم کم، اما خطرناک در توابع غیر قطعی مثل NOW()، UUID() یا RAND()).ROW: تغییرات واقعی ردیف‌ها به صورت بیتی ذخیره می‌شوند. (استاندارد پیشنهادی صنعت و الزامی برای Group Replication و ابزارهای CDC مانند Debezium).MIXED: ترکیبی هوشمند که پیش‌فرض Statement است و در موارد غیراستاندارد به Row تغییر وضعیت می‌دهد.شناسه تراکنش جهانی (GTID)با استفاده از GTID (Global Transaction Identifier)، هر تراکنش دارای یک امضای یکتا (Source_UUID:Transaction_ID) در سراسر کلاستر است. این ویژگی عملیات Failover و جابجایی رپلیکا بین نودها را بدون نیاز به آدرس‌دهی دستی فایل و موقعیت لاگ (binlog-file و binlog-pos) ممکن می‌سازد.۳. خطرات و دردسرهای فعال بودن Binlog در دیتابیس‌های تک‌نود (Standalone)بسیاری از معماران سیستم با این تصور که «چون از نسخه ۸ پیش‌فرض روشن است، پس نیازی به دستکاری ندارد»، پایگاه‌های داده منفرد (بدون رپلیکا) را رها می‌کنند. این موضوع ریسک‌های عملیاتی شدیدی به همراه دارد:۱. پر شدن ناگهانی دیسک (Disk Exhaustion Disaster)در دیتابیس‌های تک‌نود، اگر مقدار نگهداری لاگ‌ها (binlog_expire_logs_seconds) نامناسب باشد، به مرور زمان صدها فایل گیگابایتی ایجاد می‌شود. زمانی که دیسک به ۱۰۰٪ برسد:سرویس mysqld وارد حالت Read-Only شده یا کرش می‌کند.جداول خراب شده و بالا آمدن مجدد نیازمند فرآیند پر ریسک Crash Recovery خواهد بود.۲. افت شدید توان عملیاتی (I/O Bottleneck &amp; fsync Overhead)تنظیم پیش‌فرض sync_binlog = 1 به ازای تک‌تک تراکنش‌های Commit شده یک درخواست fsync به سیستم‌فایل ارسال می‌کند. این کار دیسک (مخصوصاً ذخیره‌سازهای اشتراکی، HDD یا SSDهای با IOPS محدود) را به شدت اشباع کرده و Latency تراکنش‌ها را چند برابر می‌کند.۳. سرریز لاگ موقت در تراکنش‌های حجیم (Bulk Transactions)اجرای دستوراتی مانند UPDATE یا DELETE روی چند میلیون رکورد باعث پر شدن binlog_cache_size در RAM شده و MySQL را مجبور می‌کند داده‌های موقت لاگ را در دیسک بنویسد (Binlog_cache_disk_use) که سرعت اجرای تراکنش را به شدت کاهش می‌دهد.۴. چه زمانی در سرورهای Standalone به باینری لاگ نیاز داریم؟خاموش کردن کامل Binlog در سرورهای تک‌نود همیشه راهکار درستی نیست. شما در دو سناریوی حیاتی به آن نیاز دارید:بازیابی نقطه در زمان (Point-In-Time Recovery - PITR):اگر ساعت ۱۲:۰۰ ظهر بکاپ کامل تهیه کرده باشید و ساعت ۱۶:۰۰ دیتابیس دچار خطای انسانی شود، با داشتن Binlog می‌توانید دیتابیس را دقیقاً به ثانیه قبل از رخداد خطا بازگردانید.ابزارهای Change Data Capture (CDC):انتقال بلادرنگ تغییرات به Elasticsearch، Kafka یا ClickHouse از طریق ابزارهایی نظیر Debezium به باینری لاگ وابسته است.نکته کلیدی: اگر به هیچ‌کدام از موارد بالا نیاز ندارید و بکاپ‌های روزانه برای شما کافی است، می‌توانید در دیتابیس Standalone باینری لاگ را به طور کامل با disable_log_bin غیرفعال کرده و بهره‌وری I/O را تا ۳۰٪ افزایش دهید.۵. چک‌لیست و تنظیمات بهینه‌سازی در my.cnfبرای دستیابی به بیشترین پایداری و حداقل تاخیر در محیط پروداکشن، کانفیگ زیر پیشنهاد می‌شود:[mysqld]&#xA;# -------------------------------------------------------------&#xA;# 1. فعال‌سازی و فرمت باینری لاگ&#xA;# -------------------------------------------------------------&#xA;server-id                          = 101&#xA;log_bin                            = /var/log/mysql/mysql-bin&#xA;binlog_format                      = ROW&#xA;binlog_row_image                   = MINIMAL      # فقط ستون‌های تغییر یافته ذخیره شوند تا حجم لاگ کاهش یابد&#xA;&#xA;# -------------------------------------------------------------&#xA;# 2. مدیریت دیسک و چرخه حذف خودکار لاگ‌ها (بسیار حیاتی)&#xA;# -------------------------------------------------------------&#xA;max_binlog_size                    = 256M         # اندازه هر فایل لاگ (بین 256M تا 1G)&#xA;binlog_expire_logs_seconds         = 259200       # نگهداری دقیقاً به مدت ۳ روز (3 * 86400)&#xA;&#xA;# -------------------------------------------------------------&#xA;# 3. بهینه‌سازی کارایی دیسک و Group Commit&#xA;# -------------------------------------------------------------&#xA;# در سرورهای با حساسیت حداکثری: 1&#xA;# در سیستم‌های نیازمند Throughput بالا با ریسک از دست رفتن چند میلی‌ثانیه: 0 یا 100&#xA;sync_binlog                        = 1&#xA;&#xA;# فعال‌سازی Group Commit برای تجمیع تراکنش‌ها قبل از fsync&#xA;binlog_group_commit_sync_delay     = 50           # میکروثانیه تاخیر برای تجمیع تراکنش‌ها&#xA;binlog_group_commit_sync_no_delay_count = 10&#xA;&#xA;# -------------------------------------------------------------&#xA;# 4. حافظه بافر باینری لاگ&#xA;# -------------------------------------------------------------&#xA;binlog_cache_size                  = 1M           # حافظه رم اختصاصی به ازای هر سشن برای نگهداری تراکنش&#xA;max_binlog_cache_size              = 1G           # حداکثر حجم یک تراکنش واحد در باینری لاگ&#xA;&#xA;# -------------------------------------------------------------&#xA;# 5. فعال‌سازی GTID و بهینه‌سازی رپلیکیشن چندنخی&#xA;# -------------------------------------------------------------&#xA;gtid_mode                          = ON&#xA;enforce_gtid_consistency          = ON&#xA;binlog_transaction_dependency_tracking = WRITESET # رپلیکیشن موازی فوق‌سریع در رپلیکاها&#xA;۶. دستورات عملیاتی و نگهداری (Operations &amp; Maintenance)بررسی وضعیت و حجم باینری لاگ‌های موجود-- مشاهده لیست تمام فایل‌های باینری لاگ و حجم آن‌ها&#xA;SHOW BINARY LOGS;&#xA;&#xA;-- مشاهده فایل لاگ جاری و آخرین موقعیت نوشته شده&#xA;SHOW MASTER STATUS;&#xA;مانیتورینگ وضعیت بافر حافظه و مصرف دیسک موقتSHOW GLOBAL STATUS LIKE &#39;Binlog_cache%&#39;;&#xA;اگر مقدار Binlog_cache_disk_use نسبت به Binlog_cache_use بالا باشد، باید مقدار binlog_cache_size را در فایل تنظیمات افزایش دهید.پاکسازی دستی و ایمن باینری لاگ‌هاهرگز فایل‌های لاگ را مستقیماً با دستور rm از لینوکس حذف نکنید! این کار شاخص (.index) را خراب کرده و سرور را از کار می‌اندازد. همیشه از دستورات داخلی MySQL استفاده کنید:-- حذف تمام لاگ‌های قدیمی‌تر از ۷ روز قبل&#xA;PURGE BINARY LOGS BEFORE NOW() - INTERVAL 7 DAY;&#xA;&#xA;-- حذف لاگ‌ها تا قبل از یک فایل مشخص&#xA;PURGE BINARY LOGS TO &#39;mysql-bin.000142&#39;;&#xA;۷. جدول خلاصه پارامترهاپارامتر مقدار پیشنهادی کاربرد اصلی binlog_format ROW تضمین یکپارچگی داده‌ها در رپلیکیشن و CDC binlog_row_image MINIMAL کاهش ۴۰ الی ۶۰ درصدی حجم لاگ‌های حجیم binlog_expire_logs_seconds 259200 (۳ روز) جلوگیری خودکار از پر شدن دیسک سرور max_binlog_size 256M یا 512M جلوگیری از ایجاد فایل‌های لاگ غول‌آسا sync_binlog 1 (یا 100) مدیریت توازن میان دوام داده (Durability) و سرعت نوشتن binlog_transaction_dependency_tracking WRITESET تسریع چند برابری پردازش در نودهای Replicaنتیجه‌گیریباینری لاگ ستون فقرات پایداری، مقیاس‌پذیری و پشتیبان‌گیری در دنیای MySQL است. در سرورهای تک‌نود (Standalone)، اگر نیاز به PITR یا CDC ندارید، غیرفعال‌سازی آن بار بزرگی از دوش ذخیره‌ساز برمی‌دارد؛ اما در صورت نیاز به فعال بودن آن، تعیین سقف نگهداری (binlog_expire_logs_seconds)، مدیریت اندازه فایل‌ها و بهینه‌سازی binlog_row_image از الزامات انکارناپذیر یک زیرساخت پایدار خواهد بود.</description><category>مهدی امیری متین</category><author>مهدی امیری متین</author><pubDate>Wed, 19 Aug 2026 11:30:01 +0330</pubDate></item><item><title>آشنایی با الگوریتم کواروم</title><link>https://virgool.ir/@m.amirimatin/آشنایی-با-الگوریتم-کواروم-j3bhzl146jlj</link><description>Quorum Algorithmالگوریتم کواروم (Quorum Algorithm) یکی از روش‌های پرکاربرد در سیستم‌های توزیع‌شده برای تصمیم‌گیری و هماهنگ‌سازی بین نودها (Nodes) است. هدف اصلی این الگوریتم اطمینان از این است که حتی در صورت خرابی یا از دسترس خارج شدن بخشی از سیستم، همچنان داده‌ها و تصمیمات یکپارچه (Consistent) باقی بمانند.ایده اصلی کوارومایده کواروم بر این اصل استوار است که برای انجام یک عملیات حساس (مثل نوشتن یا انتخاب لیدر)، لازم نیست همه نودها شرکت کنند، بلکه کافی است تعداد مشخصی از آن‌ها که به آن حد نصاب کواروم (Quorum Size) گفته می‌شود، موافقت کنند.به عنوان مثال، در یک کلاستر ۵ نودی:حد نصاب کواروم برای عملیات اکثریت معمولاً ۳ نود است.حتی اگر ۲ نود از کار بیفتند، سیستم همچنان می‌تواند با ۳ نود باقی‌مانده و به کار ادامه دهد.مفهوم رأی‌گیری و حداقل نودهای لازمدر بسیاری از الگوریتم‌های اجماع مانند Raft یا Paxos، رأی‌گیری برای انتخاب لیدر یا تأیید یک تراکنش بر اساس کواروم انجام می‌شود.اگر یک نود درخواست نوشتن داده‌ای را داشته باشد، باید موافقت بیش از نصف تعداد نودها را به دست آورد.این روش باعث می‌شود که هیچ دو گروه جدا از هم (در صورت تقسیم شبکه) نتوانند تصمیم متناقض بگیرند.رابطه کواروم با تحمل خطا (Fault Tolerance)کواروم ارتباط مستقیمی با تحمل خطا دارد. برای یک کلاستر با N نود:حداکثر تعداد نودهایی که می‌توانند از کار بیفتند بدون آنکه سیستم از دسترس خارج شود، برابر است با:(N-1)/2 = Fبه عنوان مثال:در کلاستر ۳ نودی ← حداکثر ۱ نود می‌تواند از کار بیفتد.در کلاستر ۵ نودی ← حداکثر ۲ نود می‌توانند از کار بیفتند.کاربردها در دیتابیس‌ها و سیستم‌های کلانEtcd و Consul برای ذخیره‌سازی تنظیمات و هماهنگی بین سرویس‌هاCassandra برای کواروم خواندن (Quorum Read) و نوشتن (Quorum Write)Galera Cluster برای هماهنگی عملیات نوشتن بین چند پایگاه داده MySQL همزمانسیستم‌های CDN (Content Delivery Network) برای هماهنگ‌سازی داده‌ها بین چند مرکز داده (Data Center) سناریوی کواروم در کلاستر سه‌نودییکی از رایج‌ترین و ساده‌ترین پیاده‌سازی‌های کواروم (Quorum) در سیستم‌های توزیع‌شده، استفاده از یک کلاستر سه‌نودی (3-Node Cluster) است. این معماری به دلیل سادگی و توانایی ایجاد اجماع (Consensus) با حداقل منابع، در بسیاری از پایگاه‌های داده و سیستم‌های هماهنگی سرویس‌ها کاربرد دارد.معمارییک کلاستر سه‌نودی شامل سه سرور (یا نود) است که هر کدام یک نسخه کامل از داده‌ها یا وضعیت سیستم را نگهداری می‌کنند.این سه نود به صورت همزمان با یکدیگر در ارتباط هستند.معمولاً یکی از آن‌ها به عنوان لیدر (Leader) انتخاب شده و دو نود دیگر فالوئر (Followers) هستند.فرآیند رأی‌گیریدر این معماری، برای انجام یک عملیات حساس مانند:انتخاب لیدرثبت یک تراکنش جدیدتغییر وضعیت پیکربندیباید حداقل ۲ نود (اکثریت) با آن موافق باشند.مثال:اگر نود A خراب شود، نودهای B و C می‌توانند به توافق برسند و عملیات ادامه یابد.اگر ارتباط بین دو نود قطع شود و هر کدام بخواهند مستقل تصمیم بگیرند، مکانیزم کواروم از وقوع Split Brain جلوگیری می‌کند.حد نصاب کواروم (Quorum Size)در یک کلاستر سه‌نودی:Quorum Size=1+[N/2]که برای N=3N = 3N=3 برابر با:Quorum Size=1+[3/2] = 2یعنی برای تصمیم‌گیری معتبر، باید موافقت حداقل ۲ نود کسب شود.مزایاسادگی پیاده‌سازی: فقط سه نود نیاز است.تحمل خطا: خرابی یک نود بدون توقف سیستم مدیریت می‌شود.جلوگیری از Split Brain: اکثریت مشخص مانع از تصمیم‌گیری متناقض می‌شود.هزینه پایین‌تر نسبت به کلاسترهای بزرگ‌تر.معایبدر صورت خرابی دو نود، سیستم از کار می‌افتد.افزایش بار پردازشی روی نودها نسبت به تعداد کم.مقیاس‌پذیری محدود در عملیات نوشتن (Write).نقاط شکست احتمالیخرابی همزمان دو نود ← از دست رفتن دسترس‌پذیری.قطع ارتباط شبکه بین نودها ← خطر آغاز فرآیند انتخاب لیدر توسط چند گروه جدا (در صورت عدم پیکربندی صحیح).لیدر نامناسب ← انتخاب لیدر با منابع ضعیف می‌تواند باعث افت کارایی شود.سناریوی کواروم در دو مرکز داده (2 DC – Two Data Centers)وقتی یک کلاستر بین دو مرکز داده (Data Center) توزیع می‌شود، موضوع کواروم (Quorum) پیچیده‌تر از حالت تک دیتاسنتر می‌شود. دلیل این پیچیدگی، احتمال قطع ارتباط بین مراکز داده و ایجاد شرایطی شبیه به Split Brain است.نحوه توزیع نودهادر یک سناریوی دو مرکز داده، معمولاً دو الگوی اصلی وجود دارد:الگوی متقارن – تعداد برابر نودها در هر مرکز دادهمثال: ۲ نود در DC1 و ۲ نود در DC2 (برای کلاستر ۴ نودی).مشکل: در صورت قطع ارتباط بین دو DC، هر طرف می‌تواند نصف نودها را داشته باشد و احتمال Split Brain بالا می‌رود.الگوی نامتقارن – تعداد نودها طوری توزیع می‌شود که یک طرف همیشه اکثریت داشته باشدمثال: ۲ نود در DC1 و ۱ نود در DC2 (برای کلاستر ۳ نودی).مزیت: در صورت قطع ارتباط، تنها طرفی که اکثریت دارد، تصمیم‌گیری را ادامه می‌دهد.مزایاافزایش تحمل خطا (Fault Tolerance): خرابی یک مرکز داده کامل لزوماً باعث توقف سرویس نمی‌شود (در الگوی نامتقارن).پایداری جغرافیایی: داده‌ها در دو مکان فیزیکی مجزا نگهداری می‌شوند و در برابر بلایای طبیعی مقاوم‌تر هستند.کاهش تاخیر برای کاربران منطقه‌ای: کاربران هر منطقه می‌توانند به نزدیک‌ترین DC متصل شوند.معایبافزایش تاخیر بین نودها (Inter-DC Latency) به دلیل فاصله فیزیکی بین مراکز داده.احتمال Split Brain در طراحی متقارن اگر مکانیزم جلوگیری از آن وجود نداشته باشد.پیچیدگی مدیریت و مانیتورینگ به دلیل وجود زیرساخت در دو مکان متفاوت.مشکلات Split Brain و روش‌های پیشگیریSplit Brain زمانی رخ می‌دهد که هر دو DC تصور کنند اکثریت دارند و هر کدام یک لیدر مستقل انتخاب کنند. این موضوع باعث ناسازگاری داده‌ها می‌شود.روش‌های پیشگیری:طراحی نامتقارن – قرار دادن تعداد نودها به شکلی که تنها یک طرف بتواند اکثریت داشته باشد.استفاده از شاهد (Witness Node) – اضافه کردن یک نود سبک‌وزن در مکان سومی که فقط برای رأی‌گیری استفاده می‌شود.Quorum-Based Failover – مکانیزمی که فقط به طرفی که اکثریت واقعی دارد اجازه ادامه کار می‌دهد.Inter-DC Heartbeat – مانیتورینگ فعال ارتباط بین DCها و جلوگیری از شروع انتخابات در شرایط نامطمئن.سناریوی کواروم در سه مرکز داده (3 DC – Three Data Centers)استقرار یک کلاستر بین سه مرکز داده (Data Center) یکی از مطمئن‌ترین روش‌ها برای جلوگیری از Split Brain و افزایش تحمل خطا است. با این حال، نحوه توزیع نودها بین DCها، تاثیر زیادی بر عملکرد و پایداری سیستم دارد.حالت اول: توزیع متقارن ۳-۳-۳معماریهر DC شامل ۳ نود است.مجموع نودها: ۹ نود.حد نصاب کواروم (Quorum Size) = ⌊9/2⌋ + 1 = ۵ نود.تحلیل انتخاب لیدر در سناریوهای قطعی۱. قطعی بین دو DCمثال: DC1 و DC2 ارتباطشان قطع می‌شود ولی هر دو به DC3 وصل هستند.چون DC3 با هر دو سمت در ارتباط است، تنها یکی از طرفین می‌تواند لیدر داشته باشد و DC3 نقش داور را بازی می‌کند. Split Brain رخ نمی‌دهد.2. قطعی کامل بین هر سه DC (Three-Way Partition)هر DC فقط ۳ نود دارد و به حد نصاب ۵ نمی‌رسد.نتیجه: کل سیستم متوقف می‌شود تا از ناسازگاری جلوگیری شود.3. قطعی یک DC از دو تای دیگرمثال: DC1 از DC2 و DC3 جدا می‌شود، ولی DC2 و DC3 همچنان به هم وصل هستند.DC2 + DC3 = 6Node ← اکثریت دارند و انتخاب لیدر ادامه دارد.DC1 با ۳ نود ← از کار می‌افتد.مزایاپایداری بالا در برابر خرابی یک DC کامل.جلوگیری از Split Brain در اکثر سناریوهای قطعی.معایبLatency (تاخیر بالا) به دلیل نیاز به ارتباط بین ۵ نود از مناطق مختلف برای هر تصمیم.هزینه زیاد به دلیل تعداد بالای نودها.توقف کامل سیستم در صورت قطع ارتباط هر سه DC از یکدیگر.حالت دوم: توزیع نامتقارن ۳-۳-۱معماریDC1 → ۳ NodeDC2 → ۳ NodeDC3 → ۱ Node (نود شاهد یا Witness Node)مجموع نودها: ۷ نود.حد نصاب کواروم = ⌊7/2⌋ + 1 = ۴ نود.تحلیل انتخاب لیدر در سناریوهای قطعی۱. قطعی بین دو DCمثال: DC1 و DC2 از هم جدا می‌شوند، اما هر دو به DC3 وصل هستند.DC3 به عنوان نود شاهد تعیین می‌کند کدام سمت اکثریت دارد.معمولاً یکی از DC1 یا DC2 لیدر می‌شود و دیگری متوقف می‌گردد.2. قطعی کامل بین هر سه DCDC1 = ۳ نود، DC2 = ۳ نود، DC3 = ۱ نود.هیچ‌کدام به حد نصاب ۴ نمی‌رسند ← سیستم متوقف می‌شود.3. قطعی یک DC از دو تای دیگرمثال: DC1 جدا می‌شود، DC2 + DC3 باقی می‌مانند.DC2 + DC3 = ۴ Node ← اکثریت دارند و ادامه کار می‌دهند.DC1 با ۳ نود ← متوقف می‌شود.مزایاجلوگیری مؤثر از Split Brain به کمک نود شاهد.هزینه کمتر نسبت به حالت ۳-۳-۳ (فقط ۷ نود).اکثریت راحت‌تر تشکیل می‌شود (۴ نود به جای ۵ نود).معایبDC3 نقطه حساس سیستم می‌شود (اگر DC3 از دست برود، برخی سناریوهای Failover دشوارتر می‌شوند).همچنان Latency بالا در عملیات بین‌DCی به دلیل فاصله جغرافیایی.وابستگی زیاد به پایداری ارتباط با نود شاهد.</description><category>مهدی امیری متین</category><author>مهدی امیری متین</author><pubDate>Mon, 20 Oct 2025 10:25:17 +0330</pubDate></item><item><title>کامیت‌های متعارف در Git</title><link>https://virgool.ir/@m.amirimatin/git-conventional-commits-cidtbjowwne3</link><description>git conventional commitsخلاصهمشخصه‌ی Conventional Commits یک قانون سبک و ساده بر روی پیام‌های commit است. این مشخصه مجموعه‌ای از قواعد آسان برای ایجاد تاریخچه‌ای شفاف از commitها فراهم می‌کند که نوشتن ابزارهای اتوماتیک را ساده‌تر می‌سازد. این قانون در کنار SemVer عمل می‌کند؛ به‌طوری که ویژگی‌ها، رفع باگ‌ها و تغییرات ناسازگار در پیام‌های commit توصیف می‌شوند.پیام commit باید به ساختار زیر نوشته شود:&lt;type&gt;[optional scope]: &lt;description&gt;&#xA;&#xA;[optional body]&#xA;&#xA;[optional footer(s)]پیش تعریفکامیت | commitکامیت در سیستم‌های مدیریت نسخه مانند Git،  به ثبت یک نقطه در تاریخچه‌ی تغییرات کد منبع گفته می‌شود. در یک commit، تغییراتی که روی فایل‌ها اعمال شده‌اند (مانند اضافه کردن، حذف یا تغییر کد) همراه با یک پیام توضیحی ذخیره می‌شوند. این ثبت تغییرات به توسعه‌دهندگان امکان می‌دهد تا به نسخه‌های قبلی کد بازگردند، تغییرات را دنبال کنند و تاریخچه‌ی پروژه را مرور نمایند.پایانه | footer در comimitدر مفهوم commitهای نرم‌افزاری، پایانه به بخشی از پیام commit گفته می‌شود که پس از بدنه‌ی اصلی commit (بعد از یک خط خالی) قرار می‌گیرد. در این قسمت، اطلاعات اضافی مانند شناسه‌های مربوط به باگ، تغییرات خاص (مانند تغییر ناسازگار)، مرجع commitهای مرتبط و سایر جزئیات به‌صورت ساختاریافته درج می‌شوند. این اطلاعات به ابزارهای اتوماتیک کمک می‌کنند تا بتوانند تغییرات را بهتر دسته‌بندی کنند یا تغییرات ناسازگار را شناسایی نمایند.یک commit شامل عناصر ساختاری زیر است تا نیت نویسنده برای مصرف‌کنندگان کتابخانه یا نرم‌افزار شما به‌خوبی منتقل شود:fix: کامیت هایی از نوع fix یک اشکال در کد را برطرف می‌کنند (این مورد با PATCH در نسخه‌بندی معنایی هم‌راستا است).2. feat: کامیت هایی از نوع feat ویژگی جدیدی به کد اضافه می‌کنند (این مورد با MINOR در نسخه‌بندی معنایی هم‌راستا است).3. BREAKING CHANGE: کامیت هایی که یا دارای پایانه‌ای با متن BREAKING CHANGE: هستند یا در نوع/محدوده از علامت ! استفاده می‌کنند، تغییرات ناسازگاری در API را معرفی می‌کنندکه باعث می‌شوند واسط برنامه (API) به‌طور ناسازگار تغییر کند و نیاز به تطبیق کد client ها داشته باشد. در این صورت، این تغییرات به عنوان افزایش نسخه MAJOR در نسخه‌بندی معنایی در نظر گرفته می‌شوند. تغییر ناسازگار می‌تواند در commitهای هر نوعی وجود داشته باشد.4. علاوه بر fix: و feat:، استفاده از انواع دیگر نیز مجاز است. به‌عنوان مثال، توصیه شده است که از نوع‌هایی مانند build:, chore:, ci:, docs:, style:, refactor:, perf:, test: و سایر موارد استفاده شود (مثال از @commitlint/config-conventional که مبتنی بر Angular convention است).علاوه بر BREAKING CHANGE: &lt;توضیح&gt;، می‌توان پایانه‌های دیگری نیز ارائه کرد که از قانونی مشابه فرمت git trailer پیروی می‌کنند.همچنین، انواع اضافی توسط این مشخصه الزامی نیستند و تأثیر ضمنی بر نسخه‌بندی معنایی ندارند (مگر آنکه شامل تغییر ناسازگار شوند). همچنین می‌توان به یک commit، محدوده‌ای به عنوان اطلاعات زمینه‌ای اضافه کرد؛ محدوده در داخل پرانتز نوشته می‌شود، به‌عنوان مثال:feat(parser): add ability to parse arraysمثال‌هاپیام commit با توضیح و پایانه‌ی تغییر ناسازگارfeat: allow provided config object to extend other configsBREAKING CHANGE: `extends` key in config file is now used for extending other config filesپیام commit با استفاده از علامت ! برای جلب توجه به تغییر ناسازگارfeat!: send an email to the customer when a product is shippedپیام commit با محدوده و استفاده از ! برای جلب توجه به تغییر ناسازگارfeat(api)!: send an email to the customer when a product is shippedپیام commit با استفاده همزمان از ! و پایانه‌ی BREAKING CHANGEchore!: drop support for Node 6BREAKING CHANGE: use JavaScript features not available in Node 6.پیام commit بدون بدنهdocs: correct spelling of CHANGELOGپیام commit با محدودهfeat(lang): add Polish languageپیام commit با بدنه چندبند و چندین پایانهfix: prevent racing of requestsIntroduce a request id and a reference to latest request. Dismissincoming responses other than from latest request.Remove timeouts which were used to mitigate the racing issue but are obsolete now.Reviewed-by: ZRefs: #123توضیحات اجمالیکلمات کلیدی MUST، MUST NOT، REQUIRED، SHALL، SHALL NOT، SHOULD، SHOULD NOT، RECOMMENDED، MAY و OPTIONAL در این سند به معنایی تعبیر می‌شوند که در RFC 2119 توضیح داده شده است.کامیت ها باید با یک نوع پیشوند شوند که از یک اسم (مثلاً feat، fix و ...) تشکیل شده و به دنبال آن می‌تواند محدوده اختیاری، علامت ! اختیاری و سپس دو نقطه به همراه یک فاصله (الزامی) بیاید.نوع feat باید زمانی استفاده شود که commit یک ویژگی جدید به برنامه یا کتابخانه اضافه می‌کند.نوع fix باید زمانی استفاده شود که commit نمایانگر رفع یک اشکال در برنامه است.پس از نوع، ممکن است محدوده‌ای ارائه شود. محدوده باید از یک اسم تشکیل شده و بخش مشخصی از کد را توضیح دهد و در داخل پرانتز قرار گیرد، به‌عنوان مثال: fix(parser):باید یک توضیح بلافاصله پس از دو نقطه و فاصله قرار گیرد. توضیح یک خلاصه کوتاه از تغییرات کد است، مثلاً: fix: array parsing issue when multiple spaces were contained in string.ممکن است یک بدنه‌ی طولانی‌تر نیز ارائه شود که اطلاعات زمینه‌ای بیشتری در مورد تغییرات کد فراهم کند. بدنه باید یک خط خالی بعد از توضیح کوتاه آغاز شود.بدنه‌ی commit می‌تواند به‌صورت آزاد و شامل هر تعداد پاراگراف جداگشته با خط جدید باشد.ممکن است یک یا چند پایانه (footer) نیز ارائه شود؛ این پایانه‌ها باید یک خط خالی پس از بدنه قرار گیرند. هر پایانه باید از یک توکن (کلمه) شروع شده و پس از آن با استفاده از :&lt;space&gt; یا &lt;space&gt;# یک رشته متنی ارائه شود (این الگو از فرمت git trailer الهام گرفته شده است).توکن‌های پایانه باید به جای فاصله از علامت - استفاده کنند، مثلاً Acked-by (این کار به تشخیص بخش پایانه از بدنه چندبندی کمک می‌کند). استثنای این قانون، توکن BREAKING CHANGE است که مجاز به استفاده به‌صورت مستقیم می‌باشد.مقدار یک پایانه می‌تواند شامل فضاها و خط‌های جدید باشد و تجزیه (parse) باید زمانی خاتمه یابد که یک جفت توکن/جداکننده‌ی معتبر بعدی مشاهده شود.تغییرات ناسازگار (Breaking changes) باید یا در پیشوند نوع/محدوده commit با علامت ! یا به‌عنوان یک ورودی در پایانه مشخص شوند.اگر به‌عنوان یک پایانه درج شود، تغییر ناسازگار باید شامل متن BREAKING CHANGE به صورت حروف بزرگ، به دنبال آن دو نقطه، یک فاصله و سپس توضیح مربوط باشد، مثلاً: BREAKING CHANGE: environment variables now take precedence over config files.اگر در پیشوند نوع/محدوده درج شود، تغییر ناسازگار باید با یک ! درست قبل از : مشخص گردد. در این صورت، درج BREAKING CHANGE: در بخش پایانه می‌تواند نادیده گرفته شود و توضیح موجود در پیام commit برای توصیف تغییر ناسازگار استفاده شود.می‌توان از انواعی به جز feat و fix در پیام‌های commit استفاده کرد، مثلاً: docs: update ref docs.واحدهای اطلاعاتی که مشخصه‌ی Conventional Commits را تشکیل می‌دهند نباید از نظر حروف (بزرگ/کوچک) حساس باشند، به استثنای BREAKING CHANGE که باید به صورت حروف بزرگ نوشته شود.تغییرات ناسازگار باید معادل BREAKING CHANGE تلقی شود، زمانی که به‌عنوان توکن در یک پایانه استفاده می‌شود.چرا از Conventional Commits استفاده کنیم؟ایجاد خودکار CHANGELOGها: با استفاده از این مشخصه می‌توان به‌طور اتوماتیک تغییرات را ثبت و در changelog درج کرد.تعیین خودکار افزایش نسخه معنایی: بر اساس نوع commitهای انجام‌شده (مثلاً رفع اشکال یا ویژگی جدید) می‌توان افزایش نسخه را به‌صورت خودکار مشخص نمود.ارتباط مؤثر: انتقال ماهیت تغییرات به هم‌تیمی‌ها، کاربران نهایی و سایر ذینفعان.فعال‌سازی فرایندهای build و publish: امکان راه‌اندازی خودکار فرایندهای ساخت و انتشار.سازماندهی بهتر commitها: با فراهم آوردن تاریخچه‌ای ساختارمند، مشارکت در پروژه‌ها برای افراد آسان‌تر می‌شود.سوالات متداولدر فاز اولیه‌ی توسعه، چگونه باید با پیام‌های commit برخورد کنم؟پیشنهاد می‌کنیم گام‌های خود را به‌گونه‌ای بردارید که انگار محصول شما قبلاً منتشر شده است. معمولاً شخصی — حتی اگر از توسعه‌دهندگان همکار شما باشد — از نرم‌افزار شما استفاده می‌کند و می‌خواهد بداند چه مشکلاتی رفع شده و چه تغییراتی ایجاد شده‌اند.آیا نوع‌های موجود در عنوان commit به حروف بزرگ یا کوچک نوشته می‌شوند؟هر نوع از حروف (بزرگ یا کوچک) قابل استفاده است؛ اما بهتر است در سراسر پروژه یکپارچه و یکسان باشد.اگر commit به بیش از یک نوع commit مطابقت داشته باشد، چه کاری انجام دهم؟تا حد امکان commitها را به چند بخش تقسیم کنید. یکی از مزایای استفاده از Conventional Commits این است که ما را به ساخت commitها و pull requestهای سازمان‌یافته‌تر ترغیب می‌کند.آیا این موضوع توسعه سریع و تکرار سریع را کاهش نمی‌دهد؟این روش از حرکت سریع به‌صورت بی‌نظم جلوگیری می‌کند. بلکه به شما کمک می‌کند تا در بلندمدت در پروژه‌های مختلف با مشارکت‌کنندگان متنوع به سرعت پیش بروید.آیا استفاده از Conventional Commits ممکن است باعث شود توسعه‌دهندگان نوع commitهایی که انجام می‌دهند را محدود کنند چون به نوع‌های از پیش تعریف‌شده فکر می‌کنند؟Conventional Commits ما را تشویق می‌کند که commitهای بیشتری از نوع‌هایی مانند رفع اشکال ایجاد کنیم. علاوه بر آن، انعطاف‌پذیری این مشخصه به تیم شما اجازه می‌دهد نوع‌های خاص خود را تعریف کرده و در طول زمان تغییر دهند.این موضوع چه ارتباطی با SemVer دارد؟commitهای از نوع fix باید به عنوان نسخه‌های PATCH در نظر گرفته شوند؛ commitهای از نوع feat باید به عنوان نسخه‌های MINOR در نظر گرفته شوند؛ و commitهایی که شامل BREAKING CHANGE هستند، بدون در نظر گرفتن نوع، باید به عنوان نسخه‌های MAJOR در نظر گرفته شوند.چگونه باید نسخه‌بندی افزونه‌های خود به مشخصه‌ی Conventional Commits (مانند @jameswomack/conventional-commit-spec) را انجام دهم؟پیشنهاد می‌کنیم برای انتشار افزونه‌های خود از نسخه‌بندی SemVer استفاده کنید (و از ایجاد این افزونه‌ها استقبال می‌کنیم!).اگر به‌طور تصادفی از نوع اشتباه commit استفاده کردم، چه کار کنم؟اگر از نوعی استفاده کرده‌اید که در مشخصه موجود است اما اشتباه به‌کار رفته، مثلاً fix به جای feat:پیش از ادغام یا انتشار، توصیه می‌کنیم با استفاده از دستور git rebase -i تاریخچه‌ی commitها را اصلاح کنید. پس از انتشار، فرآیند پاکسازی به ابزارها و روش‌های مورد استفاده شما بستگی خواهد داشت.اگر از نوعی استفاده کرده‌اید که در مشخصه وجود ندارد، مثلاً feet به جای feat:در بدترین حالت، انتشار commitی که با مشخصه مطابقت ندارد پایان دنیا نیست؛ تنها به این معناست که آن commit توسط ابزارهایی که مبتنی بر این مشخصه هستند نادیده گرفته می‌شود.آیا تمامی هم‌نوشتاران من باید از مشخصه‌ی Conventional Commits استفاده کنند؟خیر! اگر از روندی مبتنی بر squash در Git استفاده کنید، مدیران اصلی می‌توانند پیام‌های commit را در حین ادغام پاکسازی کنند بدون آنکه برای commit‌کنندگان عادی بار اضافی ایجاد شود. یکی از روندهای معمول این است که سیستم Git شما به‌طور خودکار commitهای یک pull request را squash کند و فرم مناسبی برای وارد کردن پیام commit صحیح توسط مدیر اصلی فراهم کند.آیا Conventional Commits  کامیت های revert را مدیریت می‌کند؟بله ، برگرداندن تغییرات کد می‌تواند پیچیده باشد: آیا شما چندین commit را برمی‌گردانید؟ اگر یک ویژگی را برگردانید، آیا نسخه‌ی بعدی به‌عنوان یک patch منتشر شود؟ مشخصه‌ی Conventional Commits تلاشی صریح برای تعریف رفتار revert نمی‌کند؛ بلکه این موضوع را به عهده‌ی توسعه‌دهندگان ابزار می‌گذارد تا با استفاده از انعطاف‌پذیری نوع‌ها و پایانه‌ها، منطق مدیریت revert را توسعه دهند.یکی از توصیه‌ها این است که از نوع revert استفاده کنید و در پایانه، SHA commitهایی که در حال برگرداندن هستند را ذکر نمایید:revert: let us never again speak of the noodle incidentRefs: 676104e, a215868منبع: Conventional Commits 1.0.0</description><category>مهدی امیری متین</category><author>مهدی امیری متین</author><pubDate>Sat, 08 Mar 2025 12:36:40 +0330</pubDate></item><item><title>Firewall Rules در میکروتیک</title><link>https://virgool.ir/@m.amirimatin/firewall-rules-در-میکروتیک-wbggvkqh6x6t</link><description>مقدمهفایروال (Firewall) یکی از اجزای حیاتی در شبکه‌های کامپیوتری است که وظیفه آن کنترل و مدیریت ترافیک ورودی و خروجی در یک شبکه است. در تجهیزات میکروتیک، فایروال می‌تواند به عنوان ابزاری برای امنیت شبکه، محدود کردن دسترسی‌ها و مدیریت ترافیک استفاده شود. در این مقاله به بررسی قوانین فایروال در میکروتیک خواهیم پرداخت و نحوه تنظیم آن‌ها را به صورت دقیق توضیح خواهیم داد.. مفهوم قوانین فایروالقوانین فایروال در میکروتیک به مجموعه‌ای از دستورالعمل‌ها اشاره دارد که تعیین می‌کنند کدام ترافیک مجاز و کدام ترافیک مسدود شود. این قوانین بر اساس پارامترهای مختلفی مانند آدرس IP، پروتکل، پورت و نوع ترافیک تنظیم می‌شوند.۲. ساختار قوانین فایروالهر قانون فایروال در میکروتیک شامل چندین ویژگی اصلی است:۲.۱. ChainChain مشخص می‌کند که قانون در کدام قسمت از فایروال اعمال می‌شود. معمولاً سه نوع Chain وجود دارد:input: ترافیکی که به خود روتر می‌رسد.output: ترافیکی که از خود روتر خارج می‌شود.forward: ترافیکی که از یک اینترفیس به اینترفیس دیگر عبور می‌کند.۲.۲. ActionAction مشخص می‌کند که برای ترافیک مطابق با این قانون چه عملی انجام شود. گزینه‌های رایج شامل:accept: اجازه دادن به ترافیک.drop: مسدود کردن ترافیک بدون ارسال پاسخ.reject: مسدود کردن ترافیک و ارسال پاسخ.۲.۳. ProtocolProtocol نوع پروتکلی که قانون برای آن اعمال می‌شود را مشخص می‌کند، مانند TCP، UDP و ICMP.۲.۴. Source و Destination AddressSource Address و Destination Address آدرس‌های IP مبدا و مقصد را مشخص می‌کنند که می‌توانند به صورت دقیق یا به عنوان یک محدوده تنظیم شوند.۲.۵. PortPort شماره پورت‌های خاصی را مشخص می‌کند که قانون برای آن‌ها اعمال می‌شود. برای مثال، می‌توان قوانین را برای ترافیک HTTP (پورت 80) یا HTTPS (پورت 443) تنظیم کرد.۳. نحوه تنظیم قوانین فایروال در میکروتیکبرای تنظیم قوانین فایروال در میکروتیک، مراحل زیر را دنبال کنید:۳.۱. ورود به محیط کاربری میکروتیکاز طریق Winbox یا WebFig به میکروتیک وارد شوید.به بخش IP رفته و روی Firewall کلیک کنید.۳.۲. اضافه کردن یک قانون جدیددر تب Filter Rules روی دکمه Add کلیک کنید.در پنجره باز شده، ویژگی‌های مختلف قانون را تنظیم کنید:Chain: نوع Chain را انتخاب کنید (input، output یا forward).Protocol: پروتکل مورد نظر را انتخاب کنید.Src. Address و Dst. Address: آدرس‌های IP مبدا و مقصد را مشخص کنید.Action: عمل مورد نظر (accept، drop یا reject) را انتخاب کنید.پس از تنظیم ویژگی‌ها، روی OK کلیک کنید.۳.۳. بررسی و مدیریت قوانینپس از اضافه کردن قوانین، می‌توانید آن‌ها را در لیست مشاهده کنید و بر اساس نیاز، قوانین را ویرایش یا حذف کنید.نکات مهم در استفاده از فایروالترتیب قوانین: ترتیب قوانین در فایروال میکروتیک مهم است؛ زیرا قوانین به ترتیب از بالا به پایین بررسی می‌شوند و اولین قانونی که با ترافیک مطابقت دارد، اعمال می‌شود.تست و پایش: پس از تنظیم قوانین، باید عملکرد آن‌ها را تست و پایش کنید تا از عدم وجود مشکلات امنیتی اطمینان حاصل کنید.پشتیبانی از لاگ: فعال کردن لاگ برای قوانین خاص می‌تواند به شما کمک کند تا فعالیت‌های مشکوک را شناسایی کنید.سخن پایانیفایروال در میکروتیک ابزار قدرتمندی برای مدیریت و کنترل ترافیک شبکه است. با تنظیم دقیق قوانین فایروال، می‌توان امنیت شبکه را بهبود بخشید و از دسترسی‌های غیرمجاز جلوگیری کرد. آشنایی با ساختار و ویژگی‌های قوانین فایروال می‌تواند به مدیران شبکه کمک کند تا محیطی امن و پایدار ایجاد کنند.</description><category>مهدی امیری متین</category><author>مهدی امیری متین</author><pubDate>Mon, 14 Oct 2024 13:45:58 +0330</pubDate></item><item><title>NAT در میکروتیک</title><link>https://virgool.ir/@m.amirimatin/nat-در-میکروتیک-plrse76s8m2c</link><description>مقدمهمفهوم NAT (Network Address Translation) ، یکی از قابلیت‌های مهم در تجهیزات شبکه نظیر روترها است که به وسیله آن می‌توان ترافیک شبکه را به صورت هوشمندانه مدیریت کرد. این قابلیت به ویژه برای ارتباط شبکه‌های داخلی (LAN) با شبکه‌های خارجی (WAN) مانند اینترنت بسیار کاربردی است. در روترهای میکروتیک، NAT به شکل گسترده‌ای استفاده می‌شود تا آدرس‌های IP خصوصی شبکه‌های داخلی را به یک یا چند آدرس IP عمومی ترجمه کرده و بالعکس.انواع NATدر شبکه NAT انواع مختلفی دارد که ما به چند نوع از آن اشاره میکنیم.1. Source NAT  یا همان ( SRC-NAT)در این نوع NAT، آدرس مبدا ترافیک تغییر می‌کند. این کاربرد معمولاً برای ترجمه آدرس‌های داخلی به آدرس عمومی در زمان دسترسی به اینترنت استفاده می‌شود. به عبارت دیگر کاربرد اصلی آن برای ماسک کردن آدرس‌های داخلی شبکه است تا دستگاه‌ها بتوانند با اینترنت یا دیگر بخش‌های شبکه ارتباط برقرار کنند. که معمولا به دو نوع زیر تقسیم می شود:MasqueradeMasquerade یکی از انواع Source NAT است که برای پنهان‌سازی آدرس‌های مبدا شبکه داخلی استفاده می‌شود. معمولاً زمانی که شبکه داخلی از طریق یک IP دینامیک (Dynamic IP) به اینترنت متصل است، استفاده می‌شود. این عمل به طور خودکار آدرس IP خروجی روتر را به عنوان آدرس مبدا تنظیم می‌کند.به عنوان مثال:/ip firewall nat add chain=srcnat action=masquerade out-interface=pppoe-out1Static Source NAT (SNAT)در SNAT ایستا، آدرس مبدا به یک آدرس IP خاص تغییر پیدا می‌کند. این حالت برای مواردی مناسب است که IP ثابت به دستگاه‌ها اختصاص داده می‌شود.به عنوان مثال:/ip firewall nat add chain=srcnat action=src-nat to-addresses=192.168.100.1 src-address=192.168.0.102. Destination NAT یا همان DST-NATDNAT برای تغییر آدرس مقصد در بسته‌های داده استفاده می‌شود. این نوع NAT معمولاً برای دسترسی به سرویس‌های داخلی از طریق یک IP عمومی (Public IP) یا دسترسی به سرورهای داخلی از اینترنت استفاده می‌شود.Port Forwarding (DNAT)Port Forwarding یکی از کاربردهای DNAT است که در آن درخواست‌هایی که به یک آدرس IP عمومی ارسال می‌شوند به یک سرور خاص در شبکه داخلی هدایت می‌شوند. به این روش، کاربران خارجی می‌توانند به سرویس‌های داخلی دسترسی پیدا کنند.در این مثال، ترافیک ورودی از پورت 8080 روی IP عمومی به پورت 80 سرور داخلی با آدرس 192.168.0.100 هدایت می‌شود./ip firewall nat add chain=dstnat action=dst-nat to-addresses=192.168.0.100 to-ports=80 protocol=tcp dst-port=8080Static Destination NAT (DNAT)در این نوع DNAT، آدرس مقصد به یک آدرس IP ثابت در شبکه داخلی تغییر پیدا می‌کند.در این مثال، هرگونه ترافیک به آدرس عمومی 203.0.113.5 به سرور داخلی با آدرس 192.168.0.50 ارسال می‌شود./ip firewall nat add chain=dstnat action=dst-nat to-addresses=192.168.0.50 dst-address=203.0.113.53. Bidirectional NAT (NAT دوطرفه)در NAT دوطرفه، آدرس‌های مبدا و مقصد به صورت همزمان ترجمه می‌شوند. این تکنیک به منظور ارتباط متقابل میان دو شبکه با استفاده از ترجمه دو طرفه IP مورد استفاده قرار می‌گیرد.در این مثال، ترافیک از آدرس 192.168.1.1 به آدرس 10.0.0.1 ترجمه می‌شود و بالعکس./ip firewall nat add chain=srcnat action=src-nat to-addresses=10.0.0.1 src-address=192.168.1.1/ip firewall nat add chain=dstnat action=dst-nat to-addresses=192.168.1.1 dst-address=10.0.0.14. NAT و VPNNAT می‌تواند با VPN‌ها ترکیب شود تا ارتباطات امن بین شبکه‌ها فراهم شود. معمولاً در شبکه‌هایی که از VPN برای دسترسی به شبکه‌های دیگر استفاده می‌کنند، NAT به کار می‌رود تا آدرس‌های خصوصی به آدرس‌های معتبر تبدیل شوند.پیکربندی NAT در میکروتیکبرای تنظیم NAT در روتر میکروتیک، ابتدا باید به Winbox یا CLI دسترسی پیدا کنید. مراحل زیر برای پیکربندی NAT در میکروتیک از طریق Winbox بیان می‌شوند.پیکربندی Source NATهمان طور که اشاره شدSource NAT برای دسترسی شبکه داخلی به اینترنت از طریق یک IP عمومی استفاده می‌شود. برای تنظیم آن مراحل زیر را انجام دهید:در Winbox وارد شوید و از منوی اصلی، به بخش IP و سپس Firewall بروید.در تب NAT، روی دکمه + کلیک کنید تا یک رول جدید اضافه کنید.در بخش General، Chain را روی srcnat تنظیم کنید.در بخش Out Interface، اینترفیس WAN (اینترفیسی که اینترنت به آن متصل است) را انتخاب کنید.به تب Action بروید و Action را روی masquerade تنظیم کنید.بر روی Apply و سپس OK کلیک کنید.این پیکربندی باعث می‌شود که تمام ترافیک خروجی از شبکه داخلی با IP WAN ترجمه شود.پیکربندی Destination NATبرای انجام Destination NAT یا به اصطلاح Port Forwarding، که درخواست‌های ورودی به IP عمومی را به یک IP داخلی خاص هدایت کند (مثلاً سرور داخلی):وارد Winbox شوید و از منوی اصلی به IP &gt; Firewall بروید.در تب NAT روی + کلیک کنید.در بخش General، Chain را روی dstnat تنظیم کنید.در بخش Dst. Address، آدرس IP عمومی روتر را وارد کنید.در بخش Protocol، پروتکل مورد نظر (TCP/UDP) را انتخاب کنید.در بخش Dst. Port، شماره پورت مورد نظر را وارد کنید.به تب Action بروید و Action را روی dst-nat تنظیم کنید.در بخش To Addresses، IP داخلی دستگاه مقصد را وارد کنید.در بخش To Ports، پورت داخلی را وارد کنید (در صورت نیاز).روی Apply و سپس OK کلیک کنید.این پیکربندی باعث می‌شود که تمام درخواست‌های ورودی به IP عمومی روتر روی پورت مشخص شده به IP داخلی سرور مورد نظر هدایت شود.بررسی رول‌های NATبرای مشاهده و مدیریت رول‌های NAT که در روتر میکروتیک پیکربندی شده‌اند، می‌توانید به مسیر IP &gt; Firewall &gt; NAT بروید. در این بخش تمامی رول‌های فعال NAT را مشاهده می‌کنید و می‌توانید هر کدام را ویرایش یا حذف کنید.نکات مهماستفاده نادرست از رول‌های NAT می‌تواند باعث مشکلاتی در دسترسی به شبکه‌ها شود. لذا مطمئن شوید که پیکربندی‌ها با دقت انجام می‌شود.اگر از Masquerade استفاده می‌کنید و دارای چندین اینترفیس WAN هستید، باید از سیاست‌های مناسب برای تعیین اینترفیس خروجی استفاده کنید.برای ارتباط بهتر و بدون مشکل با شبکه‌های خارجی، تنظیمات DNS و Route به درستی باید انجام شوند.سخن پایانیقابلیت NAT در میکروتیک به شما این امکان را می‌دهد که با پنهان‌سازی آدرس‌های IP داخلی و هدایت ترافیک به شبکه‌های خارجی، امنیت و کارایی شبکه خود را بهبود دهید. پیکربندی صحیح و استفاده از انواع NAT متناسب با نیاز شبکه، دسترسی به سرویس‌های خارجی را آسان و مدیریت شبکه را ساده‌تر می‌کند.</description><category>مهدی امیری متین</category><author>مهدی امیری متین</author><pubDate>Mon, 14 Oct 2024 13:45:52 +0330</pubDate></item><item><title>Routing در میکروتیک</title><link>https://virgool.ir/@m.amirimatin/routing-در-میکروتیک-lbxq1eakzhjj</link><description>مقدمهروتینگ یا مسیریابی یکی از اصولی‌ترین مفاهیم در شبکه است که به دستگاه‌ها کمک می‌کند تا داده‌ها را از مبدا به مقصد صحیح هدایت کنند. روتر میکروتیک به دلیل امکانات و قابلیت‌های فراوانی که دارد، در بسیاری از شبکه‌ها مورد استفاده قرار می‌گیرد. در این مقاله به صورت جامع به مفهوم روتینگ در میکروتیک، انواع جداول روتینگ، و روش استفاده از Routing Mark برای تمایز NAT ها پرداخته می‌شود.بخش اول: مفاهیم اولیه روتینگ در میکروتیکروترهای میکروتیک مانند سایر روترها وظیفه اصلی‌شان ارسال داده‌ها به مقصد درست از طریق انتخاب مسیر مناسب است. هر روتر دارای یک جدول روتینگ است که شامل اطلاعاتی درباره مسیرهای شبکه و مقصدهای مختلف می‌باشد.جدول روتینگ (Routing Table): جدول روتینگ شامل مجموعه‌ای از مسیرها است که روتر از آن‌ها برای ارسال بسته‌های داده استفاده می‌کند. هر ورودی در جدول روتینگ شامل اطلاعات زیر است:مقصد (Destination): آدرس IP مقصد داده‌ها.Gateway: درگاه (گیت‌وی) بعدی که بسته‌ها باید به آن ارسال شوند.Interface: رابط فیزیکی یا مجازی که بسته‌ها از طریق آن ارسال می‌شوند.Distance: فاصله یا اولویت مسیر (هر چه مقدار کمتر باشد، اولویت بالاتر است).در میکروتیک، جدول روتینگ به صورت پیش‌فرض شامل مسیرهای مستقیم (متصل به روتر) و مسیرهای یادگیری‌شده از پروتکل‌های مسیریابی (مانند OSPF یا BGP) است. اما در برخی از موارد ما نیاز به تعریف جداول روتینگ جدید و خاص داریم که در ادامه توضیح خواهیم داد.بخش دوم: ایجاد و مدیریت جداول روتینگ در میکروتیکیکی از ویژگی‌های قدرتمند میکروتیک این است که شما می‌توانید چندین جدول روتینگ مختلف ایجاد کنید و بسته‌های داده را به صورت هدفمند بر اساس این جداول ارسال کنید. به عنوان مثال، در شرایطی که چندین گیت‌وی اینترنت دارید و می‌خواهید بسته‌های مختلف از گیت‌وی‌های مختلف عبور کنند، می‌توانید از چندین جدول روتینگ استفاده کنید.نحوه ایجاد جدول روتینگ:برای ایجاد یک جدول روتینگ جدید، از دستورات زیر استفاده می‌شود:/ip route rule add table=myTableدر این دستور، یک جدول با نام myTable ایجاد شده است. اکنون می‌توانیم مسیرهای دلخواه خود را به این جدول اضافه کنیم.اضافه کردن مسیر به جدول:برای اضافه کردن یک مسیر به جدول جدید، باید مسیر دلخواه را به این جدول اختصاص دهیم:/ip route add dst-address=0.0.0.0/0 gateway=192.168.1.1 routing-mark=myTableدر این مثال، بسته‌هایی که با routing-mark مشخص شده‌اند، از گیت‌وی 192.168.1.1 عبور خواهند کرد.بخش سوم: استفاده از Routing Mark برای تمایز NAT‌هایکی از قابلیت‌های پیشرفته میکروتیک، امکان استفاده از Routing Mark برای متمایز کردن ترافیک و مسیرهای مختلف است. در بسیاری از مواقع ممکن است شما چندین NAT داشته باشید که از مسیرهای مختلف اینترنت استفاده می‌کنند. با استفاده از Routing Mark می‌توانید بسته‌های داده را بر اساس معیارهای مختلف (مانند IP منبع، پورت، و ...) متمایز کرده و آن‌ها را از طریق NAT مورد نظر عبور دهید.تعریف Routing Mark:برای تعریف Routing Mark می‌توانید از Mangle Rules استفاده کنید. Mangle به شما اجازه می‌دهد ترافیک را دستکاری کرده و ویژگی‌های خاصی به آن اضافه کنید.به عنوان مثال، برای علامت‌گذاری ترافیک از یک IP خاص به این صورت عمل می‌کنیم:/ip firewall mangle add chain=prerouting src-address=192.168.1.100 action=mark-routing new-routing-mark=myRouteMarkدر این دستور، ترافیک از IP منبع 192.168.1.100 به Routing Mark با نام myRouteMark علامت‌گذاری می‌شود.استفاده از Routing Mark برای NAT:پس از ایجاد Routing Mark، می‌توانید آن را به NAT خود اعمال کنید تا مسیر ترافیک بر اساس علامت‌گذاری انجام شود./ip firewall nat add chain=srcnat src-address=192.168.1.100 action=masquerade routing-mark=myRouteMarkدر این دستور، ترافیک از آدرس IP 192.168.1.100 که به Routing Mark myRouteMark علامت‌گذاری شده است، از طریق NAT masquerade عبور خواهد کرد.سخن پایانیدر این مقاله به بررسی مفاهیم روتینگ در میکروتیک، نحوه ایجاد و استفاده از جداول روتینگ، و نحوه استفاده از Routing Mark برای تمایز NAT‌ها پرداخته شد. با استفاده از این ابزارها و قابلیت‌ها، شما می‌توانید ترافیک شبکه خود را به صورت بهینه و مطابق نیاز مدیریت کنید و ترافیک مختلف را از مسیرهای خاص و جداگانه عبور دهید.</description><category>مهدی امیری متین</category><author>مهدی امیری متین</author><pubDate>Mon, 14 Oct 2024 13:35:12 +0330</pubDate></item><item><title>استانداردی مناسب برای کنترل پروژه با نام git flow</title><link>https://virgool.ir/@m.amirimatin/gitflow-nnqg4vqqp0i7</link><description>چندی قبل که درگیر ci/cd برای یک پروژه عریض و طویل شده بودم با مشکلات و چالش هایی روبرو شدم که حل آنها بدون استاندارد مناسب و راه حل خوب مشکل بود در آن زمان نا خود آگاه خروجی کار تقریبا شبیه به استاندارد git flow شده بود بدون اینکه بدونم چنین استانداردی وجود دارد اما باز هم کامل نبود و با چالش های زیادی روبرو بود به عنوان مثال بزرگترین مشکل این بود که یک تیم توسعه مستقل از تیم رفع باگ کار می کرد و تیم رفع باگ مستقیما روی master branch کار میکرد و باگ های اصلی سیستم رو رفع می کرد به طوری که مدیریت این مسئله که باگ های رفع شده باید با develop و feature ها مرج شود دشوار بود و فرایند ci/cd را با چالش اساسی روبرو کرد اما امروز با این استاندارد مواجه شدم و دیدم که چقدر کار رو راحت کرده به همین دلیل مطلب زیر در این جا به اشتراک میزارم و بعدا در مطلبی دیگر ترکیب آن با ci/cd را نیز منتشر خواهم کرد.موضوعی که در این مقاله میخواهم در رابطه با آن صحبت کنم، تعریف یک مدل یا Road map برای مدیریت یک پروژه روی ورژن کنترلی مثل گیت است.اگر قبلا تجربه کار کردن به صورت تیم را داشته باشید حتما به مشکلاتی همچون Merge Conflict و تداخل و همزمانی توسعه ویژگی‌ها و… برخورد کردید که گاهی وقتها وقت زیادی رو از ما میگیره تا برنچ‌های مختلف را با هم ادغام و در نهایت Deploy کنیم.به عبارتی Git Flow  یک ‌Branch Model است یا بهتره بگم یه مفهوم برای مدیریت برنچ‌ها و تیم توسعه است که بدون مشکل بتوانیم پروژه‌هایمان را توسعه دهیم و به صورت همزمان بتوانیم Feature هایی که میخواهیم را به بخش‌های مختلف پروژه اضافه کنیم بدون اینکه استرسی بابت مرج و لانچ بخش‌های مختلف داشته باشیم.Gitflow is ideally suited for projects that have a scheduled release cycle. This workflow doesn’t add any new concepts or commands beyond what’s required for the FeatureBranch Workflow. Instead, it assigns very specific roles to different branches and defines how and when they should interact. In addition to feature branches, it uses individual branches for preparing, maintaining, and recording releases. Of course, you also get to leverage all the benefits of the Feature Branch Workflow: pull requests, isolated experiments, and more efficient collaboration.در واقع Git Flow یک ایده ای برای مدیریت محیط توسعه است و مشخص می‌کند که چه Branch هایی ساخته شوند و چگونه این Branchها با هم Merge شوند.در ابتدا گیت را نصب کنید و سپس با اجرای دستور git flow init  میتوانید از آن در پروژه خود استفاده کنید. Git-flow ریپازیتوری شما را تغییر نمی‌دهد و همراه با Git استفاده می‌شود.git-flow is a wrapper around existing git commands, so the init command doesn’t change anything in your repository other than creating branches for you. If you don’t want to use git-flow anymore, there’s nothing to change or remove, you just stop using the git-flow commands.Git Flow چگونه کار می‌کند؟شمای ساده از git flowبه جای اینکه یک برنچ master داشته باشیم و یا برنچ‌های مختلف با نام‌های مختلف داشته باشیم در این شیوه ۲ برنچ به نام‌های master , develop داریم که برنچ masterهمان نسخه لانچ شده پروژه است و برنچ develop نسخه ای از پروژه است که همه feature ها و تغییرات نهایی روی آن قرار می‌گیرند و پس از تست با برنچ master  مرج میشوند.  ( من شخصا در همه پروژه‌هایی که داشتم برنچ develop را همان برنچ تست نهایی درنظر گرفتم به طوریکه این برنچ روی یک دامین تست فعال است و بعد از اضافه شدن هر Feature ابتدا روی دامین تست بررسی و سپس Release انجام می‌شود. )نکته: با استفاده از tag ها بعد از هر بار لانچ Master Branch را ورژن بندی می‌کنیم.برای ایجاد develop branch  یا در محیط کنترل ورژن آن را ایجاد میکنیم و یا اینکه با استفاده از دستور زیر روی ریپازیتوری لوکال آن را ایجاد و push میکنیم.git branch develop&#xA;git push -u origin developزمانی که از Git Flow استفاده می‌کنیم، با اجرای دستور git flow init  روی ریپازیتوری ای که وجود دارد develop branch نیز ایجاد می‌شود البته قبل از آن میبایست با اجرای دستور apt-get install git-flow آن را نصب کنید.شروع کار با git flowFeature Branchesهر ویژگی که به پروژه اضافه می‌شود روی یک برنچ با نام ویژگی توسعه داده می‌شود در واقع هر Feature یک Branch برای خود دارد که همه Feature Branchها از Develop به عنوان والد خود تبعیت می‌کنند و زمانی که یک Feature  تکمیل می‌شود با develop مرج می‌شود. ( هیچ وقت از برنچ‌های Feature مرج با master  صورت نمی‌گیرد )توجه کنید که هر Feature Branch از آخرین ورژن develop branch ساخته می‌شود در حالیکه همزمان با توسعه هر feature توسعه برنچ develop متوقف نمی‌شود و امکان توسعه و Merge سایر branchها وجود دارد.ایجاد feature branchاگر بخواهیم بدون استفاده از git-flow یک feature branch بسازیم به صورت زیر اقدام می‌کنیم:git checkout develop&#xA;git checkout -b feature_branchولی اگر از Git Flow استفاده کنیم به صورت زیر feature branch را ایجاد می‌کنیم:git flow feature start feature_branchاتمام Feature Branchزمانی که ویژگی‌های لازم اضافه شدند و feature branch تکمیل شد باید آن را با برنچ develop مرج کنیم.اگر بدون استفاده از Git Flow آن را Merge کنیم به صورت زیر اقدام می‌کنیم:git checkout develop&#xA;git merge feature_branchولی اگر از Git Flow استفاده کنیم به صورت زیر Merge را انجام می‌دهیم:git flow feature finish feature_branchپایان یک feature branchRelease Branchesاز نظر من Release branch یکی از جذابترین قسمت‌های Git Flow است، در ابتدا تصور من این بود وقتی develop برنچ را داریم و این برنچ را می‌توانیم با برنچ master  مرج کنیم چه نیازی است برنچ‌های جدیدی به نام release branch ایجاد کنیم!زمانی که برنچ develop به اندازه ای توسعه داده شد و feature های لازم با آن Merge شدند می‌توانیم آن را release کنیم و یک fork از develop برای release میگیریم. زمانی که برنچ release ایجاد می‌شود در واقع از این نقطه یک چرخه حیات برای آن برنچ ایجاد می‌شود و حتی اگر feture جدیدی هم با برنچ develop مرج شوند و تغییراتی صورت بگیرد شامل این نسخه از release نمی‌شود و این باعث می‌شود که تیم‌هایی که به صورت مستقل روی featureهای مختلف کار می‌کنند هیچ تداخلی با هم نداشته باشند. در واقع هیچ ویژگی جدیدی نمیتواند به این برنچ اضافه شود به استثنای bug fixها و موارد حیاتی که روی این برنچ انجام می‌شوند.زمانی‌که برنچ release آماده انتشار شد با master branch همراه تگ ورژن آن مرج می‌شود. همچنین لازم و ضروری است بعد از آن دوباره با develop branch مرج شود تا اگر موارد مهمی در این برنچ رفع شده بود و تغییراتی اعمال شده بود به برنچ develop نیز انتقال داده شود.زمانی‌که از Release branchها استفاده می‌کنیم در واقع تیم‌ها به راحتی باهم بر روی توسعه ویژگی‌های مختلف کار می‌کنند و همچنین میتوان پروژه را مطابق فاز بندی پیش برد به طوریکه به راحتی میتوانیم بگوییم مثلا این هفته ورژن ۴.۰ پروژه را لانچ می‌کنیم.از توضیحات فوق مشخص است که Release Branchها هم مانند Feature Branch ها بر مبنای develop branch ایجاد می‌شوند. برای ایجاد Release Branch به صورت زیر اقدام می‌کنیم:بدون استفاده از Git Flow :git checkout develop&#xA;git checkout -b release/0.1.0با استفاده از Git Flow :$ git flow release start 0.1.0&#xA;// Switched to a new branch &#39;release/0.1.0&#39;زمانی که نخستین Release آماده شد با برنچ‌های master و develop مرج می‌شود و پس از آن Release Branch حذف می‌شود. خیلی مهم است که Release Branch با develop branch مرج شود تا تغییرات مهم داخل release branch به develop branch منتقل شود و feature branch ها هم از آن استفاده کنند.برای اتمام release branch موارد زیر را انجام می‌دهیم.بدون استفاده از Git Flow :git checkout develop&#xA;git merge release/0.1.0&#xA;&#xA;git checkout master &#xA;git checkout merge release/0.1.0با استفاده از Git Flow :git flow release finish &#39;0.1.0&#39;Hotfix Branchesبرنچ Maintenance یا hotfix branch برای نگهداری و رفع سریع باگ‌های محصول نهایی است ( patch production releases ).در واقع Hotfix branches بسیار شبیه Release branch و Feature branch هستند با این تفاوت که hotfix branchها از master branch گرفته می‌شوند. Hotfix branch تنها branchی است که به طور مستقیم از master و بدون واسطه Fork میگیرد، پس از رفع باگ موردنظر با master branch و develope branch مرج میشود. ( همچنین اگر Release branch وجود داشته باشد که در حال اجرا باشد با آن نیز Merge می‌شود. ) پس از مرج، master branch ورژن تگ خود را آپدیت می‌کند.وجود یک مسیر و برنچ جدا برای bug fix این امکان را به تیم می‌دهد که منتظر Release بعدی و رفع باگ نباشند و هر تیم روی feature یا Release خود کار کند و پس از اتمام، آخرین آپدیت را دریافت می‌کند.  در واقع میتوانیم به این صورت تصور کنیم که hotfix یک برنچ با وظایف مشخص است که به طور مستقیم با master branch فعالیت می‌کند و تداخلی با روند اجرای فعالیت‌های تیم ندارد.بدون استفاده از Git Flow :git checkout master&#xA;git checkout -b hotfix_branchبا استفاده از Git Flow :git flow hotfix start hotfix_branchمشابه Release Branch برنچ  hotfix هم باید با master branch و develop branch مرج شود.بدون استفاده از Git Flow :git checkout master&#xA;git merge hotfix_branch&#xA;git checkout develop&#xA;git merge hotfix_branch&#xA;git branch -D hotfix_branchبا استفاده از Git Flow:git flow hotfix finish hotfix_branchمثال‌ کامل (رویه دستی بدون استفاده از ابزار git flow) :برای اینکه نشان دهیم یک Feature Branch به چه صورتی کار می‌کند با فرض اینکه ما آخرین آپدیت‌های master  را داریم و میخواهیم روی feature جدید کار کنیم :git checkout master&#xA;git checkout -b develop&#xA;git checkout -b feature_branch&#xA;# work happens on feature branch&#xA;git checkout develop&#xA;git merge feature_branch&#xA;git checkout master&#xA;git merge develop&#xA;git branch -d feature_branchهنگام کار روی hotfix branch  به صورت زیر اقدام می‌کنیم:git checkout master&#xA;git checkout -b hotfix_branch&#xA;# work is done commits are added to the hotfix_branch&#xA;git checkout develop&#xA;git merge hotfix_branch&#xA;git checkout master&#xA;git merge hotfix_branchدر این مقاله در مورد Gitflow Workflow صحبت کردیم، Git Flow یکی از استایل‌ها و سبک‌هایی از Gitflow Workflow است که شما می‌توانید توی تیم خودتون از آن استفاده کنید.نکات مهمی که Git Flow بر روی آن تاکید دارد این است که :در واقع workflow یک محیط عالی برای محصولات release-based است که در زمانبندی‌های مشخص می‌توانید Release‌های زمانبندی شده داشته باشید.برای رفع باگ های نسخه های نهایی لانچ شده Git Flow پیشنهاد می‌کند که یک برنچ و مسیر مشخص برای hotfix از محصول نهایی داشته باشیم.روند اجرای کلی Git Flow به صورت زیر است :develop branch از master branch ساخته می‌شود.release branch از develop branch ساخته می‌شود.Feature branches از develop branch ساخته می‌شود.زمانیکه یک feature تکمیل می‌شود با develop branch مرج می‌شود.زمانیکه یک release branch انجام می‌شود با master branch و develop branch مرج می‌شود.وقتیکه یک باگ شناسایی می‌شود یک hotfix branch از master branch ساخته می‌شود.وقتیکه hotfix رفع شد با برنچ‌های master و develop مرج می‌شود.نکته: وقتی که پروژه خود را روی لوکال clone می‌کنید و مطابق دستورات git flow پیش میروید به احتمال زیاد ورژن تگ‌هایی که وارد می‌کنید را روی گیت‌هاب یا گیت لب نبینید! برای اینکه ورژن تگها هم push شوند دستور زیر را اجرا کنید:git push --tagsهمچنین اگر روی لوکال git flow را اجرا کرده باشید و قبل آن برنچ‌ develop را ایجاد نکرده باشید با توجه به اینکه همه Releaseها روی برنچ release روی master قرار می‌گیرند به احتمال زیاد برنچ develop هم روی gitlab یا github شما وجود ندارد! برای اینکه همه تغییرات لوکال برنچ‌ها روی ریپازیتوری قرار بگیرند دستور زیر را اجرا کنید:git push --all -u</description><category>مهدی امیری متین</category><author>مهدی امیری متین</author><pubDate>Wed, 22 Jan 2020 00:32:35 +0330</pubDate></item><item><title>راهنمای نصب و کانفیگ dreamFactory در لینوکس</title><link>https://virgool.ir/@m.amirimatin/install-dreamfactory-in-linux-jrsl7vqlyvjv</link><description> دریم فکتوری چیست ؟‌ خودتان ببینید https://www.dreamfactory.com/ نصب و راه اندازیبر اساس متسندات موجود در وب سایت Dream factory برای نصب آن روش های مختلفی وجود دارد که هر کدام از آنها مزیت های خاص خودشان را دارند و ما ساده ترین روش و بی دردسر ترین روش را انتخاب کردیم و آن این است که فرض میکنیم از قبل php و mysql و nginx را در داکر نصب داریم پس نیازی به نصب مجدد آنها نیست لذا از آنجایی که  dream factory هم یک پروژه مبتنی بر فریم ورمک لاراول است آنرا به عنوان یک پروژه لارول بر اساس مستنداتی که در وب سایت دریم فکتوری موجود است نصب میکنیم.نکته مهم : دریم فکتوری نیازمند به یکسری پیشنیازهایی می باشد که  قبل از نصب باید در لینوکس نصب و فعال باشند.برای نصب پیشنیاز ها کامند های زیر را اجرا میکنیم.$ sudo apt-get install git curl zip unzipپس از نصب موارد بالا نیاز هست تا برخی از قابلیت های php را نیز نصب و فعال کنیم در اینجا ما این قابلیت ها را برای nginx نصب و فعال میکنیم و نسخه php ما هم 7.0 می باشد.sudo apt-get install php7.0-fpm php7.0-common php7.0-xml php7.0-cli php7.0-curl php7.0-json php7.0-mcrypt php7.0-mysqlnd php7.0-sqlite php7.0-mbstring php7.0-zip php7.0-bcmathسپس فایل php.ini را با استفاده از کامند زیر جهت ویرایش باز میکنیم:sudo nano /etc/php/7.0/fpm/php.iniسپس به دنبال عبارت زیر میگردیم و آنرا به شکل ذکر شده تغییر میدهیم:;cgi.fix_pathinfo=1تغییر به  cgi.fix_pathinfo=0از آنجایی که دریم فکتوری از mongoDb در بعضی از پکیج هایش استفاده میکند باید قابلیت پشتیبانی از mongoDB را نیز برای php باید فعال کنیم بدین منظور ابتدا نیازمندی های آنرا نصب میکنیم :sudo apt-get install php7.0-dev php-pear build-essential libsslcommon2-dev libssl-dev libcurl4-openssl-dev pkg-configسپس برای نصب آن کامند زیر را اجرا میکنیم:sudo pecl install mongodbسپس اگر فایل ini آن خودکار ایجاد نشد با کامند زیر آنرا ایجاد میکنیم:sudo sh -c &#39;echo &#34;extension=mongodb.so&#34; &gt; /etc/php/7.0/mods-available/mongodb.ini&#39;و در نهایت قابلیت پشتیبانی از mongodb را برای php با کامند زیر فعال میکنیم:sudo phpenmod mongodbاگر composer در سیستم نصب نباشد ابتدا باید آنرا با کامند های زیر نصب کنید:$ cd ~&#xA;$ mkdir bin&#xA;$ php -r &#34;copy(&#39;https://getcomposer.org/installer&#39;, &#39;composer-setup.php&#39;);&#34;&#xA;$ php composer-setup.php --install-dir=/home/dfuser/bin --filename=composerحالا برای نصب دریم فکتوری یک دایرکتوری به نام dreamfactory در مسیر /var/www/html ایجاد میکنیم:$ sudo mkdir /var/www/html/dreamfactoryسپس وارد آن میشویم و سورس لاراول دریم فکتوری را با کامند زیر از github  دریافت میکنیم:$ git clone https://github.com/dreamfactorysoftware/dreamfactory.git ./پس از clone شدن کامل پروژه کافی است با استفاده از کد زیر پکیج های مورد نیاز دریم فکتوری را دانلود و نصب کنید:$ composer install --no-devحالا برای ایجاد فایل .env پروژه دستور زیر را اجرا میکنیم:$ php artisan df:envدر این مرحله نوع دیتابیس را سوال میکند که ما mysql را که در داکر قبلا نصب داشتیم انتخاب میکنیم دقت کنید این دیتابیس مربوط به خود سیستم دریم فکتوری هست و ارتباطی به Api  ندارد شما بعدا میتوانید هر تعداد دیتابیس را api بدهید.نام دیتابیس و کاربر و رمز عبور و هاست آن را که میپرسد بدهید اگر اشتباهی رخ داد میتوانید فایل .env را ویرایش کنید.حالا برای اینکه دریم فکتوری نصب شود و جداول خود را ایجاد کند و تنظیمات خود را ذخیره کند دستور زیر را اجرا کنید:php artisan df:setupدر نهایت از شما اطلاعات یوزر اصلی را میخواهد که باید تکمیل کنید.پس از آن برای اینکه لاراول بتواند به فایل های کانفیگ و کش دسترسی داشته باشد دستور های زیر را اجرا مکنیم:$ sudo chown -R www-data:root storage/ bootstrap/cache/&#xA;$ sudo chmod -R 2775 storage/ bootstrap/cache/&#xA;$ php artisan cache:clearحالا برای اینکه دریم فکتوری را در مرورگر ببینیم میبایست فایل کانفیگ جدیدی برای nginx ایجاد کنیم و کانفیگ زیر را در آن قرار میدهیم :  server {&#xA;listen 80 default_server;&#xA;listen [::]:80 default_server ipv6only=on;&#xA;root  /usr/share/nginx/html/dreamfactory/public;&#xA;index index.php index.html index.htm;&#xA;server_name drfactory.local;&#xA;gzip on;&#xA;gzip_disable &#34;msie6&#34;;&#xA;gzip_vary on;&#xA;gzip_proxied any;&#xA;gzip_comp_level 6;&#xA;gzip_buffers 16 8k;&#xA;gzip_http_version 1.1;&#xA;gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;&#xA;location / {&#xA;try_files $uri $uri/ /index.php?$args;&#xA;}&#xA;error_page 404 /404.html;&#xA;error_page 500 502 503 504 /50x.html;&#xA;location = /50x.html {&#xA;root /usr/share/nginx/html;&#xA;}&#xA;location ~ \.php$ {&#xA;fastcgi_pass   php:9000;&#xA;try_files $uri $uri/ /index.php?$query_string;&#xA;include        fastcgi_params;&#xA;fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;&#xA;}&#xA;}و در نهایت دامنه drfactory.local را به 127.0.0.1 در فایل hosts سیستم تنظیم میکنیم با این وجود دیگر کسی از خارج از سرور و با استفاده از آی پی سرور هم قادر به دستیابی به پنل و api دریم فکتوری نخواهد بود اما برای ابتدای کار و زمانی که میخواهد Api را ایجاد کنید باید بتوانید وارد پنل دریم فکتوری از طریق مرورگر شوید لذا لازم است در ابتدا یک دامنه و یا آی پی صحیح برای آن ست کرد. ویا اینکه بجای استفاده از دامنه لوکال میتوان در بخش location فایل کانفیگ بالا عبارات زیر را قرار داد:location / {&#xA;allow 127.0.0.1;&#xA;&#x9;allow x.x.x.x;&#xA;&#x9;deny all;&#xA;...}&#xA;و به جای x.x.x.x آی پی اختصاصی خودمان (سرور) را تنظیم کرد.حال با وارد کردن آدرس دامنه مورد نظر در مرورگر میتوانید به پنل دریم فکتوری دسترسی داشته باشید و با استفاده از ادمینی که در مراحل نصب ساختید لاگین کنید.برای مشاهده داکیومنت نصب به این شیوه در سایت دریم فکتوری میتوانید به اینجا مراجعه کنیدکانفیگ و راه اندازیبرای راه اندازی اولیه می بایست وارد پنل دریم فکتوری شویددر ابتدا باید یک role  ایجاد کرد و دسترسی های مورد نیاز آن را تنظیم نمود سپس یک یوزر ایجاد کرد و به رول مورد نظر وصل کرد و پس از آن در بخش Services یک سرویس جدید ایجاد کرد و نوع دیتابیس آن را تعیین کرد به عنوان مثال mysql و نام دیتابیس را تعیین و نام کاربری و رمز و .. را وارد کرد در اینجا میتوان دسترسی نوشتن را برای این سرویس فعال کرد همچنین میتوان کش را برای آن فعال کرد.حال با مراجعه به تب api docs می توان به api این سرویس که ایجاد کردیم دسترسی داشته باشیم.</description><category>مهدی امیری متین</category><author>مهدی امیری متین</author><pubDate>Sun, 27 Jan 2019 15:06:22 +0330</pubDate></item><item><title>اصول کد نویسی منظم</title><link>https://virgool.ir/coderlife/اصول-کد-نویسی-منظم-g1kuwufs9mml</link><description>از آنجایی که معمولا همه برنامه نویس ها با این مشکل دست و پنجه نرم میکنند و غالبا از نامنظم بودن کلاس هایی که نوشتن همیشه شاکی هستن تصمیم گرفتم این مقاله کوتاه رو بنویسم.مشکل دقیقا از جایی شروع میشه که بخواید به صورت تیمی کار کنید اونوقت اگر هر کسی ساز خودش رو توی کد نویسی بزنه مسلما توسعه و فهم کد خیلی سخت و عذاب آور میشه پس بهتره همه به یک سری اصول پایبند باشند تا کمتر با این مشکل مواجه بشیم.کدنویسی قابل فهمتمامی برنامه نویسان حرفه ای برای کدنویسی قابل فهم ابتدا قسمتی که می خواهند برای آن کد نویسی کنند، تحلیل می کنند و مسائل پیچیده را به مسایل کوچکتر تقسینم کرده و مرحله به مرحله پیش میروند تا به راحتی متوجه روند پیشرفت برنامه باشند.همیشه در نظر داشته باشید کد های شما را باید دیگران بتوانند استفاده و تفسیر کننداستاندارد نام گذاری ها را رعایت کنیدنام جداول را همیشه به صورت snak_case  و جمع در نظر بگیریدنام کلاس ها را همیشه به صورت PascalCase در نظر بگیریدمتغیر ها را همیشه به صورت camleCase نامگذاری کنیدکلید ها را همیشه به صورت SCREAMING_SNAKE_CASE  نام گذاری کنیدنام فیلد های دیتابیس را همیشه به صورت snak_case و مفرد و گویا ذخیره کنید</description><category>مهدی امیری متین</category><author>مهدی امیری متین</author><pubDate>Sun, 27 Jan 2019 14:57:54 +0330</pubDate></item></channel></rss>