نگاهی به امروز و فردای WebAssembly

توی این مطلب سعی‌ می‌کنم یه نگاه نسبتا عمیق به وضعیت الان WebAssembly و فردای اون داشته باشم. درواقع یک جمع بندی از وضعیت فعلیش و همچنین چیزایی که خودتون در آینده بیشتر دنبالش کنید.

چی هست؟

وب اسمبلی یک زبان بهینه و سطح پایین به صورت Bytecode برای وب هست که توی یک ماشین مجازی اجرا می‌شه (با اون ویرچوال باکس که خیلی‌ها شنیدیم فرق می‌کنه اون رو از ذهنتون پاک کنید).

فرض کنیم 0x6a یک دستور بایت‌کد در این زبان هست که معادل متنی اون می‌شه add (تابع جمع). حالا شما این امکان رو دارید که به زبان‌های مختلف (Rust, Go, C, CPP ...) کد بنویسید و اون رو تبدیل کنید به WASM (بخونید وزم - مخفف وب اسمبلی).

مثلا شما می‌نویسید:

int sum = 1+2;

و مثلا تبدیل می‌شه به:

0x6a 0x01 0x02

این قالبی هست که WASM داره و کدی که شما نوشتید «کامپایل می‌شه» بهش که مرورگر اون رو می‌فهمه و اجرا می‌کنه. اگه مطلب قبلی من رو خونده باشید و یا با JIT آشنایی دارید (اگه ندارید اینجا رو بخونید) فوری مشخص می‌شه که وقتی یک کد از قبل کامپایل شده باشه دیگه مرورگر نیاز نداره خروجی اون رو «حدس بزنه» و کلی ژانگولر انجام بده در نتیجه سرعت اجرای WASM بسیار بالا تره.

آیا وب اسمبلی از جاوا اسکریپت سریع تره؟

خب اره، ولی آیا همچین مقایسه‌ای درسته؟ بذارید اینطوری بهتون بگم:

یه آزادراه رو در نظر بگیرید که دوتا ماشین دارن توش حرکت می‌کنن؛ یکی شون پول عوارضی رو آنلاین پرداخت کرده و دیگه نیاز نیست همش وایسه و پول بده اما اون یکی باید دم هر عوارضی توقف کامل کنه و پول بده ...

ماشین اول، در تمام سفر با نهایت سرعتی که توی آزادراه مجاز هست حرکت می‌کنه ولی ماشین دوم «گاهی وقت‌ها» به نهایت سرعت مجاز می‌رسه و بعد باید توقف کنه و ...

مراحل کامپایل و اجرا شدن جاوا اسکریپت
مراحل کامپایل و اجرا شدن جاوا اسکریپت

درواقع وب اسمبلی چون کامپایل می‌شه با «نهایت سرعت» و «کارایی» قابل ارائه توسط محیطی که در اون اجرا می‌شه (در اینجا مرورگر) کار می‌کنه اما جاوا اسکریپت چون باید از JIT رد بشه «ممکنه» به سرعت نهایی برسه ولی خیلی وقت‌ها این اتفاق ممکن نیست.

مراحل کامپایل و اجرا شدن وب اسمبلی
مراحل کامپایل و اجرا شدن وب اسمبلی

همونطور که می‌بینید مرحله Parse کردن حذف شده، درواقع جاوا اسکریپت باید یکبار به AST تبدیل بشه و بعد اون رو تبدیل کنن به بایت‌کد که بعد توسط مرورگر کامپایل و بهینه سازی بشه ... ولی این مرحله توی وب اسمبلی نیاز نیست چون خودش یکبار کامپایل شده و به صورت بایت‌کد به مرورگر ارائه می‌شه. مرورگر فقط نیاز داره اون رو decode کنه که خیلی سریعتر و راحت تر از Parse کردن هست.

بعلاوه چون این کد فشرده شده دریافت کردنش هم (یعنی دانلود اون توسط مرورگر) خیلی سریعتر از جاوا اسکریپت اتفاق می‌افته. هرچند مثلا gzip کردن جاوا اسکریپت حجم فایل رو کاهش می‌ده ولیکن خب gzip کردن وب اسمبلی هم حجمش رو «بیشتر» کاهش می‌ده ...

