Slide 1

Slide 1 text

COROUTINES AND FLOW JOSÉ CAIQUE

Slide 2

Slide 2 text

PROGRAM PROCESS THREADS

Slide 3

Slide 3 text

A PROGRAM IS A SET OF OPERATIONS TO A COMPUTER TO PERFORM. A COMPUTER PROGRAM BECOMES A PROCESS WHEN IT IS LOADED AND BEGINS EXECUTION

Slide 4

Slide 4 text

A THREAD IS A SEQUENCE OF SUCH INSTRUCTIONS WITH A PROGRAM THAT CAN BE EXECUTED INDEPENDENTLY OF OTHER CODE

Slide 5

Slide 5 text

COROUTINES

Slide 6

Slide 6 text

ESSENTIALLY, COROUTINES ARE LIGHT- WEIGHT THREADS

Slide 7

Slide 7 text

fun main() = runBlocking { val jobs = List(100_000) { launch { delay(1000L) print(".") } } jobs.forEach { it.join() } } java.lang.OutOfMemoryError fun main() { val jobs = List(100_000) { thread { sleep(1000L) print(".") } } jobs.forEach { it.join() } } COROUTINES THREADS

Slide 8

Slide 8 text

DISPATCHERS

Slide 9

Slide 9 text

WHICH THREAD WILL LAUNCH THE COROUTINE

Slide 10

Slide 10 text

- DISPATCHERS.MAIN (ANDROID ONLY) - DISPATCHERS.DEFAULT - DISPATCHERS.IO - DISPATCHERS.UNCONFINED

Slide 11

Slide 11 text

fun main() { GlobalScope.launch(Main) {} GlobalScope.launch(IO) {} GlobalScope.launch(Main) {} GlobalScope.launch(Unconfined) {} GlobalScope.launch(newSingleThreadContext("myContext")) {} }

Slide 12

Slide 12 text

SCOPES

Slide 13

Slide 13 text

DEFINE A SCOPE FOR NEW COROUTINES. USED TO PROPAGATE THE ELEMENTS AND CANCELLATION

Slide 14

Slide 14 text

class MyActivity : Activity(), CoroutineScope by MainScope() { override fun onDestroy() { cancel() } } class MyViewModel : ViewModel(), CoroutineScope { override val coroutineContext: CoroutineContext = Main override fun onCleared() { super.onCleared() cancel() } } class MyViewModel : ViewModel() { init { viewModelScope.launch { ... } } }

Slide 15

Slide 15 text

SUSPEND FUNCTION

Slide 16

Slide 16 text

EXECUTION OF THE CODE WITHOUT BLOCKING THE CURRENT THREAD OF EXECUTION. A SUSPENDING FUNCTION CANNOT BE INVOKED FROM A REGULAR CODE, BUT ONLY FROM OTHER SUSPENDING FUNCTIONS AND FROM SUSPENDING LAMBDAS

Slide 17

Slide 17 text

SUSPENDING FUNCTIONS DO NOT BLOCK THE CALLER THREAD. SUSPENDING FUNCTIONS HAVE THE ABILITY TO BLOCK THE EXECUTION OF THE COROUTINE

Slide 18

Slide 18 text

suspend fun doRequest() : Int { return 1 } suspend fun doRequest(): Int = withContext(IO) { 1 } //withTimeout(1000L){ ... }


Slide 19

Slide 19 text

suspend fun listFromApi(){ viewState.value = ScreenState.Loading viewState.value = ScreenState.Result(performRequest()) } suspend fun doRequest(): Int = withContext(IO) { 1 }

Slide 20

Slide 20 text

