/learning-reactive-programming

Repo to put learns about reactive programming

Primary LanguageKotlin

Reative programming

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

React in a cold or hot way

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.

Initiative Reactive Streams

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

Project Reator

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.

https://projectreactor.io/

Operators (RxJava)

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:

To see marble diagram:

Spring webflux

Improve logs on intellij: images/bff-overview.jpg

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

Coroutines

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

Next studies

  • Functional controller
  • Feign reactive

Folders on repository

References