زبانی قدرتمند با ویژگی‌های هم‌زمانی، توزیع‌پذیری و خطاپذیری: ارلنگ، اژدهای هزار سر

اهداف و تاریخچه
می‌توان گفت، یک سامانه مخابراتی که قرار است داده‌های میلیون‌ها مشترک در شهرها و کشورهای مختلف را به یکدیگر برساند نیازمند آن است که صفات یک اژدهای هزار سر را داشته باشد.
باید Robust باشد، بهرمند از آزموده‌‌‌ترین اجزا، ابزارها و امکانات در شرایط سخت.
باید بتواند پاسخگوی میلیون‌ها درخواست ارسال و دریافت داده‌های مشترکان در لحظه و به صورت Concurrent باشد چنان که که بتواند با استفاده از Multi­threading از تمام ظرفیت هسته‌های پردازنده مرکزی سخت‌افزار استفاده کند.
نباید وجود خطا برای یک مشترک یا یک مرکز مخابراتی بر روی مشترکان دیگر یا مراکز مخابراتی دیگر تاثیر گذار باشد و دیگران به صورت Fault Tolerant بتوانند به فعالیتشان ادامه دهند.
در کنار ویژگی‌های فوق، باید خود را به صورت Distributed نیز در نقاط مختلف به صورت مجازی یا فیزیکی بسط دهد تا بتواند بیشترین میزان Availability را برای سال‌های سال ارائه دهد.
نوشتن نرم‌افزار چنین سامانه‌هایی نیازمند زبانی است که بتواند این اهداف را برآورده کند، مانند زبانی که شرکت اریکسون در سال ۱۹۸۶ به وجود آورد و نام آن را Erlang گذاشت. ترکیب کلامی عبارات Error-handling Language یا Ericsson Language می‌تواند دلیل نام ‌گذاری این زبان باشد، اما Agner Krarup Erlang دانشمند، ریاضیدان و مبدع نظریه صف را می‌توان دیگر دلیل این نام ‌گذاری دانست.

این زبان، به همراه چهارچوب استاندارد خود با نام OTP نهایتا در سال ۱۹۹۸ به صورت متن‌باز ارائه شد و مورد استقبال شرکت‌های بزرگی مانند T-­Mobile و Motorola قرار گرفت.

ارلنگ زبانی است تابعی (Functional)، با مدیریت حافظه خودکار و Type System پویا، و تاثیر گرفته از زبان‌هایی مانند Prolog و Smalltalk.
این زبان، به همراه چهارچوب استاندارد خود با نام OTP نهایتا در سال ۱۹۹۸ به صورت متن‌باز ارائه شد و مورد استقبال شرکت‌های بزرگی مانند T-­Mobile و Motorola قرار گرفت.
با همه‌گیر شدن اینترنت و نرم‌افزارهای مبتنی بر آن از طرفی و نیاز‌مندی‌های مشابه این نرم‌افزارها با سامانه‌های مخابراتی از طرف دیگر؛ امروزه شرکت‌هایی مانند Amazon, Facebook, WhatsApp, Yahoo و بسیاری دیگر از ارلنگ به عنوان بستری مناسب برای کارهای سخت استفاده می‌کنند تا بتوانند میلیون‌ها کاربر خود که در نقاط مختلف جهان هستند را همواره پاسخ‌گو باشند. به نحوی که کاربرانشان به سرویس‌دهی همیشگی آن‌ها اعتماد دارند، همان‌قدر که به تلفن خانه‌شان اعتماد دارند.
البته زبان ارلنگ در ر‌ده خود رقبایی نیز دارد که بررسی آن‌ها در مقایسه با ارلنگ در محدو‌ده‌ی این مقاله نمی‌گنجد.

ویژگی‌ها
در این بخش به تفصیل ویژگی‌های اصلی ارلنگ را بررسی خواهیم کرد.

