<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های آرش جعفرزاده</title>
        <link>https://virgool.io/feed/@arashjfz</link>
        <description></description>
        <language>fa</language>
        <pubDate>2026-04-15 10:28:32</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/549713/avatar/VS6DfM.jpeg?height=120&amp;width=120</url>
            <title>آرش جعفرزاده</title>
            <link>https://virgool.io/@arashjfz</link>
        </image>

                    <item>
                <title>Concurrency in database migration</title>
                <link>https://virgool.io/@arashjfz/concurrency-in-database-migration-cmpccdlhilem</link>
                <description>سلام به همه دوستان عزیز چند روز پیش یکی از دوستان توی linkedin یه مطلبی نوشته بود و یه نکته ای در اون دیدم که به نظرم رسید خوبه در موردش صحبت کنم. مسئله این بود که تصمیم گرفته بود پروسه مربوط به database migration رو زمان بوت سرور انجام بده که خوب این یه کار خیلی رایج هست. تو این نوشته ابزاری که ایشون استفاده کرده بود مد نظر من نیست مشکلی که به نظرم در این خصوص مطرح میشه اینه که ممکنه تصمیم داشته باشیم از instance برنامه همزمان چندتا بالا بیاریم. خوب شاید سوال پیش بیاد که مشکل چیه اینا همزمان بالا بیان. از اونجایی که عمل چک کردن اینکه یکی از migration ها انجام شده و اجرای مایگریشن در یک quantum انجام نمیشه (تا اونجایی که توی ef core و fluent migrator خوندم به نظر میاد اینطوری باشه) یعنی به فرض مثال اول برنامه توی یه query چک میکنه که Migration انجام شده و اگر نشده بود تو query بعدی اونو انجام میده خوب میتونن همزمان 2 تا instance از برنامه عمل چک رو انجام بدن و فکر کنن که migration انجام نشده و همزمان تصمیم به اجرای migration بگیرن. خوب این مطلب میتونه race condition به وجود بیاره.حالا راه حلی که بنده بهش رسیدم برای حل کردن این مشکل این بود که باید از یه lock در اسکوپ global استفاده کنیم.یعنی یه lock بزرگ روی اجرای migration بزاریم. ابزار های مختلف تو این زمینه هست ولی از اونجایی که migration را داریم روی database انجام میدیم اکثر دیتابیس ها روشی برای درست کردن lock دارن و پیشنهاد میکنم از اونا استفاده کنید. مثلا توی sql server یه sp به نام sp_getapplock وجود داره که با اون میتونیم یه lock عمومی درست کنیم. اگرم روی دیتابیسی که داریم کار میکنیم این امکان وجود نداشت میتونیم از redis red lock استفاده کنیم که اونم برایه اینه که یه lock در سطح global درست کنیم.نکته آخرم رو هم بگم که سرتون رو زیاد در نیارم. اینکه ما migration رو زمان boot سرور انجام بدیم مزایا و معایب خودش رو داره. از مزایاش میتونم به این اشاره کنم که لازم نیست تیم devops به این aware باشه که قرار هست با این instance از برنامه migration ای اجرا بشه. اما از معایب این کار اینه که اگه زمان اجرای migration طولانی باشه یا به هر نحوی اجرای migration زمانبر بشه (مثلا یهو زدیم یه column رو change type کردیم که جدولش یک میلیارد رکورد داره)  بالا اومدن سرور ممکنه با خطا مواجه بشه.</description>
                <category>آرش جعفرزاده</category>
                <author>آرش جعفرزاده</author>
                <pubDate>Sat, 02 Nov 2024 13:04:44 +0330</pubDate>
            </item>
                    <item>
                <title>Closure</title>
                <link>https://virgool.io/dotin/closure-lpq0zgshjcga</link>
                <description>سلام دوستان!چند وقتی بود که برایتان چیزی ننوشته بودم. برای همین تصمیم گرفتم مطلبی در مورد Closure بنویسم. Closure در زبان‌های برنامه‌نویسی وقتی به وجود آمد که اجازه دادند یک function در یک function دیگر ساخته شود. در سی شارپ delegate یک مدل از همین نوع function هاست. یا در Javascript می‌توانم بگویم functionی که می‌سازیم همین‌طور است. به طور کلی جایی که بتوانیم یک function را تعریف کنیم و مقدار آن function را برگردانیم ممکن است Closure به وجود بیاید. به مثال زیر دقت کنید:همان‌طور که مشاهده می‌کنید در مثال بالا داخل someFunctionThatReturnFunction یک function دیگر را بازمی‌گردانیم و در ادامه بعد از اتمام این function اقدام به صدازدن functionی که درون function ذکرشده وجود داره می‌کنیم.تا اینجا که همه چیز به نظر عادی و خوب می‌رسد اما اجازه بدهید مسئله رو کمی پیچیده تر بکنیم:همان‌طور که می‌بینیم این بار در someFunctionThatReturnFunction یک variable تعریف کردیم و در ادامه داریم از آن variable در function استفاده می‌کنیم. شاید سوال برایتان پیش بیاد که این مسئله چه مشکلی می‌تواند داشته باشد. جواب هم این است که ما در زبان‌های برنامه‌نویسی مفهومی داریم به اسم Scope که همان‌طور که می‌دانیم در Javascript ما کلا دو نوع Scope داریم یکی Global و یکی هم Function.حالا اگر هم در مورد Scope زیاد ندانیم مهم نیست. مهم این است که بدانیم در مثال بالا فرض بر این بوده که وقتی صدازدن someFunctionThatReturnFunction تمام می‌شود دیگر هرچی Variable در آن ساختیم کارش تموم می‌شود. بهتر است بگویم قرار بود بشود. اما نکته اینجاست که این متغییر در یک Functionی استفاده ‌شده که دارد از Function اصلی خارج می‌شود و نباید حذف شود.اینجاست که مفهوم Closure به وجود می‌آید. یک ماهیت به وجود می‌آید بین هر دفعه که آن Function اصلی رو صدا می‌زنیم و Function زیری و آن Variableی که در Function اصلی تعریف کردیم.اگه علاقه‌مند بودید که این مبحث را به صورت عمیق‌تری در Javascript بررسی کنید در لینک زیر توضیح خوب و پیچیده ای در مورد این مطلب نوشته شده است:http://dmitrysoshnikov.com/ecmascript/javascript-the-core-2nd-edition/#closureدر ادامه به نظرم بهتر است برویم سراغ سی شارپ و کمی بررسی کنیم ببینیم که در سی شارپ برای حل این مسئله چه کاری انجام می‌شود.به نظر می‌رسد طراحان زبان سی شارپ روش خیلی ساده‌تری را برای حل این مسئله پیدا کردند. خوب به کد زیر دقت کنید:همان‌طور که مشاهده می‌کنید در کد بالا نیز مانند مثال‌های ذکرشده متغیری وجود دارد که Closure شده است. حالا کد رو کامپایل می‌کنیم و در ILSpy باز می‌کنیم. در ILSpy باید کد را به صورت ILببینیم ولی برای سادگی مطلب من کد تولیدشده را به زبان سی شارپ برایتان می‌نویسم.همان‌طور که مشاهده می‌فرمایید مسئله به صورت خیلی ساده‌تری در سی شارپ حل شده است. اگر به خاطر بیاورید در قسمت قبلی گفته شد که Closure یک ماهیت است که بین زمان اجرای Function اصلی و Function زیری و Variableی که تعریف‌شده به وجود می‌آید. زبان سی شارپ نیز وقتی به کدی می‌رسد که متغیر لازم دارد Closure شود یک کلاس تولید می‌کند (در مثال ما کلاس c__DisplayClass0_0بود) و هر دفعه که Function اصلی  صدا زده می‌شود یک Instance جدید از آن درست می‌کند یعنی شروع می‌کند آن ماهیت را درست کند. از حالا به بعد هر جایی که مقدار متغییر تغییر پیدا می‌کند آن fieldی که در کلاس تعریف‌شده را تغییر می‌دهد. در نهایت هم هر موقع که با Function زیری کار داشت Method ساخته‌ شده در کلاس جدید را برمی‌گرداند.امیدوارم مطلب مفید بوده باشد.</description>
                <category>آرش جعفرزاده</category>
                <author>آرش جعفرزاده</author>
                <pubDate>Sun, 12 Sep 2021 11:02:19 +0430</pubDate>
            </item>
                    <item>
                <title>گیت و Three tree</title>
                <link>https://virgool.io/@arashjfz/%DA%AF%DB%8C%D8%AA-%D9%88-three-tree-g9p6txrppcit</link>
                <description>خوب دوستان بعد از چندی و اندی رسیدم خدمتتون گفتم یه مطلبی در مورد گیت بنویسم انقدر این نصیر مقاله تو ویرگول داد که دیگه منم دلم خواست یه دو تا کلام بنویسماز اونجایی که مطلب قبلیمو دوستان بدشون نیومد و گفتن چرت بدی نیست :دی به نظرم اومد یه کم بیشتر در مورد گیت بنویسمحالا قصد دارم چنتا مطلب دیگه هم در مورد گیت بعدا بنویسم اگه عمری بود و حس و حالش دست دادخوب این حرفا رو ولش کن بریم یه ضرب سراغ مطلب سرتون رو درد نیارم. مطلبی که در ادامه میخونید میخواد اینو بگه که سه مرحله وجود داره تا فایل شما توی گیت بره و کامیت بشه  اول فایل رو میسازیمبعد با add فایل رو stage میکنیمبعد هم commit میکنیم چیزی که میخونید توضیح بیشتر از عملکرد خود گیت هست و اینکه اون زیر میرا داره چیکار میکنهتوی گیت 3 مدل درخت وجود داره مثل این عکسدرخت Working Directoryاولیش که خیلی هم دم دستیه همون Working directory هستش. این همون فلدر اصلی هست که توش فایل ها رو کپی میکنیم. توش فلدر میسازیم و از این کارا میکنیم. وقتی یه کدی رو clone میکنیم یا وقتی روی یه برنچ checkout میکنیم گیت کدهای مربوط به اون برنچ رو میاره توی اینجا.درخت Indexدومیش رو میگن index و بعضی ها هم بهش میگن Staging که هر کدوم یه نگاه متفاوت داره. ایندکس بیشتر اصطلاحیه که توسط توسعه دهنده های گیت استفاده میشه و به عملکرد این Tree اشاره داره. اما Staging بیشتر توسط کاربران این درخت استفاده میشه و بیشتر به کاربردش واسه اونا اشاره داره حالا وقتی جلو تر توضیح بدم متوجه میشید (یه نکته رو خدمتون بگم این مطلبی رو که دارم میگم برداشت خودم هستش در مورد این تفاوت)بزارید اول از دیدگاه کارایی یه مرور بکنیم staging رو و بعد کامل Index رو توضیح میدم. وقتی ما تو گیت توی working directory یه فایلی رو اضافه کنیم میتونیم با دستور git add به گیت بگیم آقا من توی کامیت بعدی که بخوام بزنم قصد دارم این فایلو که بهت میگم هم توی کامیتم باشه.(اینطوری فکر نکنید که اگه فایله قبلا باشه اگه نزنید فایله پاک میشه از تو کامیت بعدی نه اینطوری نیست بلکه به گیت میگین آقا من میخوام این فایلو با محتویاتش توی کامیت بعدی ببرم) عملا میگیم آقا فایلو در وضعیت کنونیش ببر تو staging area.بعد از اینکه این کارو کردید هر وقت کامیت بزنید دیگه فایله میره.این مفهوم Staging توی گیت هستش. بهش staging area هم میگن.حالا بزارید بگم index چیه. ایندکس یه فایله توی فلدر git. که میشه به اون به عنوان یه جدول نگاه کرد این جدول یه سری رکورد داره که میگه هر فایلی در چه وضعیتی هست تو این stage و اینکه وقتی add میکنیم محتویات فایلو از توی working directory بر میداره و میزنه تو دیتابیس گیت و hash ساخته شده توسط دیتابیس گیت رو تو همین جدول میزاره(اگه دیتابیس گیت که میگم براتون گنگه یعنی مطلب منو در مورد Hash object  رو نخوندین)لینک زیر فرمت این فایلو آورده(البته فکر نکنم خیلی کاربردی باشه. خخخخخ)https://git-scm.com/docs/index-formatدرخت HEADقبل اینکه بخوام توضیح بدم HEAD چیه به نظرم لازمه که کامیت رو توضیح بدم که از نظر ساختاری چیه راستشو بخواین واسه دونستنش لازمه بفهمیم branch هم چیه دقیقا توی گیت.کامیت در کل یه snapshot از index هستش به قولی آنی رو نشون میده :دیوقتی کامیت میزنیم گیت یه کپی از وضعیت جدول ایندکس درست میکنه یا به عبارتی از ایندکس یه tree میسازه (منظورم از tree همونی هستش که توی مقاله hash object گفتم اگه یادتون باشه نوع داده ای 4 نوع بود blob  و tree و commit و tag) در ادامه یه چیزای دیگه هم مثل اینکه کی کامیتو زده و پدر و مادر کامیت کینو از این چیزا میزنه در نهایت خود محتوای کامیت رو توی دیتابیس خودش ذخیره میکنه و یه hash میگیرهحالا branch چیه خیلی ساده اگه بگم یه فایل هست واسه هر branch توی گیت که مقدار اون hash ای رو که بالاتر گفتم واسه کامیت ساخته میشه رو توی خودش نیگر میداره.یعنی به زبون ساده تر میگه آقا آخرین کامیت چی بوده.به زبون دیگه branch یه اشاره گر به کامیت هستش (وقتی آدرس hash کامیت رو نگه میداره توی خودش خوب یعنی داره بهش اشاره میکنه دیگه :دی)پس تا اینجای کار با زبون الکن خودم زور زدم بتونم توضیح بدم که کامیت و branch چی هستن سعی هم کردم یه کم عمیق تر به مطلب نگاه کنیمحالا وقتشه با دونستن این دو تا مورد واستون توضیح بدم که HEAD چی هستمفهوم HEAD خیلی ساده هستش داره میگه الان کدوم کامیت هستش که checkout شده همین. در کل HEAD هم نوعی اشاره گر هستش. دو نوع دیتا توش میتونه قرار بگیره یا میگه آقا الان من به یه branch  دارم اشاره میکنم یعنی الان مثلا روی master من checkout کردم یا اینکه دارم مستقیم به Hash یک کامیت اشاره میکنم که اصطلاحا به این حالت میگن HEAD تو حالت detached قرار داره یعنی الان لنگش رو هواس :دییه فایل توی git. وجود داره به نام HEAD اگه برید یه نگا ه بهش بندازید میبینید که در حالتی که روی یک branch گیت checkout کرده محتویات این فایل مثل زیر هستشref: refs/heads/masterو زمانی که HEAD رو detached کنید یعنی برید به صورت مجزا روی یک کامیت checkout کنید یه همچین چیزی میشه محتویات فایل HEAD78809a98c28499e2a951873b02246d95e510c0cdخوب یه مطلب دیگه بگم و یه لینک خوب هم بدم واسه مفهوم reference توی گیت و حرفامو تموم کنم دیگهhttps://git-scm.com/book/en/v2/Git-Internals-Git-Referencesلینک بالا یه توضیح خیلی خوبی داده حتما بخونیدشخوب حالا مطلب آخر چیه؟ آقا بابا اون دو تا درخت اول که گفتیم (Working tree و index) به خاطر اینکه ساختار درختی فایل رو نگهداری میکنن دقیقا ساختار درختی دارن ولی HEAD خدا وکیلی دیگه ساختار درختی نداره و فقط یه اشاره گره. پس چرا به اونم میگن درخت. چون این دوستان توی کامیونیتی گیت به ساختار لینک لیستی که توی commit ها وجود داره (هر کامیت یه parent داره) و در نهایت HEAD به صورت مستقیم به یه کامیت اشاره داره یا به هر حال به یه branch اشاره داره که اونم در نهایت به یه کامیت اشاره میکنه هم میگن درخت یعنی میگن میشه گفت linked list هم یه نوع درخت هست که فقط یه شاخه داشته باشه. اینطوری شده که به زور به اونم گفتن درخت که در نهایت به این سه محیط بگن Three tree که خوشگل بشه و باهاش حال کنن.ببخشید دیگه اگه سرتون رو درد آوردم منتظر نظرتون هستم.</description>
                <category>آرش جعفرزاده</category>
                <author>آرش جعفرزاده</author>
                <pubDate>Wed, 05 May 2021 00:21:59 +0430</pubDate>
            </item>
                    <item>
                <title>گیت و Hash Object</title>
                <link>https://virgool.io/@arashjfz/%DA%AF%DB%8C%D8%AA-%D9%88-hash-object-vgwkqtie6zjo</link>
                <description>دوست دارم تو این متن یه کم بیشتر در مورد گیت بنویسم و شاید چیزایو که کمتر شنیده باشیم رو در موردش بگمگیت خودش یه سایتی داره به اسم git-scm که به کمال تمام مواردی که توی این Source Control هست رو توضیح دادهاگه احساس میکنید هنوز با مفاهیمی مثل Commit ، Branch و یا Checkout تو گیت مشکل دارید پیشنهاد میکنم اون دکمه ضربدر بالا رو بزنید و از ادامه روزتون لذت ببریدمن قصد دارم خلاصه تر و به زبون فارسی یه مفهوم پایه ای رو که تو این سایت بهش Git Object میگه توضیح بدم. اگه میخوایین مطلب اصلی رو بخونید و حوصله چرت و پرت های منو ندارید لینک زیر رو استفاده کنیدhttps://git-scm.com/book/en/v2/Git-Internals-Git-Objectsگیت کلا یه فایل سیستم هست که یه سری کانتنت توش با یه سری کلید (Hash) ایندکس شدن.حالا این یعنی چی؟!!یعنی اینکه گیت یه دیتابیس هست که یه سری اطلاعات رو بهش میدی (مثلا فایل یا اگه برنامه نویس باشیم یه Byte Array) بعد اون یه Hash ازش میسازه و بعد اطلاعات و اون Hash رو ذخیره میکنه.گیت به اینا که ذخیره میشه میگه Object.هر وقت خواستیم با اون Hash  میتونیم به اون اطلاعات دسترسی پیدا کنیمگیت کلا اینه !! با یه سری کامند که از همین قابلیت پایه استفاده میکننواسه اینکه مطلب بالا رو بهتر تر متوجه شیم کامند های پایه ای که تو گیت میتونیم Content باهاش  ذخیره کنیم بعدش دوباره بخونیم رو مینویسمدستور hash-object کارش اینه  که یه کانتنت رو به صورت فایل یا ورودی std in میگیره یه Hash واسش میسازه بعد تو همون دیتابیسی که گفتم ذخیره میکنه در نهایت هم اون Hash رو بر میگردونه$ echo &#039;test content&#039; | git hash-object -w --stdind670460b4b4aece5915caf5c68d12f560a9fe3e4همینطور که میبینین تو دستور بالا test content رو به صورت ورودی به این دستور داده گیت هم ذخیرش کردهدستور بعدی cat-file هستش این دستور برای گرفتن اطلاعات در مورد Object های ذخیره شده تو همون دیتابسیه هست که گفتم به مثال زیر دقت کنید$ git cat-file -p d670460b4b4aece5915caf5c68d12f560a9fe3e4test contentهمون طور که میبینید وقتی که از این دستور استفاده میکنیم همون مقداری رو ذخیره کرده بودیم رو واسمون بر میگردونهبه صورت پیشفرض هم گیت همه این Object ها (اگه یادتون باشه گفتم گیت این اطلاعاتی که ذخیره میشرو اسمشو گذاشته Object) رو توی یه فولدری توی git. ذخیره میکنه به اسم objectsاگه بعد اجرای دستورا توی این فلدر برید یه فلدر دیگه هست 2 حرفی (6d) که دو تا حرف اول اون Hash توش قرار داره توی اون هم یه فایل هست با نام ما بقی hash و محتوای توش یه فایل Binary هست.زمانی که داریم این Object ها رو ذخیره میکنیم یه Type هم میتونیم بهش بدیم این کار رو با سوییچ t- انجام میدیمچهار نوع Object توی گیت وجود داره اولیش blob هست. این نوع رو اگه سوییچ t- رو استفاده نکنیم به صورت پیشفرض سیستم انتخاب میکنه.معنیش هم اینه که این Object دارای یه کانتن Binary هست. توی گیت تمام فایلها اگه بخوان به صورت Object ذخیره بشن (که میخوان :دی) با نوع blob ذخیره میشننوع بعدی رو بهش میگن tree . این نوع یه طورایی نقش Folder یا Directory رو توی File System داره تو مثال زیر یه نمونه این نوع Object هارو آوردم040000 tree 219f68b0f53109cc1d8a726fd191d97fb7d29c50    aj100644 blob 59e1e9879afcc40527d8f8c275932d1be6668d2a    outer.txtدقت کنید این نوع به صورت تکست ذخیره میشه و همینطوری که میبینید یه tree از یه  سری خط تشکیل شده که هر کدوم شامل 4 بخش هست permissions (یه عدد طبق استاندارد های unix هست انگاری) ، object type (نوع داده آیتمی که زیر مجموعش هست) ، hash و File name.نوع داده بعدی Commit هست که اونم قشنگ از اسمش معلومه چی هست.گیت وقتی یه کامیت رو میخواد ذخیره کنه از این فرمت استفاده میکنه. این مثال رو ببینینtree c37142272b67e5c8d20b676113ac29b1f5e13a81parent 90e1f792e12371e0014590668eb82dd661be3b73author Arash Jafarzadeh &lt;arashjfz@gmail.com&gt; 1611859705 +0330committer Arash Jafarzadeh &lt;arashjfz@gmail.com&gt; 1611859705 +0330یه کامیت کلا توی گیت اینه: یه tree که اشاره به اونی که میدونیم میکنه (:دی)  بعد میگه مادرم کیه (ممکنه بگه پدرمم کیه و اون زمانی هست که مرج میکنیم یعنی کامیت یه پدر داره یه مادر. الان ذهنتونو درگیر نکنید) در ادامه نویسنده و کسی که کامیت رو زده رو هم میگه (همون طور که میدونیم زمان کامیت زدن مثلا من میتونم بگم یکی  دیگه نویسنده کامیته. راستشو بخواین میتونم بگم یکی دیگه کامیتو هم زده!!!)به یه نکته توجه کنید که بعد parent یه hash اومده که نشون میده کامیت parent با چه hash ای ذخیره شده. در مورد tree هم همینطوره (کلا جناب لینوس به Pointer علاقه خاصی داشتن)آخرین نوع هم tag هست. tag هم از نظر ذخیره سازی نوعش تکست هست (دقت کنید که تو پوشه objects به صورت binary ذخیره میشه و وقتی بر میگردونیمش تکست هست یعنی به صورت مفهومی گیت بهش به صورت تکست نگاه میکنه).حالا این همه گفتم کلا چی هست. شما توی گیت دو مدل tag میتونید درست کنید.اولین مدل که tag ساده هستش فقط توی فایل ref مربوط به tag ، گیت Hash مربوط به کامیت رو ذخیره میکنه.اما یه مدل tag دیگه هم میشه توی گیت تعریف کرد که بهش میگن annotated tag. این مدل تگ ها دارای message و همچنین یه مفهومی هستن به اسم tagger که معادل  همون commiter هستش (ولی اصغرشون :دی) یعنی کی تگ رو ساخته.اینا دیگه باید توی دیتابیس گیت واسه خودشون Object مخصوص خودشونو داشته باشن چون میخوان اطلاعات بیشتری رو ذخیره کننمثال زیر Object یه annotated tag رو نشون میده object 17b9f3734abf1ec51a9fda56055379cb31207c5btype committag release/1.0.0tagger Arash Jafarzadeh &lt;arashjfz@gmail.com&gt; 1611860185 +0330Some tag messageامیدوارم مطالبی که نوشتم به دردتون خورده باشه چون من زمانی که با این مطالب خودم آشنا شدم خیلی حال خوبی داشتم.</description>
                <category>آرش جعفرزاده</category>
                <author>آرش جعفرزاده</author>
                <pubDate>Thu, 28 Jan 2021 23:01:14 +0330</pubDate>
            </item>
            </channel>
</rss>