<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های محمد اکبری</title>
        <link>https://virgool.io/feed/@akbarjimi</link>
        <description>محمد هستم. توسعه دهنده بک‌اند 31 ساله از خراسان که در تهران کار و زندگی میکنم و در اصفهان و مشهد هوش مصنوعی خوانده ام.</description>
        <language>fa</language>
        <pubDate>2026-07-05 07:38:16</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/255677/avatar/4toSEU.jpg?height=120&amp;width=120</url>
            <title>محمد اکبری</title>
            <link>https://virgool.io/@akbarjimi</link>
        </image>

                    <item>
                <title>از CAD تا AID: یک حرف همه چیز را تغییر می‌دهد</title>
                <link>https://virgool.io/@akbarjimi/%D8%A7%D8%B2-cad-%D8%AA%D8%A7-aid-%DB%8C%DA%A9-%D8%AD%D8%B1%D9%81-%D9%87%D9%85%D9%87-%DA%86%DB%8C%D8%B2-%D8%B1%D8%A7-%D8%AA%D8%BA%DB%8C%DB%8C%D8%B1-%D9%85%DB%8C-%D8%AF%D9%87%D8%AF-kp8u0ug99vsa</link>
                <description>Computer-Aided Designما طراحی به کمک کامپیوتر را نامگذاری کردیم. حالا وقت آن است که طراحی به کمک هوش مصنوعی را نامگذاری کنیم.در دهه ۱۹۶۰، مهندسان و طراحان با مشکلی مواجه بودند. آنها کامپیوترهای جدید قدرتمندی داشتند، اما هیچ راه ساده‌ای برای صحبت در مورد استفاده از آنها برای طراحی وجود نداشت. بنابراین آنها یک مخفف ابداع کردند: CAD - طراحی به کمک کامپیوتر. این مخفف جا افتاد. امروزه، CAD همه جا هست، از فریم ماشین گرفته تا آسمان‌خراش‌ها و تلفن همراه در جیب شما.شصت سال به جلو. اکنون هوش مصنوعی داریم که می‌تواند در عرض چند ثانیه طرح‌ها را تولید، بهینه‌سازی و تکرار کند. یک طراح می‌تواند یک قطعه را به زبان ساده توصیف کند و یک مدل هوش مصنوعی یک فایل سه‌بعدی تولید می‌کند. آنها می‌توانند سی نوع مختلف از یک براکت را درخواست کنند و هوش مصنوعی آنها را فوراً تحویل می‌دهد. آنها می‌توانند سریع‌تر از هر گردش کاری که فقط توسط انسان انجام می‌شود، اصلاح، ترکیب و دوباره تصور کنند.پس مخفف ما کجاست؟ما «طراحی به کمک هوش مصنوعی»، «طراحی مولد»، «مدل‌سازی مبتنی بر سرعت» داریم. همه اینها لقمه‌های دهان پرکن هستند. هیچ چیز به اندازه CAD واضح نیست.پیشنهاد من: AID – طراحی به کمک هوش مصنوعی.بله، «کمک» از قبل به معنای کمک است. دقیقاً نکته همین است. AID هم ابزار (هوش مصنوعی) و هم رابطه (کمک به انسان) را در بر می‌گیرد. کوتاه، به یاد ماندنی و متقارن با CAD است. CAD به کمک کامپیوتر ساخته شده بود. AID به کمک هوش مصنوعی ساخته شده است.اما آیا این گیج کننده نیست؟ آیا مردم به «کمک‌های اولیه» یا «کمک مالی» فکر نمی‌کنند؟شاید. اما زمینه کار سنگینی انجام می‌دهد. هیچ کس CAD را با «اعزام به کمک کامپیوتر» در یک جلسه مهندسی مکانیک اشتباه نمی‌گیرد. به همین ترتیب، در یک استودیوی طراحی، «AID» به سرعت به معنای جدید خود می‌رسد. کلمات اختصاری همیشه با هم برخورد می‌کنند - و کلمات مفید باقی می‌مانند.البته، می‌توانیم چیز دیگری اختراع کنیم: AIAD (خیلی دست و پا گیر)، CoD (معانی خیلی زیاد)، Gen‑Design (بد نیست، اما محدودتر). من مدام به AID برمی‌گردم. ساده است. کار می‌کند. این کلمه‌ای است که ما می‌خواهیم با فناوری مرتبط کنیم: ما می‌خواهیم هوش مصنوعی به ما کمک کند، نه اینکه جایگزین ما شود.هر دوره خلاقانه‌ای، خلاصه‌نویسی خاص خود را دارد. میز طراحی جای خود را به CAD داد. CAD اکنون جای خود را به گردش‌های کاری تقویت‌شده با هوش مصنوعی می‌دهد. بیایید این تغییر را نامگذاری کنیم.AID. آن را در جلسه بعدی تیم خود امتحان کنید. اگر مفید بود، از آن استفاده کنید. کلمات اختصاری برای همین هستند.نظر شما چیست؟ آیا AID کار می‌کند یا مورد بهتری دارید؟ به من پاسخ دهید یا من را تگ کنید - دوست دارم آن را بشنوم.</description>
                <category>محمد اکبری</category>
                <author>محمد اکبری</author>
                <pubDate>Thu, 04 Jun 2026 12:21:13 +0330</pubDate>
            </item>
                    <item>
                <title>اگر فایل آپلود شده عکس نیست، چرا Laravel فکر می‌کنه هست؟</title>
                <link>https://virgool.io/@akbarjimi/%D8%A2%D9%BE%D9%84%D9%88%D8%AF-%D9%81%D8%A7%DB%8C%D9%84-%D9%88-%D8%A7%D9%85%D9%86%DB%8C%D8%AA-%D8%AF%D8%B1-php-gupyzdhwkgeh</link>
                <description>چکیدهتوی این مطلب قراره دقیق و فنی دربارهٔ چالشها و روش های امن آپلود فایل توی وب اپلیکیشن ها، مخصوصاً فایل های تصویری، صحبت کنیم. از بررسی فایل های جعلی و محدودیت های سنتی PHP شروع میکنیم و بعدش میریم سراغ روش هایی مثل streamها، chunk scanning، و اعتبارسنجی هدر فایلها بدون اینکه کل فایل توی حافظه بارگذاری شه. همچنین با ابزارهایی مثل ClamAV و صفهای آسنکرون لاراول چطور میشه توی پس زمینه فایلها رو اسکن کرد بدون اینکه تجربهٔ کاربر خراب بشه. ۱۰. راه حل های پیشرفته برای یکپارچگی و امنیت فایلدر Laravel  میتونیم با استفاده از پکیج هایی مثل laravel-chunk-upload این کار رو انجام بدیم. مزیت این روش اینه که هم مصرف رم کاهش پیدا میکنه، هم امکان تشخیص خطاها و حملات تزریقی در لایه های پایین تر فراهم میشه. این رویکرد در سیستم های مقیاس پذیر، مخصوصاً زمان دریافت فایل های سنگین یا ناشناخته، خیلی کاربردیه.در سطح امنیتی بالاتر، میتونیم فرآیند اسکن آنتی ویروس رو همزمان با آپلود انجام بدیم. ابزارهایی مثل ClamAV، با پشتیبانی از پکیج هایی مثل laravel-clamav، به ما اجازه میدن فایل رو قبل از ذخیره شدن روی دیسک از نظر بدافزار بررسی کنیم. ترکیب این قابلیت با سیستم صف در لاراول باعث میشه پردازش های سنگین رو به صورت asynchronous انجام بدیم.۱۱. منابع برای مطالعه بیشترOWASP File Upload Cheat SheetHow to Upload Large Files in PHPFile Upload Bypass: Upload Forms Threat ExplainedBeyond the Upload Button: A 10-Year Retrospective on Security Issues Within File Upload</description>
                <category>محمد اکبری</category>
                <author>محمد اکبری</author>
                <pubDate>Tue, 01 Apr 2025 14:35:22 +0330</pubDate>
            </item>
                    <item>
                <title>کتاب PHP چگونه کار میکند؟ - مقدمه</title>
                <link>https://virgool.io/@akbarjimi/%DA%A9%D8%AA%D8%A7%D8%A8-php-%DA%86%DA%AF%D9%88%D9%86%D9%87-%DA%A9%D8%A7%D8%B1-%D9%85%DB%8C%DA%A9%D9%86%D8%AF-%D9%85%D9%82%D8%AF%D9%85%D9%87-if2ycm07qm9b</link>
                <description>مقدمهاین کتاب یک تلاش مشترک بین چندین توسعه‌دهنده زبان PHP برای مستندسازی بهتر و توصیف نحوه عملکرد داخلی PHP است. این کتاب 3 هدف اصلی دارد:۱. نحوه کار داخلی PHP را مستند کند و شرح دهد.۲. نحوه گسترش PHP با Extensionها را مستند کند و شرح دهد.۳. نحوه تعامل با جامعه برای توسعه خود PHP را مستند کند و شرح دهد.این کتاب در درجه اول برای توسعه دهندگانی است که تجربه کار با زبان برنامه نویسی C را دارند. با این حال، تا جایی که ممکن است، سعی می کنیم اطلاعات را خلاصه کنیم تا توسعه دهندگانی که C را خوب نمی دانند، همچنان بتوانند محتوا را درک کنند. با این حال، اکیدا توصیه میکنیم اگر زبان C را نمی‌دانید، نمی‌توانید به چیزی سازنده، پایدار (بدون خرابی تحت هر پلتفرمی)، کارآمد و مفید برسید. در اینجا منابع آنلاین بسیار خوبی در مورد خود زبان C، اکوسیستم و ابزارهای ساخت آن و APIهای سیستم عامل وجود دارد:http://www.tenouk.com/https://en.wikibooks.org/wiki/C_Programminghttp://c-faq.com/https://www.gnu.org/software/libc/http://www.faqs.org/docs/Linux-HOWTO/Program-Library-HOWTO.htmlشدیدا توصیه میکنیم نگاهی هم به این کتابها بیندازید. شما با آنها خواهید آموخت که چگونه از زبان C به طور موثر استفاده کنید، و چگونه آن را به دستورالعمل های کارآمد CPU ترجمه کنید تا بتوانید برنامه های قوی، سریع، قابل اعتماد و ایمن طراحی کنید:The C Programming Language (Ritchie &amp; Kernighan)Advanced Topics in C Core Concepts in Data StructuresLearn C the Hard WayThe Art of Debugging with GDB DDD and EclipseThe Linux Programming InterfaceAdvanced Linux ProgrammingHackers DelightWrite Great Code (2 Volumes)</description>
                <category>محمد اکبری</category>
                <author>محمد اکبری</author>
                <pubDate>Sun, 25 Jun 2023 22:30:30 +0330</pubDate>
            </item>
                    <item>
                <title>حل سوالات مسابقه دیجی‌کالا کاپ - فشرده‌سازی خاص</title>
                <link>https://virgool.io/@akbarjimi/solve-digikala-cup-quiz-questions-special-compression-fya7wycyjeao</link>
                <description>مسابقه دیجی کالاخرداد ماه امسال دیجی‌کالا مسابقه‌ای رو برگزار کرد که من هم شرکت کردم. البته نتونستم در زمان مقرر به همه سوالات پاسخ بدم. ولی سوالات رو دوست داشتم و میخواستم فارغ از برنده شدن یا نشدن در مسابقه، اونا رو حل کنم.علاقه‌ام به حل کردن اون سوالات و اینکه تازه داشتم روی یوتیوب‌ام هم کار میکردم باعث شد تا به این فکر برسم که یک پلی لیست به حل سوالات مسابقات مختلف اختصاص بدم. فعلا روی مسابقه دیجی‌کالا کاپ که در خرداد ۱۴۰۰ برگزار شد تمرکز کردم و سعی میکنم سوالاتش رو حل کنم.قطعا در آینده چالش‌های بزرگتری مثل چالش ناتاس رو پیش خواهم برد ولی فعلا برای شروع فکر میکنم این مسابقه خوب باشه. در حال حاضر فقط ۲ سوال از سوالات اون مسابقه رو حل کردم. سوال تیم پردرآمد که یک سوال مربوط به Database بود و سوال فشرده‌سازی خاص که تمرکزش روی توابع بازگشتی بود.blackfireدر حین ضبط حل سوال فشرده سازی خاص، میخواستم ابزار Blackfire رو هم معرفی کنم که متاسفانه دفعه اول خوب کار کرد ولی پروسه ضبط به هم خورد و دفعه دوم پروسه ضبط درست پیش رفت ولی Blackfire کار نکرد. ویدیوی نهایی رو میتونید اینجا ببینید، پلی لیست رو میتونید اینجا ببینید و کانال یوتیوب‌ام رو میتونید ازین لینک Subscribe کنید. همینطور کدهای این پلی لیست رو در این آدرس گیت‌هاب میتونید ببینید. اگر در تلگرام این مطلب رو میخونید، میتونید پایین همین صفحه ویدیو رو ببینید. https://youtu.be/FChw6reqeFI </description>
                <category>محمد اکبری</category>
                <author>محمد اکبری</author>
                <pubDate>Thu, 07 Oct 2021 11:25:56 +0330</pubDate>
            </item>
                    <item>
                <title>کارآیی بالا در MySQL</title>
                <link>https://virgool.io/@akbarjimi/%DA%A9%D8%A7%D8%B1%D8%A7%DB%8C%DB%8C-%D8%A8%D8%A7%D9%84%D8%A7-%D8%AF%D8%B1-mysql-niqpb3ohp1ju</link>
                <description>دوره آموزش کارایی بالا در mysqlچند ماه پیش بود که در مجموعه‌ای که اونجا مشغول به کارم، نیاز شدید و اورژانسی‌ای به پایگاه داده‌ای سریع و قابل اطمینان بوجود اومد. بعد از بررسی‌های زیاد تصمیم گرفتیم تا برای اطمینان بخشی به امنیت داده، از Cluster استفاده کنیم و برای سرعت هم بین بهینه سازی InnoDB و یا استفاده از یک پایگاه داده جدید و ناشناخته (البته برای خودمون) مثل NDB یکی رو انتخاب کنیم که در نهایت قرعه به نام &quot;بهینه سازی InnoDB&quot; افتاد.در حین فرآیند بهینه سازی ‌InnoDB برای کاری که میخواستیم انجام بدیم، مداوم به مساله کمبود منابع متنی یا ویدیویی برای سوالاتی که برامون ایجاد میشد میخوردیم. این کمبود رو با آزمون و خطا جبران کردیم و بالاخره تونستیم به هدف مدنظر خودمون برسیم. ولی این چالش برای من دغدغه‌ای رو بوجود آورد. چرا نباید منابع مربوط به بهینه‌سازی یکجا جمع بشند؟کارایی بالا در mysqlطی هفته‌های بعد، منبع بسیار قابل اطمینانی برای مساله بهینه سازی MySQL پیدا کردم. کتاب High Performance MySQL: optimization, backup and replication 3th edition. کتاب در سال ۲۰۱۲ منتشر شده و متعلق به دورانی هست که هنوز MySQL ۵.۷ منتشر نشده بود. ولی با این حال مطمئن بودم کلیاتی وجود داره که حتی در نسخه ۸ MySQL هم کاربردی هستند.شروع به خوندن کتاب کردم و تا فصل ۸ پیش رفتم. تا اینکه یک روز که داشتم با همکارم صحبت میکردم (همون همکاری که به لطف راهنمایی‌اش مطلب بهینه سازی کوئری Order By RAND رو نوشتم) حرف جالبی زد و اون این بود که بهترین راه یادگیری، یاد دادن هست. فوق‌العاده بود. تصمیم گرفتم کتاب رو از ابتدا، اما این بار با تمرکز روی یاد دادن به بقیه شروع کنم. https://youtu.be/nCObuAjTvUI و نتیجه اون تصمیم، شد سری جدید ویدیوهای یوتیوب‌م با عنوان دستیابی به کارآیی بالا در MySQL یا مشابه عنوان کتاب، High Performance MySQL. این پلی لیست مداوما به روز خواهد شد. اولین ویدیو رو میتونید از این لینک ببینید. پلی لیست در این لینک قابل دسترسی هست. از اینجا  هم میتونید عضو کانال‌م بشید. همینطور برای کسایی که علاقه‌مند به یادگیری عمیق‌تر جاوااسکریپت هم هستند پلی لیست &quot;جاوااسکریپت چگونه کار میکند&quot; رو دارم پیش میبرم. و البته برای کسانی که اهل حل مساله و چالش هستند هم پلی لیست &quot;حل سوالات مسابقه دیجی‌کالا کاپ - خرداد ۱۴۰۰&quot; فکر میکنم جالب باشه، که همین امروز ویدیوی جدیدش رو هم آپلود خواهم کرد.</description>
                <category>محمد اکبری</category>
                <author>محمد اکبری</author>
                <pubDate>Thu, 30 Sep 2021 13:41:06 +0330</pubDate>
            </item>
                    <item>
                <title>جاوااسکریپت چگونه کار میکند؟ بخش اول</title>
                <link>https://virgool.io/@akbarjimi/how-javascript-works-overview-s9mmtjyodlwa</link>
                <description>تو دنیای توسعه نرم‌افزار من ترجیح میدم ابزاری که باهاش کار میکنم رو عمیقا بشناسم. استدلالم هم اینه که تقریبا تمام نرم‌افزارهایی که برای کار با کامپیوتر یا ساخت چیزی با کامپیوتر توسعه داده شدند، از اصول اولیه‌ای پیروی میکنند. پس قاعدتا اگر شما این اصول اولیه رو بشناسید و حالا یکی ازین نرم‌افزارها مثلا سیستم‌عامل رو عمیقا مطالعه کنید، هم به کرار میتونید ببینید که از اون اصول کجا استفاده شده، هم اینکه نحوه استفاده و ترفندهایی رو حین مطالعه یاد بگیرید که در زمانی که خودتون قرار باشه محصول جدیدی رو خلق کنید و مسایل و مشکلاتی رو از سر راه بردارید، به کمکتون بیاند.پس بنابراین تقریبا در تمام مسائل زندگی ترجیح میدم قبل ازینکه دل به دریا بزنم، حداقل یک نوشته رو بردارم و در موردش بخونم. میتونه کتاب، مقاله یا رساله باشه. قاعدتا آدم‌هایی هم هستند که مثل من فکر میکنند و از مزیت‌های اینترنت همینه که میتونید آدم‌هایی شبیه خودتون رو پیدا کنید.یادم نمیاد اولین برخورد من با کنسول‌های بازی و به خصوص پلی‌استیشن کی بود، ولی از وقتی با این دستگاه‌ها آشنا شدم و به خصوص وقتی برای اولین بار دسته پلی‌استیشن رو توی دستام گرفت عشق به سونی و پلی‌استیشن‌اش توی وجودم کاشته شد و نه تنها چیزی ازش کم نشده که در گذر سالها بیشتر و بیشتر شده.طوری که همیشه رویای این رو داشتم که روزی محصولی بسازم که روی کنسول محبوب‌م قابل بازی باشه و از همه مهم‌تر اینکه یا من ساخته باشمش یا اینکه بخشی از تیمی باشم که اون محصول رو توسعه دادند. البته فکر نکنید که توسعه تنهایی بازی‌ها کار سختی هست و غیر قابل انجام. FlappyBird روی آندروید، Fez روی ایکس‌باکس، Braid روی پلی‌استیشن و ایکس‌باکس و از همه مهم‌تر super meet boy روی ایکس‌باکس همه کار تیم‌های یک یا دو نفره هستند و به فروش‌های میلیونی هم رسیدند. اما خب هیچوقت نتونستم اون طور که دوست دارم بازیسازی رو اصولی یاد بگیرم.بهرصورت ارتباطم رو با دنیای کامپیوتر حفظ کردم و الان یک توسعه‌دهنده وب هستم و همچنان از عشاق دنیای سرگرمی. خوشبختانه دنیای سرگرمی و وب بخاطر بازی‌های آنلاین به هم گره خوردند و موقعیتی پیش اومد تا با ابزاری آشنا بشم که در هر دو دنیا کاربرد داره. Node.JS.خب همونطور که بالا گفتم من ترجیح میدم از پایه و خیلی کند شروع کنم. Node.JS بر پایه JS و موتور V8 نوشته شده و همینطور برای مدیریت همزمانی از ابزارهای سیستم عامل مثل kqueue و epoll استفاده میکنه. پس برنامه من این شد که تو قدم اول اینا رو بشناسم و خب هر چقدر جلوتر رفتم شگفت زده‌تر شدم. همه چیز برام جدید و هیجان‌انگیز بود و درست مثل بچه‌ای بودم که وارد شهربازی شده، دوست داره همه چیز رو امتحان کنه.و حالا اون بچه دوست داره تجربه هیجان‌انگیز و لذت‌بخشش رو برای شما هم به اشتراک بگذاره. لزومی نداره شما از همه بخش‌های این تجربه به اندازه من لذت ببرید ولی امیدوارم چیزی که میخوام براتون تعریف کنم، شما رو هم برای تجربه و کشف و البته اشتراک اون به وجد بیاره. این شما و این اولین ویدیو از سری &quot;جاوااسکریپت چگونه کار میکند؟&quot; که در کانال یوتیوب من منتشر میشه. اگر ویدیوی پایین رو نمی بینید، میتونید از این لینک و مستقیما از خود یوتیوب تماشا کنید.https://youtu.be/XHehe9YZyGU https://youtu.be/XHehe9YZyGU </description>
                <category>محمد اکبری</category>
                <author>محمد اکبری</author>
                <pubDate>Fri, 20 Aug 2021 23:23:50 +0430</pubDate>
            </item>
                    <item>
                <title>بهینه سازی کوئری Order By RAND</title>
                <link>https://virgool.io/@akbarjimi/how-to-optimize-order-by-rand-tb1jgmyilxyw</link>
                <description>MySQL and Laravel and PHPاگر با لاراول و ORM‌اش Eloquent آشنا باشید، حتما با متد inRandomOrder هم آشنا هستید. کاری که این متد انجام میده، اضافه کردن این عبارت به انتهای کوئری شماست. &amp;quotyour query&amp;quot order by rand()حالا تصور کنید که یک اپلیکیشن برای قرعه‌کشی نوشتید و از بین هزاران رکورد پایگاه داده، قراره به صورت اتفاقی ۳ رکورد انتخاب کنید. کوئری شما به این شکل در میاد.&amp;quotyour query&amp;quot order by rand() limit 3قبل از اینکه بفهمیم همچین کوئری چه مشکلاتی پیش میاره و چطور میشه بهینه‌سازی‌اش کرد، اول بهتره بفهمیم که خود MySQL این کوئری رو چطور اجرا میکنه. پایگاه‌های داده در زمینه بهینه‌سازی کوئری‌های که بهشون برای اجرا کردن میدید خیلی خوب عمل میکنند ولی خب بهرحال اونها هم محدودیت‌های خودشون رو دارند. علاوه بر این ما اینجا میخوایم چند مقدار تصادفی رو انتخاب کنیم و ازونجایی که پایگاه داده برای همچین کوئری، بهینه‌سازی خاصی نداره، در واقع در دنیای SQL این یک Anti-pattern محسوب میشه.حالا بریم ببینیم پایگاه داده برای مرتب کردن سطرها در حالت تصادفی چیکار میکنه:۱- تمام سطرهایی که با شرایط کوئری شما (شامل where ها و group by ها و ...) match هستند رو توی حافظه Load میکنه.۲- به هر کدوم از این سطرها یک عدد تصادفی اختصاص میده.۳- تمام سطرها رو بر اساس این عدد تصادفی مرتب میکنه.۴- تعداد سطرهایی که بهش توی عبارت Limit گفتید رو بهتون برمیگردونه.اگر سطرهای کمی توی جدول داشته باشید، اینکار برای پایگاه داده خیلی آسونه. ولی هر چقدر تعدادشون بیشتر بشه، به همون اندازه هم اینکار غیربهینه‌تر میشه. هر چند باز هم بخش Load داده‌ها در حافظه حتی اگر جدول بزرگی داشته باشید، باز هم میتونه سریع باشه ولی مرتب کردن اونها کار سختی هست. علاوه بر این هر پایگاه داده‌ای محدودیتی در حجم داده‌ای داره که قراره مرتب بشه.بعنوان مثال برای mysql و در سیستم‌عامل لینوکس این مقدار اگر اشتباه نکنم باید ۲۵۶ کیلوبایت باشه. البته میشه این عدد رو بیشتر کرد ولی مزایا معایب خاص خودش رو داره. خب پس اگر قرار باشه داده‌هایی با حجم بیشتر از عدد بالا رو مرتب کنید، MySQL مجبور میشه از دیسک هم بعنوان حافظه کمکی استفاده کنه که در نتیجه سرعت عملیات رو خیلی پایین میبره.راهکار اول : Random Offsetیکی از ساده‌ترین کارها اینه که از ستونی استفاده کنیم که اعداد ترتیبی داره. مثلا کلید در پروژه‌های لاراول معمولا ID و از نوع big integer و auto increment هست و کاندیدای خوبی برای راه‌حل ماست. کوئری ما برای انتخاب ۳ سطر تصادفی، از ترکیب ۳ عدد تصادفی که بین اون اعداد ترتیبی پیدا کردیم، استفاده میکنه.SELECT * FROM table WHERE id IN(
    SELECT floor(random() * (COUNT(*)) + 1) FROM table
    UNION
    SELECT floor(random() * (COUNT(*)) + 1) FROM table
    UNION
    SELECT floor(random() * (COUNT(*)) + 1) FROM table
)این راهکار ساده‌ست ولی مشکلات خودش رو داره. حدف سطرهایی که حاوی اعداد ترتیبی هستند، منجر به ایجاد gap در فضای اعداد continous ما میشن که باید پر بشند. همینطور نمیشه از شرط استفاده کرد چون بازم باعث به وجود اومدن gap میشه، و البته بعضی سطرها میتونن بیشتر از یکبار در نتایج ظاهر بشند. راهکار دوم : Random Rangeحالا بیاید ایده قبلی رو یکم گسترش بدیم. به جای اینکه مجموعه داده‌ای مون رو مجبور کنیم که هیچ gapی نداشته باشه، میتونیم بگیم برای جستجو بین تمام سطرها از یک نقطه شروع تصادفی استفاده کنه.SELECT * FROM repositories WHERE id &lt;= (SELECT floor(random() * (COUNT(*)) + 1) FROM repositories) LIMIT 3این راه‌حل هم مشکلات خاص خودش رو داره. اگر بعضی از سطرهای متوالی رو حذف کنید، شانس سطرهای بعدی برای قرار گرفتن تو نتایج بالاتر میره. همینطور ما اینجا در شرطی که قرار دادیم، واضحا بعضی از سطرها رو از قرار گرفتن در نتایج حذف کردیم و رقابت بین سطرهای بعدی هست. راه حلچند وقت پیش با یکی از همکارهام در مورد راه حلی برای حل یک مساله مالی صحبت میکردیم که از الگوریتم k-NN اسم برد. من چیزی در موردش نمیدونستم. برام جالب شد و در موردش خوندم. حالا اینجا میخوایم یک ترفند بزنیم و از این الگوریتم برای حل مساله‌مون استفاده کنیم. کاری که میکنیم چیه؟ MySQL برای کار با GIS از Index های Spatial که اگر بازم اشتباه نکنم از نوع R-Tree هستند استفاده میکنه. کاری به جزییات‌اش نداریم. ما فقط میخوایم روی داده‌های تصادفی‌مون شاخص بگذاریم تا خیلی سریع به داده‌های تصادفی‌مون برسیم. بهینه سازی کوئری order by randیک ستون از نوع POINT به جدول اضافه میکنیم و توش رو با مقادیر تصادفی پر میکنیم. روی این ستون Index از نوع Spatial میگذاریم. خب تا اینجا رو اومدیم، بعدش چی؟ حالا کافیه یک نقطه شروع تصادفی انتخاب کنید و با استفاده از k-NN نقاط تصادفی مدنظرتون رو از بین انبوه داده‌ها بکشید بیرون.  متاسفانه ازینجا به بعد مرحله برای MySQL قفل هست و باید فعلا از Postgres استفاده کنید، چون k-NN در MySQL، هنوز پشتیبانی نمیشه. البته باید روی postgres هم از PostGIS استفاده کنید.</description>
                <category>محمد اکبری</category>
                <author>محمد اکبری</author>
                <pubDate>Tue, 22 Jun 2021 22:53:35 +0430</pubDate>
            </item>
                    <item>
                <title>IoC Container و استفاده از تکنیک Swap در لاراول</title>
                <link>https://virgool.io/@akbarjimi/laravel-ioc-swap-fxi4tdzivar3</link>
                <description>laravel ioc swapفرض کنید یک تابع Register برای ثبت نام کاربران در UserController دارید. درون این تابع قطعه کدی هست که یک رشته ۵ کاراکتری تصادفی برای کاربری که ایمیل خود را وارد سامانه کرده است، ارسال میکند.مساله اینجاست که چطور میخواید این قطعه کد که چند کاراکتر تصادفی تولید میکند را در فرآیند Test بررسی کنید.راه حل‌های اولیه خیلی ساده هستند. مثلا یک helper function بنویسیم و در اون مشخص کنیم که اگر در محیط Test بودیم، به جای یک رشته تصادفی، یک رشته از قبل مشخص شده، مثلا &quot;ab123&quot; رو به ما بده. اشکال این روش این هست که شما منطق برنامه‌تون رو در حین Test عوض کردید. برنامه شما قراره یک رشته تصادفی برای کاربر ایمیل کنه، نه یک رشته از قبل آماده شده.روش دوم این هست که اگر در محیط Test بودیم، اون تابع خروجی تصادفی خودش رو هم به ادامه برنامه بده و هم در یک جایی مثلا یک فایل JSON ذخیره کنه. خب این روش از قبلی، البته فقط در سطح ایده، بهتره.اشکال کلی که به دو روش بالا وارد هست اینه اگر عناصر پویای جدیدی مثل زمان هم به سیستم ما اضافه بشند، ثابت نگه داشتن زمان در حین تست کار بیهوده‌ای هست.بیاید تصور کنیم چی میشد اگر میتونستیم اون رشته رو جایی ذخیره کنیم بدون اینکه بخوایم به منطق برنامه دست ببریم. اگر با لاراول کار میکنید، میدونید که از IoC استفاده میکنه. اگر نمیدونید IoC چی هست، مخفف Inversion of Control هست (ویکی‌پدیا) و تصور کنید یک آرایه بسیار بزرگ از تمام کلاس‌های موجود در فریم‌ورک و اپلیکیشن شما هست که در هر جایی بهشون نیاز داشتید، میتونید ازشون استفاده کنید. توضیح فنی‌تر در عکس زیر هست.مراحل ایجاد یک IoCحالا کاری که باید انجام بدیم اینه که ۳ کلاس تعریف کنیم. یک کلاس برای Facade، یکی برای RangomGen و  یکی هم برای RandomGenFake. ما کدهایی که قراره کاراکترها تصادفی و عناصر پویا مثل زمان رو مدیریت کنه رو در RandomGen مینویسیم. RandomGenFake از RandomGen ارث‌بری میکنه و فقط یکی از توابع کلاس RandomGen که برای get کردن کاراکترهای تصادفی تولید شده هست رو نیازه تا override کنیم. این دفعه قبل از return کردن مقدار تولید شده، اون رو در یک متغیر static نگهداری میکنیم.حالا برای استفاده در قدم اول نیاز هست تا RandomGen رو در IoC رجیستر کنیم، در کلاس Facade نامی که در IoC به RandomGen اختصاص دادیم رو در تابع getFacadeAccessor برگردونیم و در کلاس Facade از swap استفاده کنیم. یک تابع static به نام fake میسازیم و در اونجا کلاس RandomGen اصلی رو با RandomGenFake عوض میکنیم یا اصطلاحا swap میکنیم و RandomGenFake رو برمیگردونیم. مشابه عکس زیرswapیکی از بزرگترین مزیت‌های این روش برای من، دسترسی به متغیر app هنگام swap هست، که میتونیم به عنوان آرگومان ورودی به تابع سازنده RandomGenFake بدمش و به کل اپلیکیشن دسترسی داشته باشم.من ایده این پیاده‌سازی رو از کلاس Notification لاراول که در Facadeهاش موجود هست گرفتم، بخاطر همین اینجا کدی برای نمایش نمیذارم و صرفا ارجاع‌تون میدم که اون کلاس رو که در حال حاضر در آدرس زیر هست،  مطالعه کنید.Illuminate\Support\Facades\Notificationبعد از همه اینکارها، اتفاقی که میفته اینه که در طی فرآیند Test فقط کافیه اول تابع تست Facade::fake رو صدا بزنید، حالا در IoC کلاس RandomGenFake نشسته، تست رو اجرا میکنید، و بعد از response گرفتن، هنوز به کاراکترهای تولید شده حین برنامه دسترسی دارید چون در یک متغیر static نگهداری میشوند.شاید سوالی براتون پیش اومده باشه که خب چرا نیاز هست دو کلاس داشته باشیم و میتونیم متغیر static رو در کلاس اول هم داشته باشیم. جواب من اینه که در برنامه‌هایی که تعداد Connectionها زیاد هست و به خصوص بعد از معرفی Laravel octane و رفتن لاراول به سمت Concurrency، استفاده از متغیرهای static اگر درست مدیریت نشن منجر به Memory Leak میشه.</description>
                <category>محمد اکبری</category>
                <author>محمد اکبری</author>
                <pubDate>Wed, 09 Jun 2021 09:39:55 +0430</pubDate>
            </item>
                    <item>
                <title>حداکثر کارایی در MySQL InnoDB Cluster</title>
                <link>https://virgool.io/@akbarjimi/optimize-mysql-innodb-cluster-ydfmojgsbcca</link>
                <description>MySQL InnoDB Clusterما برای ایجاد یک کلاستر ۳ عضوی از MySQL نسخه ۸ استفاده میکنیم. برای شروع، سرور باید تنظیمات زیر را هنگام bootstrap شدن اعمال کند.enforce_gtid_consistency=ONیکم در مورد GTID توضیح بدم. GTID مخفف Global Transaction Identfication هست و وقتی شما چند سرور MySQL رو Cluster کردید، اگر در سرور Primary تراکنشی انجام بشه بهش یک کد اختصاص داده میشه که شامل server_uuid و یک عدد هست که به صورت ترتیبی از ۱ تا ۴/۲۹۴/۹۶۷/۲۹۵ ادامه پیدا میکنه و با : از هم جدا شدند. مثلا 3E11FA47-71CA-11E1-9E33-C80AA9429562:1چون Replication ما از نوع GTID-based هست پس ما نیاز داریم که تنها statement هایی که می میتونند با استفاده از GTID با خیال راحت وارد سیستم بشن رو اعمال کنیم و باقی statement ها رو نادیده بگیریم. چه statement هایی با GTID-based replication سازگار نیستند؟ مثلا CREATE TABLE سازگار نیست.gtid_mode=ONحالا که بالا در مورد GTID و اجبارکردن سرور به اینکه حتما همه statementها از GTID استفاده کنند، صحبت کردیم و اعمالش کردیم، بهتره که سرور رو به حالت GTID ببریم. ممکنه شما یک سرور خام داشته باشید که هنوز روش داده ای نیست یا برعکس.ببینید تقریبا تمام statementهایی که در mysql اجرا میکنید در یک تراکنش اجرا میشند. حالا تراکنش میتونه بر حسب اینکه چه position‌ی در فایل binlog داره شناسایی بشه یا هم GTID. پس وقتی سروری که از قبل روش داده هست رو به حالت GTID میبرید یا باید همه تراکنش ها GTID-based بشند یا فقط تراکنش های جدید GTID بگیرند.اتفاقی که می افته اینه که برحسب مقداری که به این Flag میدید میتونه فقط تراکنش‌های جدید شما GTID بگیرند یا جدید و قدیم با هم GTID compatible باشند.server_id=$RANDOMخب ما اینجا دو تا عبارت برای توضیح دادن داریم. اول میریم سراغ server_id یا شناسه سرور. شناسه سرور همونطور که بالا گفتم عددی بین ۱ تا ۴ میلیارد و خورده ای هست. یعنی یک متغیر از نوع integer و unsigned هست. وقتی دارید چند سرور رو وارد  cluster میکنید برای اینکه این سرورها از تفکیک بشن نیاز هست که اعداد مختلفی بهشون نسبت داده بشه.ما چون از Docker برای راه اندازی cluster استفاده کردیم، تصمیم گرفتیم وقتی هر سروری راه‌اندازی میشه بهش با استفاده از متغیر RANDOM که یک متغیر سراسری در Bash لینوکس هست یک عدد تصادفی نسبت بدیم و چون تعداد سرورهای ما نهایتا ۷ خواهد بود پس احتمالا اینکه ۱ عدد تکراری رو به ۲ سرور نسبت داده باشیم خیلی کم هست.max_connections=5000حداکثر تعداد مجاز اتصال همزمان کلاینت ها.open_files_limit=21010در سیستم‌های Unix و Unix-like هر فایل برای بازشدن، بستن، نوشتن و خوانده شدن نیاز به یک عدد یکتا دارد. از آنجایی که فایل‌ها جزو منابع سیستم محسوب میشوند و هر پردازشی در یونیکس سقفی برای باز کردن منابع دارد، به صورت پیش‌فرض mysql تنها به ۱۰۲۴ اشاره‌گر فایل دسترسی دارد. در صورتی که فقط max_connection را اضافه کرده‌اید، عددش را در ۵ ضرب کرده و اینجا قرار دهید. اگر علاوه بر این table_open_cache رو هم تنظیم کرده با این فرمول عدد open_files_limit را محاسبه کنید.۱۰ + max_connection + (table_open_cache * 2)tmp_table_size=128Mحداکثر اندازه جداول موقتی حافظه داخلی. ببینید شما وقتی یک کوئری که مثلا توش join یا group by هست رو اجرا میکنید، mysql بعد از واکشی اطلاعات برای پردازش اونها یکسری جداول موقت که بعد از پایان یافتن کوئری از بین میرند، در RAM ایجاد میکنه. اگر اندازه این جداول کمتر از مقدار داده‌ای باشه که هر کوئری از دیسک فراخوانی میکنه، mysql مجبور میشه تا اطلاعات موقت رو دوباره رو دیسک بنویسه و در نتیجه I/O شما باز هم بالاتره میره.برای مقداردهی به این flag بهتره ابتدا سرورهای خودتون رو زیر فشار قرار بدید، سپس کوئری show global status where Variable_name like &#x27;%tmp%&#x27; رو اجرا کنید. خروجی جدولی ۳ سطری خواهد بود که برای ما ۲ سطر Created_tmp_disk_tables و Created_tmp_tables مهم هستند. اگر RAM زیادی دارید بهتره مقدار tmp_table_size رو به قدری بالا ببرید تا Created_tmp_disk_tables به صفر برسه وگرنه هر چقدر ازین عدد کم کنید بهتره.table_open_cache=8000خب یکبار دیگه نیاز هست تا کوئری که بالا روی متغیرهای سیستمی اجرا کردیم رو اجرا کنیم. با این تفاوت که به جای %tmp% مقدار %Open_tables% رو قرار میدیم. اگر عددی که در سطر Open_tables هست خیلی بالا بود، بهتره مقدار این Flag رو بالاتر ببریم. البته حواستون باشه که اگر مقدار این flag رو بالا میبرید، باید مقدار open_files_limit رو هم بالا ببرید.table_open_cache_instances=16 or 8مستندات mysql توصیه میکنه که در صورتی که سرور شما پردازنده‌ای با ۱۶ هسته داره این مقدار رو روی ۸ یا ۱۶ بگذارید. بهتره بعد از اعمال هر کدوم از این عددها یکبار بنچمارک بگیرید تا عدد مناسب رو قرار بدید.max_prepared_stmt_count=512000این متغیر تعداد کل دستورات آماده شده در سرور رو محدود می کنه. میتونه در محیط هایی مورد استفاده قرار بگیره که احتمال حملات DDOS بر اساس خاموش شدن حافظه سرور با تعداد کوئری‌های بسیار زیاد وجود داره. اگر مقدار کمتر از تعداد فعلی کوئری‌ها تنظیم بشه، کوئری‌های موجود تحت تأثیر قرار نمی گیرند و میشه از اونا استفاده کرد ، اما تا زمانی که عدد فعلی به زیر حد نرسه، نمیشه دستورات جدیدی تهیه کرد. تنظیم مقدار 0 این ویژگی رو غیرفعال می کند.transaction_isolation=REPEATABLE-READخب ما در RDBMS‌ها ۴ سطح قفل شدن داده داریم. این قفل شدن داده با قفل شدن‌های table lock و row lock که در InnoDB و MyISAM استفاده میشه فرق میکنه و نیاز داره که یک مقاله جداگانه در مورد انواع مقادیرش و نحوه عملکردشون نوشته بشه. پیشنهاد میشه در جاهایی که داده حساسی دارید از REPEATABLE-READ استفاده میکنید. در غیر این صورت میتونید سطح رو پایین تر بیارید مثلا روی READ-COMMITTED یا READ-UNCOMITTED‍back_log=5000خب تصور کنید که mysql شما در یک مدت زمان کوتاه، تعداد زیادی درخواست اتصال پیدا میکنه. مثلا یک کمپین تبلیغاتی برگزار کردید و انتظار دارید حجم زیادی کاربر محصول خاصی رو درخواست بدن و این تعداد از مقدار max_connection بیشتر بشه. در نتیجه اتصالات زیادی باید در صف قرار بگیرند. مقدار back_log نشون میده قبل از اینکه لحظه ای پاسخ MySQL به درخواست های جدید متوقف بشه چند درخواست رو می تونه در این مدت کوتاه انباشته کنه. البته در نظر داشته باشید که اگر انتظار تعداد اتصالات بسیار زیاد در زمان کم رو دارید این مقدار رو زیاد کنید. به عبارت دیگه، این مقدار به اندازه صف listen() برای ورودی های TCP / IP هستش. سیستم عامل شما محدودیت خاصی در اندازه این صف داره. اگر از سیستم عامل‌های Unix-like استفاده میکنید بهتره صفحه راهنمای سیستم عامل خودتون رو در این زمینه مطالعه کنید. چون این عدد نمیتونه بیشتر از اندازه‌ای که در سیستم عامل برای این صف در نظر گرفته شده، باشه.character_set_server=utf8mb4collation_server=utf8mb4_general_ciطبق گفته وبلاگ تیم سرور mysql کدگذاری utf8mb4 بسیار سریع است و نیازی به عوض کردن آن نیست. پس اگر جایی خوندید که کدگذاری ascii از utf8mb4 سریعتر هست چون بیت‌های کمتری مصرف میکند، تب رو ببندید.</description>
                <category>محمد اکبری</category>
                <author>محمد اکبری</author>
                <pubDate>Tue, 20 Apr 2021 12:25:19 +0430</pubDate>
            </item>
                    <item>
                <title>آمار بازدید پست‌های من در سال ۹۹</title>
                <link>https://virgool.io/@akbarjimi/%D8%A2%D9%85%D8%A7%D8%B1-%D8%A8%D8%A7%D8%B2%D8%AF%DB%8C%D8%AF-%D9%BE%D8%B3%D8%AA-%D9%87%D8%A7%DB%8C-%D9%85%D9%86-%D8%AF%D8%B1-%D8%B3%D8%A7%D9%84-%DB%B9%DB%B9-ozry5kukv4of</link>
                <description>در طول تاریخ از اعداد استفاده کردیم تا اغلب داد و ستد کنیم و آن‌چیزی که شمردنی است را بشماریم. برای هر عدد واحد درست کردیم تا عددهای زندگی قاطی نشوند و از اعداد، شفاف‌تر استفاده کنیم؛ مثلا وقتی می‌گوییم ده هزار تومان به پول اشاره داریم و وقتی می‌گوییم ده هزار بلیط به بلیط!روز به روز که در زندگی جلو‌تر رفتیم عددها فرقی نکردند ولی این واحدها بودند که زیاد شدند. واحد کریپتو، واحد اصله درخت، واحد فاصله و …«واحد» یک توافق عمومی است برای شمردن؛ تا همانطور که گفتم شمردن‌ها قاطی نشود. مشاهده افراد دارای ثروت (اجتماعی یا مالی) به من ثابت کرده اینکه چه چیزی را بشماریم از اینکه چطور بشماریم مهم‌تر است. هرکس با واحد خاصی مسائل زندگی را می‌شمارد. اینطور به نظرم آمده که مشخص کردن واحد یعنی مشخص کردن اینکه من در زندگی برای چه چیزهایی ارزش قائلم و می‌خواهم چه چیزهایی را در زندگی بشمارم. https://cdn.virgool.io/annual-report/1399/kixyjv7q4bda-NP0g5.mp4 اعدادی که بدون واحد ثبت کردمبه ویدیویی که ویرگول برایم ساخته که نگاه می‌کنم میبینم که در سال ۹۹، من در مجموع ۳۲۱ کلمه در ویرگول نوشتم و منتشر کردم و مخاطبین، پست‌های من را ۳ مرتبه پسندیدند و  ۰ بار هم نظر خود را روی پست‌های من به اشتراک گذاشتند. در سال ۹۹، ۰ نفر در ویرگول من را دنبال کردند تا پست‌های بعدیم را بخوانند. این اعداد نشان میدهند من کاری کرده‌ام. هرکدام به واحدی وصل هستند. از خودم می‌پرسم من کدام واحد را شمارش کرده‌ام؟ کدامیک از واحدهای بالا از همه برای من مهم‌تر است؟ ادامه ویدیو را می‌بینم.آمار از اثر بیرونی می‌گویندطبق آمار پست‌های من ۱۶۰ بار خوانده شدند و ۷۵۰ ثانیه صرف مطالعه آنها شده است، که با توجه به جمعیتی که در ایران به اینترنت دسترسی دارند، ویرگول به من می‌گوید که توانستم  ۰/۰۰۰۰۱۰۲۸۲ ثانیه، سرانه مطالعه دیجیتال کشور را بالا ببرم.از طرف دیگر ویرگول به من می‌گوید که اگر قرار بود پست‌هایم را چاپ و به دست تک تک خوانندگان برسانم باید ۳۲۰ کاغذ مصرف می‌کردم.آن عددهای کوچک ابتدای ویدیو حالا تبدیل شده‌اند به عددهای بزرگ به اینکه من جلوی مصرف این تعداد کاغذ را گرفتم یا به اینکه من  ۰/۰۰۰۰۱۰۲۸۲ ثانیه، سرانه مطالعه دیجیتال کشور را جابه جا کرده‌ام. واحد این عددها برای من ملموس‌تر است.واحد نوشتن چیست؟همه عددهای بالا و همینطور اثر بیرونی که روی خوانندگان و همینطور در مقیاس بزرگتر طبیعت و جامعه اطرافم گذاشتم اعدادی هستند که من دوستشان دارم و به آنها افتخار می‌کنم. اگر چنین ویدیویی دست شما نیز رسید به شما بابت تک تک اعداد تبریک می‌گویم.اثر هر نوشته تا حدودی معلوم است، اگر بنویسید جلوی قطع درخت را می‌گیرید، به سرانه مطالعه کشور اضافه می‌کنید و خوانندگانی جذب می‌کنید که شما را از طریق نوشته‌هایتان می‌شناسند و …به نظرم می‌رسد که نوشته‌های من و شما واحد ندارند ولی اثر بیرونی دارند.</description>
                <category>محمد اکبری</category>
                <author>محمد اکبری</author>
                <pubDate>Mon, 22 Mar 2021 19:46:16 +0430</pubDate>
            </item>
                    <item>
                <title>پیاده‌سازی Swoole در لاراول به کمک Laravel Octane</title>
                <link>https://virgool.io/@akbarjimi/laravel-octane-bnzsyat028ue</link>
                <description>PHP Swooleاز مدتی پیش تصمیم گرفته بودم که حداقل هفته ای یک مطلب در اینجا بنویسم. هفته‌ای که گذشت به استرس‌های مختلفی گذشت و چندان جایی برای نوشتن مطلب جدید نگذاشته بود. این بی مطلبی باعث شد که تصمیم بگیرم بخشی از نظرات خودم رو در مورد انسان و جامعه بنویسم.ولی خب خدا رو شکر از در اکوسیستم لاراول از در و دیوار اخبار جدید، Package‌های جدید و مدل‌های جدید میباره و نیازی نیست تا افکار خودم رو به رشته تحریر در بیارم. پس در اینجا قبل ازینکه عازم سفر بشم جدیدترین خبر هیجان‌انگیزی که همین نیم ساعت پیش خوندم رو مینویسم.شاید بگین چرا لینک ندادی؟ که خب باید بگم دوست داشتم :). ماجرا ازین قراره که من از تقریبا اوایل زمستان ۹۹ با موجود جدیدی به نام Swoole در دنیای PHP آشنا شدم و در پروژه نرم‌افزاری اخیری که در مجموعه‌ای که باهاشون کار میکنم انجام دادیم اصرار زیادی به پیاده‌سازی اون داشتم.منتها مدیر من با این تصمیم به دلیل حساسیت بالای پروژه مخالفت کرد و گفت اگر روزی پیاده‌سازی سالمی از اون انجام شد، حتما Swoole رو در پروژه‌های خودمون به کار خواهیم گرفت. از اونجایی که من آدم عجولی هستم، تصمیم گرفتم به جای انتظار و نشستن برای اینکه روزی کسی بخواد Swoole رو در Laravel پیاده‌سازی کنه، خودم مطالعه و پیاده‌سازی‌اش کنم.Road Runnerهمین الان که دارم این مطلب رو مینویسم، کنفرانس سالانه LaraCon 2021 در جریان هست و Taylor Otwell خالق این فریم‌ورک محبوب، لاراول اکتان یا به انگلیسی Laravel Octane رو معرفی کرد. لاراول اکتان پیاده‌سازی Swoole و RoadRunner که دو Coroutie محبوب در دنیای PHP هستند، در لاراول هست.شاید بپرسید فایده این ۲ Coroutine چی هست؟ باید بگم تصور کنید در صورتی که پایگاه داده شما گلوگاه نباشه، میتونید تا ۶۰۰۰ درخواست در ثانیه یا ۵۰۰ میلیون درخواست روزانه رو پاسخگو باشید. الان چون خیلی هیجان زده بودم و البته همزمان عجله هم دارم، همینجا صبر میکنم تا در مطالب بعدی بیشتر در مورد Swoole و Connection Pool صحبت کنیم.</description>
                <category>محمد اکبری</category>
                <author>محمد اکبری</author>
                <pubDate>Thu, 18 Mar 2021 16:25:52 +0330</pubDate>
            </item>
                    <item>
                <title>تابع fsync در PHP</title>
                <link>https://virgool.io/@akbarjimi/fsync-buffers-all-the-way-down-kmyj0g2zzfsv</link>
                <description>خب سلام. امشب میخوام اولین مطلب این وبلاگ رو منتشر کنم و قاعدتا همونجور که از قدیم گفتن، بچه اول مال کلاغهاست.مساله اینه که من تقریبا یک هفته پیش در پادکستی به نام PHP Internal News اپیزودی رو گوش کردم که این عنوان رو داشت.fsync: Buffers All The Way Downچند ماهی هست که با MySQL سر و کله میزنم و به لطف کتاب High Performance MySQL: Optimization, Backups, Replication, and More کمی با ساختار و نحوه کارکردش آشنا شدم. آخرین قسمت از کتاب رو که داشتم میخوندم، در مورد نحوه ذخیره سازی داده روی دیسک بود و از تابع fsync اسم برده بود. وقتی چشمم به عنوان این اپیزود از پادکست رسید حدس زدم باید اطلاعات جالبی در موردش بهم بده. و خب حدسم صحیح بود.تابع fsync تا اونجا که من فهمیدم برای اطمینان حاصل کردن از نوشته شدن داده روی دیسک به کار میره و برخلاف سایر زبان ها، در PHP پیاده سازی نشده.تصورم این بود که خب چیز مهمی رو از دست ندادم و احتمالا خیلی کم با نبود این تابع مواجه بشم. که اینجا حدسم اشتباه بود و خیلی زود، یعنی در واقع همین امروز با عدم وجود تابع fsync در PHP مواجه شدم. ماجرا از این قرار هست که برای جلوگیری از race condition در یک حلقه بی‌نهایت، با استفاده از Cache لاراول، یک Lock رو در فایل مینویسم.منتها سرعت اجرای حلقه از سرعت نوشته شدن Lock در دیسک بسیار بیشتر هست. پس قاعدتا وقتی فرمان نوشتن به دیسک ارسال میشه، دیسک این فرمان رو اجرا میکنه، منتها در buffer خودش مینویسه. وقتی حلقه میخواد دوباره اجرا بشه، ابتدا وجود Lock رو بررسی میکنه ولی چون Lock هنوز نوشته نشده، پس به اجرا شدن ادامه میده.فرصت بسیار خوبی هست تا تابع fsync رو به Cache لاراول در قالب یک PR اضافه کرد. مسلما کسی که بتونه این کار رو بکنه نشوندهنده دانش خوبش در PHP و لاراول هست و رزومه خوبی براش میشه.</description>
                <category>محمد اکبری</category>
                <author>محمد اکبری</author>
                <pubDate>Mon, 08 Mar 2021 23:50:59 +0330</pubDate>
            </item>
            </channel>
</rss>