Slide 1

Slide 1 text

Why Reactive Programming? Felipe Costa Android Developer @ OLX Brasil Bruno Kosawa Android Developer @ OLX Brasil

Slide 2

Slide 2 text

OLX is part of the biggest online marketplace group in the world Why Reactive Programming? About OLX Brasil One of the biggest groups on Internet1 One of the biggest groups of online classified2 1 USDbn mkt cap, Fev/2017 2 EURm receita classificados, 2015

Slide 3

Slide 3 text

OLX is the result of two big companies Why Reactive Programming? About OLX Brasil 50% 50% + = Shareholders

Slide 4

Slide 4 text

Why Reactive Programming? About OLX Brasil Sources: Fabric 0.5 M DAU 3 M DAU

Slide 5

Slide 5 text

Why Reactive Programming? About the Speakers • Bacharel em Ciência da Computação pela UFRJ • Trabalha com programação desde 2011 • Trabalha com Android desde 2014 • Engenheiro de software na OLX há 1 ano • Bacharel em Ciência da Computação pela UFRJ • Trabalha com programação desde 2010 • Trabalha com Android desde 2011 • Engenheiro de software na OLX há 2 anos Felipe Costa Bruno Kosawa

Slide 6

Slide 6 text

1Why Reactive Programming? Input and Output

Slide 7

Slide 7 text

"Programs take input and produce output."

Slide 8

Slide 8 text

Counter function fun count(array: Array): Int {
 var count = 0
 
 for (item in array)
 count++
 
 return count
 } Why Reactive Programming? 1. Input and Output

Slide 9

Slide 9 text

Unix tool Why Reactive Programming? 1. Input and Output

Slide 10

Slide 10 text

Kinds of inputs we deal with Why Reactive Programming? // Listeners
 View.OnClickListener { view -> /* */ } // Lifecycle Callbacks
 override fun onCreate(savedInstanceState: Bundle?) { /* */ }
 override fun onBindViewHolder(holder: ViewHolder, position: Int) { /* */ }
 
 // Async Callbacks
 override fun onFailure(throwable: Throwable) { /* */ }
 override fun onResponse(response: ReponseDTO) { /* */ } 1. Input and Output

Slide 11

Slide 11 text

Why Reactive Programming? 1. Input and Output Imperative Programming

Slide 12

Slide 12 text

Why Reactive Programming? 1. Input and Output override fun onCreate(savedInstanceState: Bundle?, persistentState: PersistableBundle?) {
 super.onCreate(savedInstanceState, persistentState)
 
 setupInitialState()
 
 Api.loadCharacters(object : ResponseCallback> {
 
 override fun onResponse(response: List) {
 updateUI(response)
 }
 
 override fun onFailure(throwable: Throwable) {
 showLoadCharactersError()
 }
 })
 
 button.setOnClickListener {
 
 Api.favoriteCharacter(object : ResponseCallback {
 
 override fun onResponse(response: Character) {
 updateFavoriteUI(response)
 }
 
 override fun onFailure(throwable: Throwable) {
 handleFavoriteError()
 }
 })
 }
 } Execution Order Framework Network Network UI Time

Slide 13

Slide 13 text

Imperative Programming Why Reactive Programming? 1. Input and Output Framework Network UI Others Execution Order Time Update State Know what happened previously

Slide 14

Slide 14 text

State

Slide 15

Slide 15 text

State is exponentially complex Why Reactive Programming? val isDisplayed: Boolean // 2 states
 
 val isEnabled: Boolean // 4 states
 
 val isSelected: Boolean // 8 states
 
 val isFavored: Boolean // 16 states 1. Input and Output

Slide 16

Slide 16 text

Why Reactive Programming? 1. Input and Output Compositional Event System (Non-Linear Programming) Imperative Programming

Slide 17

Slide 17 text

Why Reactive Programming? 1. Input and Output Reactive Programming

Slide 18

Slide 18 text

Why Reactive Programming? 1. Input and Output Reactive Programming

Slide 19

Slide 19 text

2Why Reactive Programming? Definition

Slide 20

Slide 20 text

• Paper 1989 - Gérard Berry • Microsoft Rx (2009) • Rx = Reactive Extensions • RxJava (Kotlin S2) • “Functional Reactive Programming” A little bit of context Why Reactive Programming? 2. Definition

Slide 21

Slide 21 text

"Reactive programming is programming with asynchronous data streams."

Slide 22

Slide 22 text

We all responde to flowing data and react to changes… Broadcasts Why Reactive Programming? 2. Definition Listeners MVP MVC Callbacks Event Bus

Slide 23

Slide 23 text

What is reactive programming? It is programming paradigm oriented by data streams and the propagation of change Why Reactive Programming? 2. Definition