یه مرحله دیگه توی JIT هست تحت عنوان Reoptimization. یعنی بر اساس کدی که بهینه شده باید درباره «قدم‌های بعدی» اون همزمان با اجرا؛ تصمیم گرفت. فرض کنید 100 تا Object دارین که 99 تاش بهینه شدن ولی موقع اجرا مشخص می‌شه که Object آخر بهینه نیست. اینجا اون «انتظار» که از اجرای کد داشتیم براورده نشده و دوباره باید بهینه سازی انجام بشه ... که این مرحله توی WASM نیاز نیست.

پس، بله! وب اسمبلی سریع تره ولی دوتا ماشینه رو یادتونه؟ حالا فرض کنید اونی که سریع ترین سرعت رو داره مسیر رو بلد نیست ولی اونی که سرعتش کمتره بلده از یه راه کوتاه‌تر بره و مجبور نیست کل آزادراه رو طی کنه.

یعنی چی؟ خب ببینید یه چیزی مثل DOM Manipulation درحال حاضر توی وب اسمبلی کندتره چون API اون بهینه نشده... (ولی روش کار می‌شه) پس قرار نیست یک شبه جای جاوا اسکریپت رو بگیره. اما توی خیلی از زمینه‌ها مشکلات و محدودیت‌هایی که جاوا اسکریپت داره رو برطرف می‌کنه و ویژگی‌های قابل توجه‌ای به وب اضافه می‌کنه - اینم بگم، خیلی وقتها لازمه از دنیای جاوا اسکریپت بریم توی دنیای WASM و برگردیم، قبلا این عملیات خیلی کند بود ولی الان سریع شده.

مثلا وب اسمبلی برای بازی کردن توی مرورگر خیلی خوبه یا حتی شرکت ادوبی محصول Lightroom رو با وب اسمبلی نوشته تا توی مرورگر قابل استفاده باشه. همه اینها باعث می‌شن که بهش به عنوان یک زبان جدید برای وب نگاه کنیم ... (این ویدیو هم ببینید)

آیا می‌تونیم جاوا اسکریپت رو به وب اسمبلی تبدیل کنیم؟

نه، جاوا اسکریپت خیلی زبان داینامیک و پیچیده‌ای هست. وب اسمبلی بایت کدی تولید می‌کنه که نوع داده‌ها توی اون استاتیک هستن بعلاوه توی وب اسمبلی هنوز Garbage Collection پیاده سازی نشده و باید خودتون مدیریت حافظه رو در دست بگیرید.

تایپ اسکریپت «شاید» در آینده به طور رسمی به وب اسمبلی کامپایل بشه چون به نظر می‌رسه تایپ‌هاش رو اضافه کردن. اما خب یه پروژه دیگه هست به اسم AssemblyScript که دقیقا کارش همینه (ولی یه تیم جداست).

شکل دستورات

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

(module
   (memory $0 0)
   (table $0 1 funcref)
   (export "memory" (memory $0))
)

این چیه؟ چرا این شکلیه؟ -- این قطعه کد یک «بیان متنی» از بایت کدهای وب اسمبلی هست. که تحت عنوان WAST شناخته می‌شه. اگه فکر می‌کنید شبیه Lua هست کاملا درسته چون به این شکل از نوشتن میگن S-expressions که توسط زبان Lua ابداع شده.

این شکل از نوشتن، به اندازه کافی انتزاعی هست که یک انسان بتونه بخونه و بنویسه و در عین حال یک ماشین با کمترین هزینه ترجمه کنه (بیشتر بخونید). شما می‌تونید به جای Rust یا Go مستقیم توی WAST کد بزنید و کامپایل کنید به WASM. این کار رو کسی نمی‌کنه بجز کسانی که می‌خوان به خود وب اسمبلی یه چیزی اضافه کنن. چون، همه چیز سطح پایین و در کنترل شماست و تقریبا چیزی جلودار خرابکاری‌ها نیست.