تابعی (Functional)
زبان‌های تابعی نوع خاصی از زبان‌های برنامه‌نویسی هستند که محاسبات خود را به شیوه توابع ریاضی بر روی حالات و داده‌های تغییرناپذیر انجام می‌دهند. همان طور که از ریاضیات دوران مدرسه به یاد داریم، اگر در معادله‌ای مقدار متغیر x را برابر عددی قرار می‌دادیم، تا انتهای معادله آن عدد تغییر نمی‌کرد. از این رو تمام متغیرها در زبان‌های تابعی تنها یک‌بار مقدار میگیرند (Single assignment) و به اصطلاح، تغییرناپذیر یا Immutable هستند.
دیگر ویژگی زبان‌های تابعی Referential Transparency است. به این صورت که همواره یک تابع با ورودی‌های یکسان، خروجی یکسانی تولید می‌کند، فارغ از شرایط و حالات محیطی. البته نداشتن عوارض جانبی (Side Effects) که می‌تواند باعث تغییر حالت محیط اجرا شود از طرفی و استفاده نکردن از Global Variables و Mutator Methods در توابع این زبان‌ها از طرف دیگر جزء پیش‌نیازهای این ویژگی است.
در ادامه خواهیم دید که تابعی بودن ارلنگ چگونه باعث به وجود آمدن هم‌زمانی در آن می‌شود.

هم‌زمانی (Concurrency)
یک سامانه هم‌زمان، دارای نرم‌افزاری است که در آن فرآیندهای مختلف نرم‌افزاری با بهره‌مندی از سخت‌افزاری با چندین پردازنده مرکزی یا چند هسته از یک پردازنده مرکزی بتوانند به صورت هم‌زمان اجرا شوند و حتی با هم ارتباط برقرار کنند. نوشتن چنین نرم‌افزاری همواره کار دشواری بوده است، زیرا برای مثال اگر دو فرآیند هم‌زمان بخواهند به یک قسمت از حافظه مشترک دسترسی پیدا کنند، امکان دارد Race Condition اتفاق بیافتد و برنامه به وضعیت غیرقابل انتظاری برود. با این حال راه‌حل‌های مختلفی برای این چالش وجود دارد، مانند استفاده از Mutex یا Semaphore در بعضی زبان‌ها.
زبان ارلنگ با استفاده از ویژگی‌های تابعی خود از طرفی و استفاده از مفاهیم Actor Model از طرف دیگر بر این چالش به نحوی کارآمد غلبه کرده است. به صورتی که هر فرآیند در زمان اجرا تنها به حافظه غیرقابل تغییر خود دسترسی دارد و در صورت نیاز برای ارتباط با یک فرآیند هم‌زمان دیگر برای او به صورت Asynchronous پیام می‌فرستد.

توزیع‌‌پذیری (Distribution)
یکی از تهدیدهای بزرگ برای سامانه‌هایی با میزان بار بالا، Single Point of Failure بودن است. به این صورت که اگر تمام وظایف پاسخ‌گویی به درخواست‌های کاربران برعهد‌ه سامانه‌ای با یک Node روی شبکه باشد، با از بین رفتن آن Node تمام سامانه به صورت غیرفعال درمی‌آید. از طرف دیگر در این حالت نمی‌توان با استفاده از Geolocation کاربر، آن را به نزدیک‌‌ترین Node فرستاد تا سریع‌تر به پاسخ خود برسد.
توزیع‌‌پذیری، پاسخی است به این گونه چالش‌ها. زبان ارلنگ با بهره گرفتن از ساختار توزیع‌‌پذیری در هسته اصلی خود، ما را قادر می‌سازد که سامانه خود را در Node‌ های مختلف شبکه نصب کنیم به صورتی که بتوانند با ارتباط با یکدیگر وظایف را بین خود تقسیم کرده و آن‌ها را انجام دهند.

خطا‌‌پذیری (Fault Tolerance)
شاید یکی از مهم‌‌‌ترین ویژگی‌های ارلنگ خطا‌پذیری آن باشد. این ویژگی را از دو جنبه می‌توان بررسی کرد. اولی خطا‌پذیری کل سامانه توزیع شده در Node‌ های مختلف است که نتیجه توزیع‌‌پذیری آن است. دیگری خطا‌پذیری درون یک Node است. به این صورت که یک سامانه خطاپذیر سامانه‌ای است که به هنگام رخداد خطا درقسمتی از آن، خطا را تحمل کرده و به زندگی خود ادامه می‌دهد، بدون رخداد Total Breakdown برای کل سامانه. زبان ارلنگ دارای فلسفه‌ای است با نام Let it Crash، به این مفهوم که در صورت رخداد خطا توسط یک فرآیند در زمان Run-­Time، آن را پذیرفته و بدون گرفتن و بررسی کردن آن، فرآیند خاطی را از بین می‌برد. البته فرآیندها در ارلنگ می‌توانند یکدیگر را نظارت کنند و از این رو فرآیندهای ناظر در صورت مرگ فرآیندهای خاطی، فرآیندهای جدیدی به وجود می‌آورند تا وظایف آن‌ها را انجام دهند.

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