Slide 24

Slide 24 text

3Why Reactive Programming? Propagation of change

Slide 25

Slide 25 text

Propagation of Change Having α := ß + γ with ß = 10 and γ = 20 Why Reactive Programming? 3. Propagation of change Spreadsheet ß γ α 10 20 30

Slide 26

Slide 26 text

Propagation of Change When ß changes to 30, α changes as well Why Reactive Programming? 3. Propagation of change Spreadsheet ß γ α 30 20 50

Slide 27

Slide 27 text

Observer Pattern Why Reactive Programming? 3. Propagation of change Observer +notify() ConcreteObserver2 +notify() ConcreteObserver1 +notify() Subject +registerObserver(observer) +unregisterObserver(observer) +notifyObservers() +observerCollection

Slide 28

Slide 28 text

Why Reactive Programming? 3. Propagation of change Observers Subject Registering Calm

Slide 29

Slide 29 text

Why Reactive Programming? 3. Propagation of change Observers Subject Notify Angry

Slide 30

Slide 30 text

Why Reactive Programming? 3. Propagation of change Observers Reacting Subject Angry

Slide 31

Slide 31 text

Why Reactive Programming? 3. Propagation of change Observable

Slide 32

Slide 32 text

Observable Why Reactive Programming? 3. Propagation of change • Container that can be emit signals to observers • Signals are emitted through time

Slide 33

Slide 33 text

4Why Reactive Programming? Data streams

Slide 34

Slide 34 text

Data Stream Values over time. Examples: • Mouse cursor positions on the screen; • Property values updates; • Text Field changes; • Bits being downloaded from the cloud Why Reactive Programming? 4. Data streams

Slide 35

Slide 35 text

Why Reactive Programming? 4. Data streams Observable.just("Alpha", "Beta", "Gamma") Time

Slide 36

Slide 36 text

Why Reactive Programming? 4. Data streams just("Alpha", "Beta", "Gamma").subscribe() Time Gamma Beta Alpha

Slide 37

Slide 37 text

Why Reactive Programming? 4. Data streams just("Alpha", "Beta", "Gamma").subscribe({ it -> println(it)}) Time Gamma Beta Alpha

Slide 38

Slide 38 text

Why Reactive Programming? 4. Data streams just("Alpha", "Beta", "Gamma") .subscribe({ it -> println(it)}, { println("completed")}) Time Gamma Beta Alpha onCompleted

Slide 39

Slide 39 text

Why Reactive Programming? 4. Data streams just("Alpha", "Beta", "Gamma") .subscribe({ it -> println(it)}, { it -> println(it.message)}, { println("completed")}) Time Gamma Beta Alpha onError

Slide 40

Slide 40 text

5Why Reactive Programming? Data streams are composable

Slide 41

Slide 41 text

Time Why Reactive Programming? 5. Data streams are composable Time Observable.transform(f: (x) -> y): Observable

Slide 42

Slide 42 text

Time Why Reactive Programming? 5. Data streams are composable 5 2 8 1 Time 2 16 4 10 map { it * 2 }

Slide 43

Slide 43 text

Time Why Reactive Programming? 5. Data streams are composable 5 2 8 1 Time 8 2 filter { it % 2 == 0 }

Slide 44

Slide 44 text

Why Reactive Programming? 5. Data streams are composable var lastClickTime: Long = 0 override fun onClick(v: View) { val clickTime = System.currentTimeMillis() if (clickTime - lastClickTime < 700L) { onDoubleClick(v) lastClickTime = 0 } else { onSingleClick(v) } lastClickTime = clickTime } fun onSingleClick(v: View) { /* */ } fun onDoubleClick(v: View) { /* */ } Double Tap

Slide 45

Slide 45 text

Why Reactive Programming? 5. Data streams are composable container.clicks() .buffer(700L, TimeUnit.MILLISECONDS) .map { it.size } .map { if (it == 2) "Double Tap" else "" } .subscribe(textView::setText) Double Tap

Slide 46

Slide 46 text

Why Reactive Programming? 5. Data streams are composable container.clicks() .buffer(700L, TimeUnit.MILLISECONDS) .map { it.size } .map { if (it == 2) "Double Tap" else "" } .subscribe(textView::setText) Double Tap Time

Slide 47

Slide 47 text

Why Reactive Programming? 5. Data streams are composable container.clicks() .buffer(700L, TimeUnit.MILLISECONDS) .map { it.size } .map { if (it == 2) "Double Tap" else "" } .subscribe(textView::setText) Double Tap Time Time Buffer(700L)

Slide 48

Slide 48 text

