Основна концепция на Reactive programming
Дизайна на реактивни системи и реактивното програмиране са едни от технологичните катализатори, благодарение на които в последните години имаме възможност да работим с приложения, чието време за отговор е от порядъка на няколко мили секунди, а надеждността е 100 процентна. Принципите за реактивност са внедрени и използвани навсякъде – уеб и мобилни приложения и устройства, многоядрени процесори, облачно базирани клъстери и т.н.
Това е и една от темите, които ще бъдат засегнати на предстоящото събитие, организирано от DEV.BG – „Реактивно програмиране – основни принципи и проблеми при изграждането на съвременни софтуерни системи”, което ще се проведе на 17 януари от 19 часа.
За да бъде една система надеждна, не само от потребителска, но и от бизнес гледна точка, тя трябва да осигурява функциониране дори при евентуална повреда, както и при голямо натоварване. Реактивните системи имат амбициозната цел да удовлетворят тези условия.
Основните принципи на реактивните системи не са никак нови. Те мога да бъдат проследени назад до 70-те години, например в системата “Тандем”, а през последните няколко години с изключителното ускорение в развитието на технологиите, те се превръщат в ключов момент в развитието на облачните технологии, Internet of Things и въобще в технологичната индустрия.
Според дефиницията на Reactive Manifesto – една реактивна система представлява набор от принципи на архитектурен дизайн за изграждане на модерни системи, който е добре подготвен да посрещне нарастващите изисквания, които приложенията срещат днес.
С други думи – реактивната система е архитектурен стил, позволяващ множество индивидуални приложения да се обединят като един елемент, без да престават да са във връзка едно с друго.
Реактивните системи са:
Responsive: Реагират бързо към всички потребители, с цел осигуряването на постоянен позитивен потребителски опит, при различни условия. Възникналите проблеми могат да бъдат засечени бързо и отстранени ефективно. Фокусът е върху предоставяне на бързо и последователно време за отговор, така че качеството на услугата да бъде високо. Успешното им представяне изгражда доверие в крайния потребител и го насърчава за по-нататъшно взаимодействие със системата.
Resilient: Системата трябва да бъде гъвкава, като по този начин успява да функционира не само в идеални условия, но най-вече в условия от реалния свят. Представянето, устойчивостта и сигурността са части от гъвкавия модел. Системата е необходимо да бъде гъвкава на всички нива. Всяка система, която не е гъвкава, би била ненадеждна след повреда. Гъвкавостта се постига чрез репликиране, ограничаване, изолиране и делегиране. Повредите биват ограничени върху един компонент, изолирайки различните компоненти един от друг. Така частта от системата, в която има повреда, може да бъде възстановена без това да се отрази на системата като цяло. Възстановяването на всеки компонент е делегирано на друг и производителността се гарантира чрез репликация.
Elastic: Системата остава адекватно функционираща при различно натоварване. Реактивните системи могат да реагират на промени във входящия трафик. Те намаляват или увеличават разпределението на ресурсите. В дизайна им не са предвидени точки на съревнование, което ги прави способни да споделят и репликират компоненти и да разпространяват входящ трафик между тях. Еластичността се постига по икономичен начин, базиран на използвания хардуер и софтуерните платформи.
Message Driven: Реактивните системи се основават на асинхронно предаване на съобщения. Така се създава граница между различните компоненти, което осигурява свободно свързване, изолираност и прозрачност на местоположението. Експлицитното предаване на съобщения позволява управление на натоварването и потока данни, чрез оформяне и мониториране на опашка от съобщения в системата. Прозрачните съобщения, като начин на комуникация, правят възможна работата с конструкции и семантични данни дори при повреда, като по този начин улесняват отстраняването и.
Използването на конвенционалния подход в програмирането на реактивни системи и приложения не е особено ефективен. Не е възможно да се предвиди и контролира начинът на възникване на външни условия и събития, т.е когато външната среда се промени неочаквано. Не само това. Когато се случи промяна в състоянието на едно изчисление или данни, програмистът е необходимо ръчно да ъпдейтва всички други, които зависят от него. Този ръчен подход при промяна на състоянията и зависимост на данните, се оказва сложен за изпълнение и склонен към допускане на грешки.
Много полезна техника за имплементиране, която може да бъде използвана при системи с реактивна архитектура е:
Реактивното програмиране
Реактивното програмиране е програмиране с асинхронен поток на данни.
Потокът данни може да бъде използван за друг поток. Дори много потоци от данни може да бъдат използвани като вход към друг поток. Възможно е един поток да бъде филтриран, за да се създаде друг, който притежава само данните, които ни интересуват.
Асинхронен по дефиниция означава – не съществуващ или появяващ се в едно и също време. В контекста на програмирането се има предвид, че обработването на съобщения и събития се случва в някакво случайно време, възможно е и в бъдещо.
Тази техника позволява части от изпълнението, които се съревновават за споделени ресурси, не да чакат блокирани, а вместо това да извършат друга работа, докато ресурсът се освободи.
Реактивното програмиране въвежда представата за “поведение”, защото представя продължителна, променяща се с времето стойност и събития, като дискретни стойности.
Идеята е, че промените в състоянието автоматично и ефикасно се разпространяват в мрежата от зависими изчисления. Ето един прост пример:
var1 = 1
var2 = 2
var3 = var1 + var2
В конвенционалният императивен език за програмиране, var3 би имал стойността 3, определена от var1 и var2, в момента, в който са били дефинирани. Но в реактивното програмиране, стойността на var3 ще бъде автоматично ъпдейтвана при промяна в стойностите на var1 и var2. (var3 е зависима от var1 и var2).
Няколко примера за техники, които се поддържат в реактивното програмиране са:
- Futures/Promises – контейнери за единична стойност, където асинхронни трансформации на стойността могат да бъдат добавени, дори ако все още не са налични;
- Streams – неограничени потоци от обработка на данни;
- Dataflow variables – единични дефинирани променливи (клетки памет), които може да зависят от входни данни, процедури или други клетки, така че те са автоматично обновени при промяна;
Библиотеки в реактивното програмиране
Една спецификация за библиотеки в реактивното програмиране е reactive stream. Идеята е да се намери минималният набор от интерфейси, методи и протоколи, който описва необходимите операции за постигане на целта – асинхронни потоци от данни с non-blocking back pressure.
Някои от библиотеките, които осигуряват имплементацията на reactive stream са:
- Reactor – реактивна библиотека за изграждане на приложения върху Java Virtual Machine. Библиотека на ниско ниво, даваща възможност да се използват отдалечени ресурси като локални;
- RxJava – библиотека развита от Netflix, осигуряваща адаптер наречен rxjava-reactive-streams;
- Akka – използва модул наречен Akka Stream за имплементация;
Ползата от реактивния подход в програмирането
Основните ползи от реактивното програмиране са намаляване използването на изчислителни ресурси в многоядрения и мултипроцесорния хардуер.
Освен тях, чрез реактивният подход се премахва необходимостта от експлицитно координиране между активните компоненти на една система.
Съществените ползи за потребителя се състоят и стават видими в модерните уеб и мобилни приложения. Те са с високо ниво на интерактивност с множество интерфейси, свързани с различни събития. Преди десетина години взаимодействието с една уеб страница основно се състоеше в попълване на заявка за зареждане и като отговор – зареждане на страницата.
Днешните приложения притежават изобилие на събития от всякакъв вид, случващи се в реално време и позволяващи на потребителя да взаимодейства с тях. Инструментите, необходими за успешното осъществяване на такъв подход са базирани на реактивното програмиране.
Вероятно най-трудната част в изучаването на реактивните системи и програмиране е научаването да се мисли по реактивен начин. Става въпрос за освобождаване от старите норми на императивни и не променящи се навици на типичното програмиране и позволяване на развитието на едно ново, различно мислене в програмирането.
Най-ползотворно би било комбинирането на техниките на реактивното програмиране с принципите в дизайна на реактивните системи.
Стани част по потребителската група Reactive Programming. Абонирай се и ще ти изпращаме информация за всичко, което предстои в групата.
Автор: Десислава Танева
Визия: pexels.com
Прочети още:
6 от най-популярните Machine Learning алгоритми – приложения и възможности
Умен дом с openHAB и Eclipse SmartHome. Интервю с Димитър Иванов