هرچند اگر، تمایل به نوشتن WAST دارین باید حتما درمورد Stack-oriented programming و Stack machine اطلاعات زیادی داشته باشید. چون وب اسمبلی جز زبان‌های پیرو Stack machine هست.

حالا که می‌دونید WAST چیه؛ بیاید 1 رو با 2 جمع بزنیم تا بهتون نشون بدم «پیرو استک ماشین» بودن یعنی چی:

(i32.add
   (i32.const 1)
   (i32.const 2)
)

این بیان متنی همون بایت کد (0x6a 0x01 0x02) مربوط به عمل جمع هست که توی استک به این شکل هست:

اجرای دستور جمع در Stack
اجرای دستور جمع در Stack

البته این یه مثال فرضی هست، کامپایلر هیچوقت برای مقادیر ثابت مثل 1 و 2 استک در نظر نمی‌گیره چون خروجی همون لحظه می‌تونه تشخیص داده بشه که 3 هست ... ولی منظور من اینه که دقیقا مثل یک استک دستورات Push و Pop می‌شه پس شما «باید» بلد باشین با «کمترین» حرکت ممکن دستور یا عملیات خاصی رو پیاده سازی کنید.

امیدوارم الان متوجه شده باشید که چرا مقایسه کردنش با جاوا اسکریپت از یک جنبه سطحی (مثل سرعت) معقول نیست.

ویژگی‌های اصلی و فرعی

چهار رکن اصلی WASM
چهار رکن اصلی WASM

تا اینجا فهمیدیم که یک زبان مثل اسمبلی هست، پس می‌شه باهاش برنامه‌های دسکتاپ رو کامپایل کرد به چیزی مثل x86 و توی «یک محیط» اجرا کرد (1). و اینکه حجمش بسیار کمه برای همین انتقال دادن میزان زیادی از کد توی وب راحت انجام می‌شه‌ (2) و درمورد نحوه اجرای دستورات صحبت شد که نشون دادم چرا سریعه (3) ...

اما، ما که نمیتونیم یه برنامه‌ای رو از وب دانلود کنیم و بهش اجازه بدیم از تمام حافظه استفاده کنه. برای همین مدیریت حافظه توی وب اسمبلی به صورت خطی انجام می‌شه. درواقع وب اسمبلی می‌ره یک بخشی از حافظه سیستم رو «اجاره» می‌کنه و بعد اون رو به شکل یک آرایه در اختیار برنامه‌ها قرار می‌ده. اینطوری یک برنامه نمی‌تونه از اون فضا خارج بشه.(4)

این فقط «شروع راه» بود! خیلی ویژگی دیگه داره اضافه می‌شه و یا به مرحله‌ای رسیده که علاقه منداش می‌تونن استفاده کنن.

مثلا پشتیبانی از multithreading، به مرحله چهار از پیاده سازی رسیده (شیش مرحله داریم از 0 تا 5، مرحله پنجم دیگه تمیز کاری نهایی و پذیرفته شدن کامل اون ویژگی هست). درواقع multithreading این امکان رو داره که فعالیت‌های مختلف یک برنامه رو به بخش‌های کوچیک تقسیم کنیم و بعد به صورت همزمان انجام بشن تا خیلی خیلی سریعتر اون فعالیت به اتمام برسه.

یا مثلا پشتیبانی از SIMD که خیلی ساده بگم؛ شما مثلا یه عملیات دارین که «ممکنه» 64 بیتی باشه پس به اندازه یک عملیات 64 بیتی حافظه رزرو می‌کنید. اما اون مجموعه از داده‌ها که عملیات روش انجام می‌شه «ممکنه» همش 64 بیتی نباشه مثلا شاید دوتا 32 بیتی داری. خب اگه یکی یکی انجامش بدی هر بار 32 بیت از حافظه اضافه میاد که الکی رزرو شده. برای همین اگه اون عملیات رو همزمان روی هردوتاشون انجام بدی اینطوری هم از حافظه به خوبی استفاده کردی و هم سرعت پردازش بالا میره. (یه ویدیو جالب).