Why Reactive Programming? 5. Data streams are composable container.clicks() .buffer(700L, TimeUnit.MILLISECONDS) .map { it.size } .map { if (it == 2) "Double Tap" else "" } .subscribe(textView::setText) Double Tap Time Time Map { it.size } 1 2 1 3

Slide 49

Slide 49 text

Why Reactive Programming? 5. Data streams are composable container.clicks() .buffer(700L, TimeUnit.MILLISECONDS) .map { it.size } .map { if (it == 2) "Double Tap" else "" } .subscribe(textView::setText) Double Tap Time Time map { if (it == 2) "Double Tap" else "" } DT 1 2 1 3

Slide 50

Slide 50 text

Why Reactive Programming? 5. Data streams are composable container.clicks() .buffer(700L, TimeUnit.MILLISECONDS) .map { it.size } .map { if (it == 2) "Double Tap" else "" } .subscribe(textView::setText) Double Tap

Slide 51

Slide 51 text

Why Reactive Programming? 5. Data streams are composable container.clicks() .buffer(700L, TimeUnit.MILLISECONDS) .map { it.size } .filter { it >= 2 } Multiple Tap

Slide 52

Slide 52 text

Why Reactive Programming? 5. Data streams are composable var counter = 0 upButton.setOnClickListener { counter++ resultTextView.text = counter.toString() } downButton.setOnClickListener { counter-- resultTextView.text = counter.toString() } Up and Down

Slide 53

Slide 53 text

Why Reactive Programming? 5. Data streams are composable val upStream = upButton.clicks().map { 1 } val downStream = downButton.clicks().map { -1 } merge(upStream, downStream) .startWith(0) .scan({ t1, t2 -> t1 + t2 }) .map { it.toString() } .subscribe(resultTextView::setText) Up and Down

Slide 54

Slide 54 text

Why Reactive Programming? 5. Data streams are composable val upStream = upButton.clicks().map { 1 } val downStream = downButton.clicks().map { -1 } merge(upStream, downStream) .startWith(0) .scan({ t1, t2 -> t1 + t2 }) .map { it.toString() } .subscribe(resultTextView::setText) Up and Down

Slide 55

Slide 55 text

Why Reactive Programming? 5. Data streams are composable val upStream = upButton.clicks().map { 1 } val downStream = downButton.clicks().map { -1 } merge(upStream, downStream) .startWith(0) .scan({ t1, t2 -> t1 + t2 }) .map { it.toString() } .subscribe(resultTextView::setText) Up and Down

Slide 56

Slide 56 text

Why Reactive Programming? 5. Data streams are composable val upStream = upButton.clicks().map { 1 } val downStream = downButton.clicks().map { -1 } merge(upStream, downStream) .startWith(0) .scan({ t1, t2 -> t1 + t2 }) .map { it.toString() } .subscribe(resultTextView::setText) Up and Down

Slide 57

Slide 57 text

Why Reactive Programming? 5. Data streams are composable val upStream = upButton.clicks().map { 1 } val downStream = downButton.clicks().map { -1 } merge(upStream, downStream) .startWith(0) .scan({ t1, t2 -> t1 + t2 }) .map { it.toString() } .subscribe(resultTextView::setText) Up and Down

Slide 58

Slide 58 text

Why Reactive Programming? 5. Data streams are composable val upStream = upButton.clicks().map { 1 } val downStream = downButton.clicks().map { -1 } merge(upStream, downStream) .startWith(0) .scan({ t1, t2 -> t1 + t2 }) .map { it.toString() } .subscribe(resultTextView::setText) Up and Down

Slide 59

Slide 59 text

Why Reactive Programming? 5. Data streams are composable val upStream = upButton.clicks().map { 1 } val downStream = downButton.clicks().map { -1 } merge(upStream, downStream) .startWith(0) .scan({ t1, t2 -> t1 + t2 }) .map { it.toString() } .subscribe(resultTextView::setText) Up and Down

Slide 60

Slide 60 text

Why Reactive Programming? 5. Data streams are composable val upStream = upButton.clicks().map { 1 } val downStream = downButton.clicks().map { -1 } merge(upStream, downStream) .startWith(0) .scan({ t1, t2 -> t1 + t2 }) .map { it.toString() } .subscribe(resultTextView::setText) Up and Down

Slide 61

Slide 61 text

fun callbackHellExample() {
 favoriteButton.setOnClickListener(View.OnClickListener {
 
 })
 } Why Reactive Programming? 5. Data streams are composable

Slide 62

Slide 62 text

fun callbackHellExample() {
 favoriteButton.setOnClickListener(View.OnClickListener {
 Api.favoriteCharacter(!character.isFavorite, object : Callback {
 override fun success(isFavorite: Boolean) {
 }
 
 override fun error(throwable: Throwable) {
 showMessage("Error: " + throwable.message)
 }
 })
 })
 } Why Reactive Programming? 5. Data streams are composable

