Reative programming is different of reactive systems. Reactive programming focusing on computation through ephemeral dataflow chains—tend to be event-driven, while reactive systems—focusing on resilience and elasticity through the communication, and coordination, of distributed systems—is message-driven. Some concepts about reactive programming
- Event Driven: Publish and subscribe
- Data Streams: All works with data Streams
- Asynchronous
- Non-blocking
- Back pressure: when the progress of turning that input to output is resisted in some way. In most cases that resistance is computational speed or TPS Control. By the way, you might eventually hear someone use the word “backpressure” to actually mean something has the ability to control or handle backpressure.
- Functional/Declarative programming: different paradigm, pure functions, immutability, lambdas, etc
Observables (who publish events) can be cold or hot
- Cold: The lazy ones. Obervables only start publish events when anyone subscribe to this observable.
- Hot: The hard workers. Observables publish events, with or without subscribers. An example can be obervable who do lecture of temperature, that publish events every scheduled time.
Is a definition and rules to define reactive programming. Reactive Streams is an initiative to provide a standard for asynchronous stream processing with non-blocking back pressure:
- Process a pontentially unbounded number of elements
- Sequencially and asynchronously passing elements beetwen components
- And with mandatory non-blocking backpressure
In this definition, we have 4 interfaces:
- Publisher (or observable)
- Subscriber: Who read events
- Subscription: contract within publisher and subscriber - manage the backpressure
- Processor: Processing data state https://www.reactive-streams.org/
Flow (Cold way):
- Subcriber subscribe on publisher
- Result of this, subcription is create.
- Publisher receive notification
onSubscribe
method. - Subscriber requests N elements (backpressure) using subscription
- Publisher publish ->
onNext
method subscriber. This ends when:- Publisher send all the elements requested (defined by backpressure)
- Publisher send all the elements it has.
onComplete
method to finish subscriber and subscription - There is an error ->
onError
method cancel subscriber and subscription
Implements reactive streams. We have others implementations, like Akka or rxJava2.
- Two composable APIs: Flux(number unbounded of elements) and Mono (one or zero elements).
- Good for microservice architecture, because Reactor offers backpressure-ready network engines for http.
- Huge range of operators, that allow us to select, filter, transform and combine streams.
When we have a flow of data, we have some kind of operators that we can use to do something with data before send to the subscriber, or to the next operator. We have the next types:
- Transforming Operators: transform the data and pass to next
- Filtering Operators: filter stream data
- Debounce: Observable wait a time until emit items.
- Distinct: https://rxmarbles.com/#distinct
- ElementAt
- Filter: https://rxmarbles.com/#filter
- First
- IgnoreElements
- Last
- Sample
- Skip: Ignore the first n elements
- SkipLast: Ignore the last n elements
- Take: Take the first n elements
- TakeLast: Take the last n elements
- Combining Operators
- combineLatest
- merge
- zip: https://rxmarbles.com/#zip
- Utility Operators
- Delay: Delay to start emiting (only the first element)
- do
- Timestamp: Adding timestamp information on event
- Conditional Operators
- all
- contains
- Connectable Operators
To see marble diagram:
- https://rxmarbles.com
- http://reactivex.io/RxJava/javadoc/
- http://reactivex.io/RxJava/javadoc/io/reactivex/Flowable.html
Spring do wrapper arround flux and mono objects. The subscribe process is doing on class ServerHttpHandlerAdapter (from package org.springframework.http.reactive)
Kotlin BlockHound:
- tricky:
implementation("io.projectreactor.kotlin:reactor-kotlin-extensions")
init {
BlockHound.install(CoroutinesBlockHoundIntegration())
}
For Kotlin, we have problems using bean validations' annotation @Validated
. Is not supported with coroutines: spring-projects/spring-framework#23152
It is a design pattern of concurrency that kotlin uses to simplify the asynchronous executions.Is is a light thread, so not necessary create a new thread for every coroutine, using groups of subprocesses. It can be suspend and reactive by necessity.
The Scope of a launch coroutine is the lifecycle of coroutines. GlobalScope is scope that during all the time of application, but is not recomended to use in production
To run code in coroutines, we can use GlobalScope.launch{}
for executions without wait for the result and async{}.await()
to wait for result.
Job is a cancelable element with a lifecycle finalishing at the end of the execution. It doesn't return a value
- Functional controller
- Feign reactive
- rxjava: Project using RxJava based on udemy course rxJava2
- project-reator: Project using Reactor based on DevDojo youtube course
- web-flux: Project using WebFlux based on DevDojo youtube course
- web-flux-coroutines: Project with webflux using flow and coroutines
- coroutines: Project using coroutines based on udemy course Kotlin coroutines
- DevDojo: https://devdojo.academy/#Cursos
- Rx Java on udemy: https://www.udemy.com/course/rxjava_2
- Marble diagrams: https://rxmarbles.com
- Blog Spring about kotlin coroutines: https://spring.io/blog/2019/04/12/going-reactive-with-spring-coroutines-and-kotlin-flow
- Medium coroutines: https://medium.com/@tienisto/asynchronous-spring-using-kotlin-coroutines-and-r2dbc-93b3a079ac22
- Coroutines udemy course: https://www.udemy.com/course/kotlin-coroutines-aprende-programacion-asincrona-en-kotlin/