از جهت «بهینه شدن کد و اجرای سریعتر» هم راه‌ حل‌های جالبی ارائه شده مثل Streaming compilation و Tiering compiler که یعنی به محض رسیدن یک قسمت از کد به کامپیوتر؛ همزمان یه مرحله کامپایل می‌شه.

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

قابلیت Implicit HTTP caching هم خیلی جالبه یعنی یک بار که کد کامپایل و بهینه شد دیگه همون نسخه رو می‌تونی اجرا کنی و نیاز به کامپایل و بهینه سازی مجدد نیست. (و کلی ویژگی باحال دیگه مثل Garbage Collection و Exception Handeling و Debuging که اینجا می‌تونید بخونید.)

پس؛ با وجود این همه ارکان فرعی که درحال اضافه شدنه یه بحث جذاب شکل گرفته و اونم استفاده از وب اسمبلی در بیرون از وب هست برای IoT یا پردازش ابری و ...

وب اسمبلی بیرون از وب

چرا بالا تر گفتم «محیط اجرا» و مستقیم نگفتم مرورگر؟ به خاطر اینکه؛ در هیچ کجا ذکر نشده که «باید حتما مرورگر باشه» و بلکه فکرهایی شده برای اینکه خارج از مرورگر هم بشه از وب اسمبلی استفاده کرد.

اما به چه درد می‌خوره؟ خب همیشه وقتی به وب فکر می‌کنیم یاد HTML CSS JS میوفتیم اینها «کدهای یه نفر دیگه» هستن که ما «یه راهی پیدا کردیم که با خیال راحت اجراش کنیم». مثلا فرض کنید جاوا اسکریپت به همه سیستم دسترسی داشت و یه کتابخانه معروف مثل React می‌تونست بعدا یه کد مخرب به آپدیت جدیدش اضافه کنه و همه وبسایت‌ها آلوده می‌شدن ...

می‌دونم الان با اخم به پاراگراف نگاه می‌کنید. خب React که متن بازه همه می‌تونن سورسش رو ببینن. آره؛ اما آیا همه وب متن بازه؟ همه وب قابل اعتماده؟ یا حتی اون قسمت‌هایی که متن باز هستن اگه یه روزی شیطنت کنن ما «بلافاصله» می‌فهمیم؟ یا بعد چند روز/ماه که گندش در اومد؟

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

یه موضوع دیگه Portability هست. الان وبسایت‌ها فارغ از اینکه بدونن معماری پردازنده شما چیه کد جاوا اسکریپت می‌نویسن و اجرا می‌شه چون مرورگر سکوی اجراست و اون تشخیص می‌ده.

دقیقا NodeJS هم هدفش این بود دیگه که جاوا اسکریپت رو بتونی خارج از مرورگر هم اجرا کنی... اما حتی اونجا هم مجبوری یه ماژول CPP بنویسی اگه سرعت بالا می‌خوای.

خب، وقتی بتونیم ایمنی رو با Sandbox ارائه کنیم و Portability در کنارش باشه نتیجه اینه که می‌تونیم بدون نیاز به کانتینر؛ فضای اجرای یک قطعه کد رو محدود کنیم و کدهای بیشتری رو در زبون‌های مختلف روی یک ماشین اجرا کنیم. کجا این قضیه به درد می‌خوره؟ خب معلومه توی FaaS.

بعلاوه ماهیت وب اسمبلی طوریه که واقعا به زبان ماشین خیلی نزدیکه؛ در نتیجه اگه بشه روی دستگاه‌های IoT ازش استفاده کنیم عملا این امکان رو داریم که با پایتون و تایپ اسکریپت و خیلی زبون‌های دیگه شروع کنیم به برنامه نویسی روی اونها دیگه بازارش محدود نیست به زبان C و پیچیدگی‌های آنچنانی از بین میره.

روند اجرا بیرون از مرورگر چطوریه؟

