Reactive programming: concept, training, features and expert advice

The principles of reactive programming are not new, and they can be traced back to the 70s and 80s in the fundamental works of Jim Gray and Pat Helland on the tandem system.

James Nicholas "Jim" Gray




These people are far ahead of their time. Only in the last 5-10 years, the technology industry was forced to revise the existing "best practices" for the development of the corporate system. She learned to apply knowledge of the reactive principles of today's world of multicore and cloud computing.

The basis for a reactive system is messaging, which creates a time line between components, allows them to be decoupled in time, using parallelism and space, which distributes the load and provides mobility. This decoupling is a requirement of complete isolation between the components and forms the basis for both stability and elasticity of systems.

Reactive Programming Basics

This programming focuses on the flow of information and the dissemination of data changes. When using programming languages, it is easy to distinguish between static and dynamic flows, while the basic model will automatically propagate changes through all data flows. In simple words, in Rx programming data streams emitted by one component, and the basic structure provided by Rx libraries will propagate these changes to another component registered to receive these changes. Rx reactive programming consists of three key points.





rx has three key points




The main functions of the components:

  1. Observables are nothing more than data streams. Observable packs data that can be transferred from one stream to another. They basically emit data periodically or only once in their configuration-based life cycle. There are various operators that can help the observer send some specific data based on certain events.
  2. Observers consume the data stream emitted by the observable. Observers subscribe using the subscribeOn () reactive programming method to obtain data that conveys the observables. Whenever an observable transmits data, all registered observers receive the data in the onNext () callback. Here they can perform various operations, such as parsing a JSON response or updating a user interface. If there is an error caused by the observable, the observer will receive it in onError ().
  3. Schedulers (schedule) is a component in Rx, which tells the observed and observers what flow they should work on. You can use the observOn () method to tell observers which thread they should be watching. In addition, schedOn () can be used to tell the observable in which thread they should be running.

In reactive programming using RxJava, basic default threads are provided, such as Schedulers.newThread () will create a new background. Schedulers.io () will execute the code in the input / output stream.





Advantages and limitations of the method

Advantages and limitations of the method




The main advantages of Rx are the increased use of computing resources on multi-core and multiprocessor equipment, increased productivity by reducing points and increasing productivity by reducing serialization points, according to Amdahl’s Law and Gunter's Universal scalability law.

The second advantage is high productivity for developers, since traditional programming paradigms have struggled to provide a simple and maintainable approach to working with asynchronous and non-blocking computing and IO. Functional reactive programming handles these tasks, since it usually eliminates the need for explicit coordination between active components.

Where Rx occurs, a component creation process and a workflow composition are created. To fully utilize asynchronous execution, enabling backpressure is critical to avoid overuse or, rather, unlimited resource consumption. In order to ensure a steady state in terms of data flow, back pressure based on the load sends demand flowing upstream and receives messages.

Thus, the main advantages of the system are:

  1. Increased productivity - thanks to the ability to quickly and stably process huge amounts of data.
  2. Improved UX - due to the fact that the application is more responsive to the user.
  3. Simplified modifications and updates - thanks to more readable and easier code prediction.

But despite the fact that Reactive Programming is a very useful thing when creating modern software, in order to talk about a system at a higher level, you need to use another tool - Reactive Architecture for the process of designing reactive systems. In addition, it is important to remember that there are many programming paradigms, and Rx is just one of them, like any tool, it is not intended for all use cases.

Stability of reactive systems

Stability is responsiveness to failure and is an integral functional property of the system. It needs development, and not just adding to the system in a retroactive form. The stability of javascript reactive programming goes beyond fault tolerance and this is not due to degradation, and if it fails, it can completely fix itself.

This requires isolation of components and containment of failures in order to avoid failures propagating to neighboring components, which can lead to catastrophic scenarios with cascading failures. Thus, the key to creating Resilient systems - self-healing - is that they can be characterized as messages sent to other components that act as supervisors and are managed from a secure context outside the failed component.

Here, being message-driven, these tools move away from tightly coupled, fragile, deeply nested synchronous call chains, which in most cases are ignored. The idea is to separate failure management from the call chain, for example, relieving the client of responsibility for handling server failures.

System Architecture Performance

System Architecture Performance




Because most systems are inherently complex, one of the most important aspects is to ensure that the system architecture minimizes performance both in design and maintenance, while minimizing random complexity to a minimum. This is important because during the life cycle of a system, if it is not designed properly, it will be harder and harder to maintain performance, and it will take more and more time and effort to understand to localize and fix problems.

Reactive systems represent the most productive system architecture in the context of multi-core, cloud and mobile architectures:

  1. Failure isolation offers bulkheads between components, preventing cascading failures and limiting the volume and extent of failures.
  2. Hierarchies of supervisors offer several levels of protection in combination with self-healing capabilities, which eliminates many temporary failures from any operational costs for investigation.
  3. Message skipping and location transparency allow you to disable and replace components without affecting the end-user experience. This reduces the cost of failures, their relative relevance, as well as the resources necessary for diagnosis and correction.
  4. Replication reduces the risk of data loss and reduces the impact of failure on the availability of information retrieval and storage.
  5. Elasticity allows you to conserve resources as usage fluctuates, which minimizes operating costs at low load and the risk of failures or urgent investments in scalability as the load increases.

Relation to traditional web applications

Relation to traditional web applications




Web applications can greatly benefit from the development style with Rx, which allows you to create request-response workflows, including forking service calls, asynchronously retrieving resources and compiling responses, and then sorting for the client. More recently, push-and-server events and web sockets have become increasingly used in practice, and to do this on a scale requires an effective way to store many open connections and where IO does not block.