fun retrieve() : Int { doRequest() } suspend fun doRequest(): Int = withContext(IO) { 1 //some result here } Suspend function 'performRequest' should be called only from a coroutine or another suspend function

Slide 21

Slide 21 text

BUILDERS

Slide 22

Slide 22 text

THE WAYS TO RUN A NEW COROUTINE

Slide 23

Slide 23 text

runBlocking{ viewState.value = ScreenState.Loading viewState.value = performRequest() } @Test fun testSuspendingFunction() = runBlocking { val res = suspendingTask1() assertEquals(0, res) }

Slide 24

Slide 24 text

val job : Job = viewModelScope.launch{ viewState.value = ScreenState.Loading viewState.value = performRequest() } //job.cancel()

Slide 25

Slide 25 text

val result : Deferred = viewModelScope.async { viewState.value = ScreenState.Loading viewState.value = performRequest() } result.await() //blocking
 result.cancel()

Slide 26

Slide 26 text

viewModelScope.launch(Main) { val user = withContext(IO) { userService.doLogin(username, password) } val currentFriends = withContext(IO) { userService.requestCurrentFriends(user) } val suggestedFriends = withContext(IO) { userService.requestSuggestedFriends(user) } val finalUser = user.copy( friends = currentFriends + suggestedFriends) }

Slide 27

Slide 27 text

viewModelScope.launch(Main) { val user = withContext(IO) { userService.doLogin(username, password) } val currentFriends = async(IO) { userService.requestCurrentFriends(user) } val suggestedFriends = async(IO) { userService.requestSuggestedFriends(user) } val finalUser = user.copy( friends = currentFriends + suggestedFriends) }

Slide 28

Slide 28 text

REMOVING CALLBACKS

Slide 29

Slide 29 text

suspend fun login(name: String, psw: String): User = suspendCancellableCoroutine { continuation -> service.doLogin(username, password) { user -> continuation.resume(user) } } //continuation.resumeWithException(error)

Slide 30

Slide 30 text

FLOW

Slide 31

Slide 31 text

KOTLIN REACTIVE PROGRAMMING COLD STREAMS + COROUTINES + OPERATORS SIMILAR TO SEQUENCES, FLOWS CAN BE TRANSFORMED USING VARIOUS COMMON OPERATORS LIKE MAP, FILTER, ETC UNLIKE A SEQUENCE, A FLOW IS ASYNCHRONOUS AND ALLOWS SUSPENDING FUNCTIONS ANYWHERE IN ITS BUILDER AND OPERATORS

Slide 32

Slide 32 text

fun foo(p: Params): Flow = flow { while (hasMore) emit(nextValue) } val ints: Flow = flow { for (i in 1..10) { delay(100) emit(i) } } ints.collect { println(it) }

Slide 33

Slide 33 text

fun Flow.delayASecond() = flow { collect { value -> // collect from the original flow delay(1000) // delay 1 second emit(value) // emit value to the resulting flow } }

Slide 34

Slide 34 text

YOU CAN EASILY CREATE YOUR OWN OPERATOR

Slide 35

Slide 35 text

val broadcast: ConflatedBroadcastChannel // emitting launch { broadcast.send(mMap.getBounds()) } // listening broadcast.consumeEach { service .retrieve(it) .map { it.getOrNull() } .collect { it?.let { … } } } //close broadcast.close()

Slide 36

Slide 36 text

JOSÉ CAIQUE ▸ Software Engineer ▸ Computer Science by UFS ▸ Android Tech Lead at Stone ▸ Speaker

Slide 37

Slide 37 text

J C A I Q U E _ J O S E C A I Q U E J O S E C A I Q U E T H A N K S

Slide 38

Slide 38 text

REFERENCES ▸ http://www.inf.puc-rio.br/~roberto/docs/MCC15-04.pdf ▸ https://searchsoftwarequality.techtarget.com/definition/program ▸ https://stackoverflow.com/questions/43021816/difference-between-thread- and-coroutine-in-kotlin ▸ https://github.com/Kotlin/KEEP/blob/master/proposals/coroutines.md ▸ https://kotlinlang.org/docs/reference/coroutines/basics.html ▸ https://medium.com/@elizarov/coroutine-context-and-scope-c8b255d59055 ▸ https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/ kotlinx.coroutines/-coroutine-scope/ ▸ https://skillsmatter.com/skillscasts/12727-coroutines-by- example#showModal?modal-signup-complete ▸ https://antonioleiva.com/coroutines/ ▸ https://sourcediving.com/kotlin-coroutines-in-android-e2d5bb02c275 ▸ https://medium.com/@elizarov/simple-design-of-kotlin-flow-4725e7398c4c