روی خیلی از سیستم‌ها یک زبان برنامه نویسی به طور مستقیم به شبکه، حافظه، سیستم‌فایل و غیره دسترسی نداره. چرا؟ چون اگه برنامه‌ها حق داشته باشن آزادانه از تمام منابع استفاده کنن بالاخره چه عمدی یا غیر عمدی سو استفاده رخ می‌ده.

حالا سیستم‌عامل یک سری توابع تحت عنوان System Call ارائه می‌کنه و هر قطعه کدی که به منابع سیستم نیاز داشته باشه باید اون توابع رو صدا بزنه و از اونها درخواست کنه.

اصطلاحا به این میگن یک برنامه user space که توی حلقه 3 اجرا می‌شه. درواقع سیستم‌عامل یک سری حلقه امنیتی داره و بحث ما مربوط میشه به حلقه سوم.

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

اما چرا این حرکت لازم نیست؟ به خاطر اینکه اکثر زبون‌های برنامه نویسی خیلی چیزا رو به صورت انتزاعی پیاده می‌کنن (مثلا تابع خواندن از فایل رو توی کتابخانه استاندارد خودشون به برنامه نویس ارائه میدن) بعدش در لحظه کامپایل بر اساس سیستم هدف؛ system call های مورد نیاز رو جایگزین اون لایه انتزاعی می‌کنن و پورتابل شدن از این رویه میاد.

اما وب اسمبلی برای یک ماشین فرضی کد تولید می‌کنه یعنی درواقع نمی‌دونه معماری و سیستم‌عامل حاضر روی ماشین چیه.

بنابراین همچین اتفاقی میوفته:

شما کدتون رو توی یکی از زبانهایی که وب اسمبلی پشتیبانی می‌کنه می‌نویسید. بعد یک «تفسیر» از اون کد تولید می‌شه که کامپایلر وب اسمبلی از اون استفاده می‌کنه تا با دیتا تایپ‌های خودش تطابق بده و بایت‌کد تولید کنه. مثلا چیزی تحت عنوان Struct توی وب اسمبلی نیست این باید تبدیل بشه به چی؟ کار IR تفسیر همچین شرایطی هست.

توی فضای وب، مرورگر می‌شه runtime وب اسمبلی و مسئول تبدیل بایت‌کد WASM به کد ماشین (پس اینطوری پورتابل می‌شه).

بعدش یک سری system call در اختیار وب اسمبلی قرار می‌ده و اونهم بر اساس نیازهای برنامه درحال اجرا اون توابع رو در اختیار برنامه قرار می‌ده. (اینطوری ایمنی به شکل Sandbox پیاده می‌شه).

به همین جهت بیرون از وب هم به یک runtime نیاز داریم که دوتا از معروف ترین هاش WAVM و Wasmtime هستن.

اما یه سوال دیگه، بیرون مرورگر کی قراره شرایط Sandbox رو دیکته کنه؟ کی قراره به ما بگه کدوم syscallها رو در اختیار داریم و کدوما رو نداریم؟

رابط بین وب اسمبلی و سیستم میزبان

وزی (WASI) یا همون رابط بین وب اسمبلی و سیستم میزبان یک سری قرارداد هستن که هر runtime باید اونها رو پیاده کنه و Sandboxing از این طریق به برنامه‌های درحال اجرا دیکته می‌شن.

توی حالت عادی برنامه‌ها مسیری که نیاز دارن رو به صورت یک رشته به سیستم عامل می‌دن و بعد سیستم عامل چک می‌کنه که آیا کاربری که این برنامه رو اجرا می‌کنه دسترسی داره به اون مسیر یا نه؟ و چون رشته هست، عملا وقتی دسترسی بهت داد می‌تونی فراتر از اونهم پیش بری.

ولی مستندات WASI اینطوری تعریف شده که، سیستم میزبان یک مسیر رو در اختیار runtime قرار می‌ده بعد وقتی برنامه درحال اجرا درخواست می‌کنه که از مسیر x فایل y رو بهم بده، بهش یک file descriptor برگشت می‌ده. یعنی برنامه دیگه فقط حق داره روی فایل y عملیات انجام بده و «اگر» نیاز شد می‌تونه بقیه مسیر x رو طی کنه. اما نمی‌تونه فراتر از x بره.

