Асинхронне програмування (АП) – це форма паралельного програмування, яка дозволяє структурної одиниці системи працювати окремо від основного потоку програми. Коли робота завершена, вона повідомляє основний потік про те, чи була робота завершена чи ні. Таке програмування вигідно, так як воно збільшує підтримувану пропускну спроможність, що робить її привабливою, враховуючи зростаючу потребу інтернету в системах з високою масштабованістю.
Моделі асинхронного програмування
Для того щоб обробити безперервність результату неблокирующих операцій після їх завершення, були створені різні моделі АП. Переваги їх оцінюються з точки зору того, наскільки вони дозволяють наблизитися до схеми, найбільш близькою до послідовної.
Типи моделей АП:
Архітектурні принципи Node
Незважаючи на те що останнім часом Node JS отримує різку критику щодо використання ним обчислювальних циклів з-за однопотокового середовища, його філософія, заснована на трьох сильних архітектурних принципах, залишається затребуваною.
JavaScript асинхронен за своєю природою, як і Node. Платформа для запуску серверного JavaScript Node.js була представлена в 2009 році з використанням асинхронної моделі вводу-виводу, керованої подіями, що робить її ефективною і масштабованої.
Чат є найбільш типовим прикладом багатокористувацького програми Node.js в реальному часі. Починаючи з IRC для багатьох пропрієтарних і відкритих протоколів на нестандартних портах, з’явилася можливість реалізовувати всі в сучасних Noje.js з WebSockets, які працюють за замовчуванням на тому ж порту 80, який прослуховує нові повідомлення, відправлені їх клієнтами. На стороні клієнта є HTML-сторінка з кількома налаштованими обробниками, одна для кнопки «Надіслати», що вибирає повідомлення і відправляє його в WebSocket, та інша, яка прослуховує повідомлення, що надходять на клієнт. Очевидно, що це проста і базова модель, але заснована на інший дисперсії складності.
Неактивна модель, яку Node JS використовує API для підтримки асинхронного програмування, є кроком до продовження. Кожна неблокирующая операція отримує функцію в якості останнього параметра, яка включає логіку продовження. Вона буде викликана після закінчення операції, як для обробки результатів у разі успіху, так і для усунення помилок. Функція продовження дозволяє вказати операції блокування, як вона повинна продовжуватися після завершення операції.
Управління послідовним потоком
Для того, щоб в рамках цієї моделі продовжити встановлення послідовних потоків виконання, необхідно об’єднати кожну наступну функцію в ланцюжок, як продовження попередньої, де результати будуть оброблятися в разі успіху або невдачі. Це призводить до диагонализации коду, який був названий пірамідою пекла (ад зворотного виклику), з-за відсутності практичної керованості, якщо тільки число послідовних ланцюжків зростає мінімально.
Розпаралелювання – асинхронне виконання неблокирующих операцій відбувається негайно, так як його простий виклик виконується у фоновому режимі за визначенням. Щоб перетворити блокуючі операції в неблокирующие, потрібно невеликий процес інкапсуляції, який запускає операцію у фоновому режимі.
Синхронізація функцій продовження
Вона вимагає ланцюжка в кінці кожної паралельної послідовності функції завершення, яка застосовує певну логіку тільки після того, як буде підтверджено, що всі паралельні гілки завершені. Для реалізації цієї перевірки використовуються діаграми на основі лічильників.
Приклад з допомогою продовжувачів:
Бібліотеки продовжувачів
Існує безліч бібліотек, які можуть допомогти полегшити життя розробникам, які працюють з моделлю АП. Деякі з них пов’язані не тільки з АП, але і з функціональною парадигмою, яка обумовлена тим фактом, що механізми впровадження сполук, по суті, є функціональними перевагами.
Види бібліотек:
Переваги і недоліки
Асинхронне програмування на основі продовжувачів хороший варіант для ситуацій з простою логікою управління потоком. Зазвичай це відноситься до програм в Node JS, які дозволяють визначати неблокуючий відповідь на вхідні запити.
Переваги моделі:
Недоліки:
Модель, керована подіями
Подія є сигналом бізнес-екосистемі. Анатомічно вони зазвичай складаються з типу, тимчасової мітки і набору даних, що характеризують контекст, в якому відбулася подія. Архітектура подій (EDA) забезпечує механізм зв’язку між клієнтами і постачальниками в відношеннях 1: N і з номінальною розв’язкою. Одне з багатьох його застосувань – усунення проблем асинхронної обробки даних.
У централізованих архітектурах, керованих подіями, існує центральна комунікаційна шина-посередник, яка відповідає за забезпечення ефективності процесу реєстрації прослуховуючих клієнтів і запуску повідомлень на вимогу постачальників до них. Цей механізм припускає потужність N:N, а схема називається шаблоном PUB/SUB.
В розподілених керованих подіями архітектурах кожен провайдер відповідає за керування підпискою своїх клієнтів і за відправку повідомлень, при виникненні події. Механізм зв’язку також номінально відокремлений, але зазвичай кількість провайдерів і клієнтів становить 1:N. Ця схема відповідає реальній схемі або джерелами подій в Node JS jargon.
Обчислювальна абстракція: Promise
Обіцянка – це обчислювальна абстракція, яка являє собою зобов’язання з боку неблокірующіх операції, викликаної для доставки відповіді викликає програмі, коли результат отримано після завершення. Обіцянка – це об’єкт, який надає два методи для включення логіки обробки у разі успіху або невдачі.
Вони відповідають простому життєвому циклу, який необхідно знати, щоб з ними можна було працювати. Істотна цінність обіцянки полягає в двох принципах. По-перше, логіка процесу в разі успіху або невдачі застосовується тільки один раз. І, по-друге, гарантується виконання логіки успіху або невдачі, навіть якщо обіцянку дозволено до того, як будуть введені його драйвери. Якщо буде потрібно, обіцянка чекає своїх обробників, асинхронного програмування JavaScript.
Є кілька способів отримати обіцянки, які можна ідентифікувати як шаблони побудови, які періодично з’являються при використанні цієї моделі. Визначення ES6 включає в себе обіцянки і Node JS версії 0.12 має підтримку цієї специфікації. Крім того, є кілька бібліотек, які реалізують модель обіцянок. Для того щоб мати порівняльну систему відліку, був визначений стандарт Promises A +, який управляє всіма реалізаціями з доступними на той момент об’єктами.
Синхронне та асинхронне програмування
Рекомендується використовувати АП JavaScript, завантаження для всіх тегів і коду постачальника з нього. Це забезпечує найкращу сумісність з найбільшою кількістю постачальників. Таке розміщення надає всім тегам постачальників найбільшу можливість завершити відстеження, перш ніж відвідувач перейде на наступну сторінку.
Синхронна завантаження відбувається, коли браузер повинен зупинити рендеринг сторінок, щоб завершити виконання коду JavaScript. Якщо він виявляє синхронний тег JS, то блокує відображення сторінки до завершення виконання коду. Це аналогічно тихоходному вантажівки на дорозі з однією смугою руху, який уповільнює рух за ним. Сучасні веб-сайти відійшли від цього методу, бо він представляє прямий ризик затримки часу завантаження сторінки.
Недоліком цього методу є те, що весь сайт блокується від початку до повного завантаження тега. І хоча постачальники тегів укладають угоди про рівень обслуговування протягом терміну їх доставки, на продуктивність можуть впливати кілька факторів. До них відносяться повільне час відгуку, пов’язане з постачальниками, ведення непотрібних серверів додатків в гібридну модель клієнт-сервер і повільний інтернет-трафік. Якщо користувач завантажує теги синхронно, рекомендується переконатися, що у постачальника час відгуку складає 100 мілісекунд (мс) або швидше.
Програмування синхронної і асинхронної обробки даних через API – це інтерфейси прикладного програмування, які повертають дані для запитів або відразу, або, відповідно, пізніше. Синхронні і асинхронні API надають спосіб робити негайні або заплановані запити ресурсів, даних або послуг, коли вони доступні. Сучасний метод, прийнятий для сайтів, полягає в асинхронної завантаженні тегів.
У цьому методі код JavaScript обробляється паралельно з іншим вмістом сторінки. Це означає, що навіть якщо тег постачальника повільно реагує або завантажується, він не буде сповільнювати роботу іншій частині сторінки. Використовуючи цей підхід, можна не тільки розділяти теги JavaScript, завантажувані незалежно один від одного, асинхронний метод мінімізує вплив завантаження зовнішніх файлів JS на процес рендеринга сторінок.
Розуміння і профілювання C #
Microsoft і спільнота .NET дуже спростили АП завдяки реалізації асинхронного очікування в C #. Останні версії ASP.NET активно використовують його для підвищення продуктивності. Багато інструменти для моніторингу продуктивності і профілювання намагаються підтримувати і візуалізувати продуктивність асинхронного програмування 1С. Продукти Stackify Prefix & Retrace мають відмінну підтримку додатків, що використовують C # async await. Для початку потрібно зрозуміти, як насправді працює-код, що використовує async awai” і HttpClient в якості прикладу.
Використовуючи ILSpy, можна побачити, як компілятор перетворює цей код у AsyncState Machine. Кінцевий автомат виконує весь складний код під прикриттям, що дозволяє розробникам, писати асинхронний код.
Профілювання асинхронного програмування в C 5 0 складним, тому що він перетинає потоки. Традиційно, метод і всі виклики його дочірніх методів відбуваються в одному потоці. Це полегшує розуміння відносин між батьківськими та дочірніми методами. З асинхронним кодом це зовсім інша історія. Батьківський метод запускається в одному потоці. Коли починається операція вводу-виводу, код в цьому потоці закінчується. Коли операція вводу-виводу завершується, код продовжує виконуватися в новому потоці. Зв’язати код між цими потоками, як частина більш великої транзакції, досить складно.
AIOHTTP: сервер-клієнт для asyncio
Aiohttp – дозволяє користувачам створювати асинхронні сервери і клієнти. Пакет асинхронного програмування aiohttp працює для клієнтських і серверних веб-сокетів. Документація з цього прикладу aiohttp використовується для захоплення HTML-сторінки.
У цьому прикладі показано, як завантажити один або декілька файлів, і також можна завантажувати файли через програму. У ньому зазначено кілька нових елементів, таких як asynctimeout. Це дозволяє створити менеджер контексту часу очікування. Внизу код створює асинхронний цикл синхронізації і використовує його в якості основної функції.
Створюють об’єкт Client Session у головній функції асинхронного програмування і coroutine, і функцію співпрограми, яка збирає URL все, що потрібно завантажити. Download у coroutine він створює менеджер контексту, який працює близько X секунд. Після закінчення цього кількості секунд X менеджер контексту закінчується. Далі використовують функцію get () сесії, яка знаходить об’єкт відповіді.
Коли розробник створює атрибут вмісту об’єкта відповіді, він повертає aiohttp. StreamReader, який дозволяє користувачеві завантажувати файл в будь-якому розмірі. Як тільки буде прочитаний файл, він буде записаний на локальний диск. Після чого використовують функцію response (), щоб завершити обробку відповіді. Згідно документації він неявно викликає release (). Тим не менш, асинхронне програмування Python явно краще. Краще залишити цю функцію, щоб запобігти подальші проблеми. Тут є один розділ, який блокує розділ код, записаний на диск, при цьому код залишається заблокованим. Використання aiohttp – реальний спосіб поліпшити робочий процес, де користувачам не потрібно витрачати час на створення сервера, завантаження посилань і написання асинхронних файлів, що скорочує час створення проекту.
Асинхронне програмування дозволяє досягти більшої ефективності в програмному забезпеченні, оскільки не блокується потік для виконання тривалих процесів або взаємодії з користувачем, як для розробки додатків для Node, так і для браузерів.