Slide 63

Slide 63 text

fun callbackHellExample() {
 favoriteButton.setOnClickListener(View.OnClickListener {
 Api.favoriteCharacter(!character.isFavorite, object : Callback {
 override fun success(isFavorite: Boolean) {
 character.save(isFavorite, object : Callback {
 
 })
 }
 
 override fun error(throwable: Throwable) {
 showMessage("Error: " + throwable.message)
 }
 })
 })
 } Why Reactive Programming? 5. Data streams are composable

Slide 64

Slide 64 text

fun callbackHellExample() {
 favoriteButton.setOnClickListener(View.OnClickListener {
 Api.favoriteCharacter(!character.isFavorite, object : Callback {
 override fun success(isFavorite: Boolean) {
 character.save(isFavorite, object : Callback {
 override fun success(character: Character) {
 updateUI(character)
 }
 
 override fun error(otherThrowable: Throwable) {
 showMessage("Error: " + otherThrowable.message)
 }
 })
 }
 
 override fun error(throwable: Throwable) {
 showMessage("Error: " + throwable.message)
 }
 })
 })
 } Why Reactive Programming? 5. Data streams are composable

Slide 65

Slide 65 text

Why Reactive Programming? 5. Data streams are composable fun reactiveExample() { favoriteButton.clicks() }

Slide 66

Slide 66 text

Why Reactive Programming? 5. Data streams are composable fun reactiveExample() { favoriteButton.clicks() .flatMap { Api.favorite(!character.isFavorite) } }

Slide 67

Slide 67 text

Why Reactive Programming? 5. Data streams are composable fun reactiveExample() { favoriteButton.clicks() .flatMap { Api.favorite(!character.isFavorite) } .flatMap { isFavorite: Boolean -> character.save(isFavorite) } }

Slide 68

Slide 68 text

Why Reactive Programming? 5. Data streams are composable fun reactiveExample() { favoriteButton.clicks() .flatMap { Api.favorite(!character.isFavorite) } .flatMap { isFavorite: Boolean -> character.save(isFavorite) } .doOnError { error: Throwable -> showMessage("Error: {error.message}") } }

Slide 69

Slide 69 text

Why Reactive Programming? 5. Data streams are composable fun reactiveExample() { favoriteButton.clicks() .flatMap { Api.favorite(!character.isFavorite) } .flatMap { isFavorite: Boolean -> character.save(isFavorite) } .doOnError { error: Throwable -> showMessage("Error: {error.message}") } .subscribe { character: Character -> updateUI(character) } }

Slide 70

Slide 70 text

6Why Reactive Programming? Concurrency

Slide 71

Slide 71 text

Schedulers Schedulers when and where work is performed Why Reactive Programming? 6. Concurrency

Slide 72

Slide 72 text

Why Reactive Programming? 6. Concurrency fun reactiveExample() { favoriteButton.clicks() .flatMap { Api.favorite(!character.isFavorite) } .flatMap { isFavorite: Boolean -> character.save(isFavorite) } .doOnError { error: Throwable -> showMessage("Error: {error.message}") } .subscribe { character: Character -> updateUI(character) } }

Slide 73

Slide 73 text

Why Reactive Programming? 6. Concurrency fun reactiveExample() { favoriteButton.clicks() .flatMap { Api.favorite(!character.isFavorite) } .flatMap { isFavorite: Boolean -> character.save(isFavorite) } .subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()) .doOnError { error: Throwable -> showMessage("Error: {error.message}") } .subscribe { character: Character -> updateUI(character) } }

Slide 74

Slide 74 text

7Why Reactive Programming? Conclusion

Slide 75

Slide 75 text

Pitfalls • Backpressure • Memory issues • Logging Why Reactive Programming? 7. Conclusion

Slide 76

Slide 76 text

• http://reactivex.io • https://gist.github.com/staltz/868e7e9bc2a7b8c1f754 • http://blog.danlew.net/2017/07/27/an-introduction-to-functional- reactive-programming/ • http://joshaber.github.io/2013/02/11/input-and-output/ • https://github.com/felipehjcosta/kotlin-rxjava-android • https://github.com/felipehjcosta/reactive-programming-samples Links Why Reactive Programming? 7. Conclusion

Slide 77

Slide 77 text

Thanks Felipe Costa Bruno Kosawa fcostaa felipehjcosta bkosawa bkosawa felipe.costa@olxbr.com bruno.costa@olxbr.com

Slide 78

Slide 78 text

Questions? Felipe Costa Bruno Kosawa fcostaa felipehjcosta bkosawa bkosawa felipe.costa@olxbr.com bruno.costa@olxbr.com