همچنین این سطح دسترسی «از برنامه به برنامه دیگه» فرق می‌کنه و یکسان نیست. همه برنامه‌ها به طور پیشفرض به کل مسیر x دسترسی ندارن.

این تعاریف ماژول بندی شدن؛ فعلا بحث‌های سیستم‌فایل و شبکه و غیره توی wasi-core قرار گرفته و این سیستم ماژول بندی باعث می‌شه که بعدا افراد جامعه کاربری ماژول‌های خودشون رو توسعه بدن

مثلا خیلی چیزا توی wasi-core داره استاندارد‌های POSIX رو دنبال می‌کنه و چیزایی مثل read,open,close توش پیاده سازی شدن اما بحثی مثل fork واقعا پیچیده هست و نمی‌شه همون مسیر POSIX رو دنبال کرد و در عین حال، به خاطر ماژولار بودن این روال؛ شانس «استاندارد سازی» fork هست و بعدا می‌تونه به عنوان یک ماژول جدا اضافه بشه.

برای یک زبونی مثل Rust خودش مستقیم این توابع رو توی اون لایه انتزاعی صدا می‌زنه ولی برای زبون‌های دیگه مثل c و cpp کتابخانه wasi-libc وجود داره.

مثلا Rust توی اون لایه انتزاعی یه شرط گذاشته که «اگه قرار بود به WASM کامپایل بشی، باید از wasi syscalls استفاده کنی» زبون‌های دیگه مثل python می‌تونن از اون کتابخانه wasi-libc استفاده کنن و کتابخانه‌های بومی اون زبان رو تولید کنن.

حالا پورتابل بودن در کنار امنیت برقرار می‌شه و همزمان «تعریف امنیت» بین هر runtime می‌تونه متفاوت باشه مثلا node یک سری دسترسی بیشتر بده ولی firefox کمتر و همون کد (با سطح دسترسی‌های متفاوت) روی جفتشون اجرا می‌شه ...

درست مثل ویژگی‌های فرعی که کم کم اضافه می‌شه؛ یک سری ماژول فرعی هم مثل asynchronous I/O یا file watching و غیره اضافه می‌شن و به مرور دنیای بیرون از مرورگر هم بهتر و بهتر می‌شه.

پاسخ به سوالات توییتر

+ الان blazor بیاد استقبال میشه ازش؟

خب، موسی به دین خود. عیسی به دین خود!. محصولات مایکروسافت همیشه پیروان دو آتیشه خودش رو داره پس در زنده موندن blazor شکی نیست؛ اما وب اسمبلی توی زمینه‌های بزرگتری فعالیت می‌کنه بنابر این اگه بخوایم کلاس بندی کنیم میشه رقیب blazor در زمینه وب. یا میشه رقیب Firecracker در زمینه FaaS. هیچوقت کاملا جایگزینش نمیشه.

+ آیا آینده‌ای داره، یا مثل سیلور لایت زود آفتابش غروب میکنه؟

بله، اینده خیلی خوبی داره و نه! مثل سیلور لایت سرش نمیاد. بالا تر گفتم باید وب اسمبلی رو کلاس بندی کنیم؛ پس اگه در زمینه وب شکست بخوره در زمینه‌های دیگه آینده داره ...

تو Back-End هم استفاده می‌شه؟

نه به شکلی که NodeJS حضور داره بلکه در مقیاس بزرگتر. مثلا بازار سرویس‌های PaaS کمرنگ می‌شه و ظهور و فعالیت سرویس‌های FaaS پررنگ تر.

بیاید به سرویس فندق (لیارا/اروان) نگاه کنیم؛ چه چیزی باعث می‌شه فندق هزینه‌اش زیاد بشه؟ خب؛ یه سری بحث مثل لود بالانسر یا پشتیبانی و فایروال و غیره هست که توی IaaS هم وجود داره پس این فاکتور‌ها رو نمی‌تونیم دستکاری کنیم.