There are tools for this, for example, Streams and Futures, which make non-blocking and asynchronous conversions simple, and push them to customers. Reactive programming with a data access level - updates and queries them in an efficient resource, preferably using SQL or NoSQL databases with asynchronous drivers.

Web applications also benefit from developing a responsive system for things like distributed caching, data consistency, and multi-node notifications. Traditional web applications typically use worthwhile sites. But as soon as programmers start using Server-Sent-Events (SSE) and WebSockets, these nodes become operational, because at least they maintain the state of the client connection, and push notifications are sent to them accordingly. This requires the development of a reactive system, as this is an area where recipient addressing through messaging is important.

The essence of reactive Java programming

It is not necessary to use Rx in reactive systems. Because Rx programming and reactive systems are not the same thing. Although they are often used interchangeably, they are not exact synonyms and reflect different things. Systems represent the next level of reactivity. This level implies specific design and architectural solutions that allow you to create sustainable and flexible applications.

Nevertheless, a very good idea - a combination of methods - brings even more benefits to applications, as it makes them even more connected, allows more efficient use of resources and provides lower latency. When it comes to huge amounts of data or multitasking, asynchronous processing is often needed to make systems fast and responsive.

In Java, the representative of the old object-oriented programming, asynchrony can become really complex and make code difficult to understand and maintain. Thus, Rx is especially useful for this “purely” object-oriented environment, as it simplifies working with asynchronous threads.

With its latest releases, starting with Java 8, Java itself has made some attempts to implement built-in reactivity, but these attempts are not very popular with developers today. However, there are some live and regularly updated third-party Java reactive programming implementations that help save you a day and are therefore especially appreciated by Java developers.

Kotlin: initial performance test

Kotlin: initial performance test




In a regular Android application, programmers usually repeatedly perform some reactive programming operations using RxJava, so you need to compare speed, processor and memory usage with the same operations that were implemented with both Kotlin coroutines and RxJava. This is an initial performance test.

Whenever a new tool is used that will be widely used throughout the code, it is important to understand whether it will affect the overall performance of the application before deciding how appropriate it is to use it. The usage practice gives a short answer: in most cases, users should consider replacing RxJava with Kotlin coroutines, especially in Android.

Reactive programming using RxJava can still be used in a limited number of cases, and in these cases, you can mix both RxJava and coroutines.

Simple reasons:

  1. Provide much more flexibility than ordinary Rx.
  2. Provides a rich set of statements in collections that look the same as with RxJava statements.
  3. Kotlin reactive programming can interact as needed using rxjava.
  4. They are very lightweight and efficient, given the higher level of CPU usage for garbage collection from all objects created by RxJava.

Reactive Extensions

Reactive Extensions (ReactiveX or RX) is a library that follows the principles of Rx, that is, compiling asynchronous and event-based programs using an observable sequence. These libraries provide many interfaces and methods that help developers write clean and simple code.

Reactive extensions are available in several languages. Programmers are especially interested in RxJava and RxAndroid, since android is the most focused area.

Reactive programming using RxJava is an implementation of the Java Reactive Extension from Netflix. This is basically a library that composes asynchronous events, following the observer pattern.

You can create asynchronous traffic, convert and consume them as an observer in different data streams. The library offers a wide range of amazing operators, such as map, union, and filter, that can be applied to the data stream. When a programmer begins to use actual code examples, he will learn more about operators and transformations.

Multithreading in Android Applications

Android "class =" if uuid-2938324 "src =" / misc / i / gallery / 73564 / 2938324.jpg "/>

Android reactive programming (RxAndroid) is specific to the Android platform with several classes added on top of RxJava. More specifically, schedulers are presented in RxAndroid (AndroidSchedulers.mainThread ()), which plays an important role in supporting the concept of multithreading in Android applications.

Among other things, experts advise using only the RxJava library. Even thanks to the large number of schedulers used in programming for Android.

Below is a list of planners and their summary:

  1. Schedulers.io () - used to perform non-intensive operations, such as network calls, reading disks / files, database operations, and which supports a thread pool.
  2. AndroidSchedulers.mainThread () - provides access to the main Thread / UI topic. Typically, operations occur in this thread, such as updating the user interface, interacting with the user. Specialists advise users that they should not perform any intensive operations on this thread, as this may cause an application to throw or ANR dialog.
  3. Schedulers.newThread () - using this, a new thread will be created every time a task is scheduled. It is usually suggested not to use a schedule for very lengthy work. Threads created with newThread () will not be reused.
  4. Schedulers.computation () - this chart can be used to perform intensive operations with the processor, processing huge data from a reactive programming center, processing raster images. The number of threads created using this scheduler depends entirely on the number of available CPU cores.
  5. Schedulers.single () - this scheduler will execute all tasks in the following order, which can be used when the need for sequential execution is required.
  6. Schedulers.immediate () - this scheduler executes the task immediately, synchronously blocking the main thread.
  7. Schedulers.trampoline () - performs tasks in First In-First Out mode. All scheduled tasks will be executed one after another, limiting the number of background threads to one.
  8. Schedulers.from () - allows you to create a scheduler from the executor, limiting the number of threads created. When the thread pool is busy, tasks will be queued.

Basic examples of RxJava

Now that you have a good theoretical knowledge of RxJava and RxAndroid, you can go to some code examples to better understand the concept. RxJava RxAndroid build.gradle .

.

Main steps




.

RxJava




Observer Observable, , :

  1. SubscribeOn (Schedulers.io ()) - Observable, .
  2. ObservOn (AndroidSchedulers.mainThread ()) - Observer Android.
Android




, RxJava.

Reactive, 2016 -2018 .

Rx , , DevOps, . «Cloud Native» . Java .




All Articles