ولی آیا می‌تونیم با یه نرخ معقول «کانتینر بیشتر بسازیم»؟ الان فندق مثل اینه که یه زمین رو اجاره کرده و روش یه هتل ساخته و داره اتاق‌هاش رو کرایه می‌ده .. من نمی‌تونم «نصف یک اتاق» رو اجاره کنم یا «یه اتاق و نیم» رو اجاره کنم درسته؟

این باعث می‌شه که اتاق‌هایی با اندازه مشخص اجاره بده و حتی اگه مهمان بین ساعت 7صبح تا 4 ظهر توی اتاقش نیست اون نمیتونه به کس دیگه اجاره بده؛ چمدون‌هاش توی اتاقه (همون registry).

پس متوجه می‌شیم که هدف PaaS «سهولت در توزیع/انتشار یک محصول» هست ولی لزوما در «کاهش هزینه» موثر نیست.

یه ذره عمقی‌تر صحبت کنم؛ توی شرایط داکر، فهمیدن اینکه «کی چقدر منابع مصرف کرده» سخته و راه آسون تر اینه که بگیم تو 8 گیگ رم داری و 4 هسته پردازنده؛ قیمت اجارش می‌شه اینقدر ...

یه ذره منطقی‌تر اینه که اجاره رو روزانه حساب کنیم و مشتری هر لحظه بتونه منابع رو گسترش بده. تا اینطوری از کم شروع کنه و بعد پله پله زیاد کنه؛ یا اگه جمع کرد فقط تا اون روزی که استفاده داشته پول بده.

اما وقتی مشتری فندق زیاد می‌شه نمی‌تونه روی همون زمین بازم اتاق هتل بسازه باید بره زمین بیشتر اجاره کنه ...

از این طرف FaaS بحث‌های لود بالانسر و فایروال و غیره رو داره و در عین حال می‌تونی به اندازه‌ای که کدت از cycle‌های پردازنده و باقی متریک‌ها استفاده کرده پول بدی. و وقتی کدت اجرا نمیشه‌ همزمان یه نفر دیگه از منابع می‌تونه استفاده کنه.

استخراج این متریک‌ها از وب اسمبلی کاملا ممکن هست، بعلاوه سبک بودن runtime اون در کنار قوانین WASI و پورتابل بودنش بهش این امکان رو می‌ده که کدهای «هر زبانی» خیلی «سریع» و «بدون ایجاد تداخل برای کد‌های دیگه» اجرا بشن.

شرکتی مثل fastly کاملا از این موقعیت سود می‌بره. چرا؟ خب اونها کلی سرور سراسر دنیا دارن که باید به صورت عادی ترافیک زیادی رو تحمل کنه؛ فایروال و لود بالانسر و بقیه چیز‌ها هم که وجود داره. این‌ها اومدن runtime خودشون رو توسعه دادن که بتونن سرویس FaaS ارائه بدن روی سرورهاشون و انقدر سریعه که بر اساس هر درخواست یک sandbox بالا میارن (فکر کنم در حدود 60 نانو ثانیه طول می‌کشه تا هر sandbox بالا بیاد).

البته، قصد من از این مقایسه نادیده گرفتن زحمات فندق یا بقیه نیست. به این اشاره می‌کنم که خیلی از فرایند‌های stateless رو میشه با هزینه کمتر اجرا کرد. و اینم بگم PaaS به کلی از بین نمیره مثلا یه برنامه موبایلی رو در نظر بگیرید که نیاز داره محاسبات خاصی انجام بده و نتیجه رو ذخیره کنه. در اینجا زیرساخت پایگاه داده رو می‌تونم ببرم روی PaaS و اون تابع رو ببرم روی FaaS.

کلام پایانی

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

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

منابع (بیشترش حول صحبت های Lin Clark هست) :

"Isolation without Containers" by Tyler McMullen
Rust, WebAssembly, and the future of Serverless (DevFest 2019)
Bringing WebAssembly outside the web with WASI by Lin Clark
GOTO 2018 • A Cartoon Quest: New Adventures for WebAssembly • Lin Clark
WebAssembly Demystified
WebAssembly Articles