SlideShare a Scribd company logo
ASYNC CODE ON KOTLIN:
RXJAVA OR/AND COROUTINES
Fabio Collini
@fabioCollini
linkedin.com/in/fabiocollini
github.com/fabioCollini
medium.com/@fabioCollini
codingjam.it
Android programmazione avanzata
Android Developers Italia
Ego slide
RxJava
Coroutines
OR
RxJava
Coroutines
AND
RxJava Coroutines->
RxJavaCoroutines ->
rxCompletable, rxMaybe, rxSingle, rxObservable, rxFlowable
CompletableSource.await, MaybeSource.await, MaybeSource.awaitOrDefault,
MaybeSource.openSubscription, SingleSource.await,
ObservableSource.awaitFirst, ObservableSource.awaitFirstOrDefault,
ObservableSource.awaitFirstOrElse, ObservableSource.awaitFirstOrNull,
ObservableSource.awaitLast, ObservableSource.awaitSingle,
ObservableSource.openSubscription, ObservableSource.iterator
github.com/Kotlin/kotlinx.coroutines/tree/master/reactive/kotlinx-coroutines-rx2
Single
Maybe
Completable
Observable
Flowable
Cold Vs Hot
Subjects
suspend methods
Job/Deferred
Channels
Actors
Producers
Publishers
BroadcastChannels
Wrapper of a synchronous method
fun myPref(): String =
prefs.getString("myPref", "")
fun myPref(): Single<String> =
Single.fromCallable {
prefs.getString("myPref", "")
}1
suspend fun myPref(): String =
withContext(CommonPool) {
prefs.getString("myPref", "")
}2
RxJavaCoroutines
Thread & error management
fun myPref(): Single<String> =
Single.fromCallable {
prefs.getString("myPref", "")
}1
suspend fun myPref(): String =
withContext(CommonPool) {
prefs.getString("myPref", "")
}2
myPref()
.subscribeOn(io())
.observeOn(mainThread())
.subscribe(
{ myText.text = it },
{ e -> myText.text = e.message }
)
launch(CommonPool) {
try {
val value = myPref()
withContext(UI) {
myText.text = value
}
} catch (e: Exception) {
withContext(UI) {
myText.text = value
}
}
}
RxJava Coroutines
Wrapper of an asynchronous method
fun View.scale(v: Float): ViewPropertyAnimator {
return animate()
.scaleX(v)
.scaleY(v)
}4
text.setOnClickListener {
text.scale(2f).withEndAction {
text.scale(1f)
}1
}2
Wrapper of an asynchronous method
fun View.scale(value: Float): Completable =
Completable.create { emitter ->
val animator = animate()
animator.scaleX(value).scaleY(value).withEndAction {
emitter.onComplete()
}3
}4
text.setOnClickListener {
text.scale(2f)
.andThen(text.scale(1f))
.subscribe()
}2
RxJava
Wrapper of an asynchronous method
fun View.scale(value: Float): Completable =
Completable.create { emitter ->
val animator = animate()
animator.scaleX(value).scaleY(value).withEndAction {
emitter.setCancellable(null)
emitter.onComplete()
}
emitter.setCancellable {
animator.cancel()
}3
}4
RxJava
Wrapper of an asynchronous method
suspend fun View.scale(v: Float) =
suspendCoroutine<Unit> { continuation ->
animate()
.scaleX(v)
.scaleY(v)
.withEndAction { continuation.resume(Unit) }
}1
text.setOnClickListener {
launch(UI) {
text.scale(2f)
text.scale(1f)
}
}
Coroutines
Wrapper of an asynchronous method
suspend fun View.scale(v: Float) =
suspendCancellableCoroutine<Unit> { continuation ->
val animator = animate()
animator
.scaleX(v)
.scaleY(v)
.withEndAction { continuation.resume(Unit) }
continuation.invokeOnCancellation {
animator.cancel()
}
}1
Coroutines
suspend fun View.scale(v: Float) =
suspendCoroutine<Unit> { continuation ->
animate()
.scaleX(v)
.scaleY(v)
.withEndAction {
continuation.resume(Unit)
}3
}4
launch(UI) {
text.scale(2f)
println(“Where am I?”)
}5
fun View.scale(value: Float): Completable =
Completable.create { emitter ->
animate()
.scaleX(value)
.scaleY(value)
.withEndAction_{
emitter.onComplete()
}1
}2
text.scale(2f)
.doOnComplete { println("Where am I?") }
.subscribe()
Threading
RxJava Coroutines
suspend fun View.scale(v: Float) =
suspendCoroutine<Unit> { continuation ->
animate()
.scaleX(v)
.scaleY(v)
.withEndAction {
thread {
continuation.resume(Unit)
}
}3
}4
launch(UI) {
text.scale(2f)
println(“Where am I?”)
}5
fun View.scale(value: Float): Completable =
Completable.create { emitter ->
animate()
.scaleX(value)
.scaleY(value)
.withEndAction_{
thread_{
emitter.onComplete()
}_
}1
}2
text.scale(2f)
.doOnComplete { println("Where am I?") }
.subscribe()
Threading
RxJava Coroutines
fun View.scale(value: Float): Completable =
Completable.create { emitter ->
animate()
.scaleX(value)
.scaleY(value)
.withEndAction_{
thread_{
emitter.onComplete()
}_
}1
}2
text.scale(2f)
.observeOn(AndroidSchedulers.mainThread())
.doOnComplete { println("Where am I?") }
.subscribe()
Threading
RxJava
interface StackOverflowService {
@GET("/users")
fun getTopUsers(): Single<List<User>>
@GET("/users/{userId}/badges")
fun getBadges(
@Path("userId") userId: Int
): Single<List<Badge>>
@GET("/users/{userId}/top-tags")
fun getTags(
@Path("userId") userId: Int
): Single<List<Tag>>
}0
interface StackOverflowService {
@GET("/users")
fun getTopUsers(): Deferred<List<User>>
@GET("/users/{userId}/badges")
fun getBadges(
@Path("userId") userId: Int
): Deferred<List<Badge>>
@GET("/users/{userId}/top-tags")
fun getTags(
@Path("userId") userId: Int
): Deferred<List<Tag>>
}1
RxJava Coroutines
class MyViewModel(
private val service: StackOverflowService
) : ViewModel() {
private val disposable = CompositeDisposable()
fun load() {
disposable +=
service.getTopUsers()
.subscribeOn(io())
.observeOn(mainThread())
.subscribe(
{ users -> updateUi(users) },
{ e -> updateUi(e) }
)1
}A
private fun updateUi(s: Any) {
//...
}B
override fun onCleared() {
disposable.clear()
}C
}D
class MyViewModel(
private val service: StackOverflowService
) : ViewModel() {
private val job = Job()
fun load() {
launch(CommonPool + job) {
try {
val users = service.getTopUsers().await()
updateUi(users)
} catch (e: Exception) {
updateUi(e)
}4
}5
}E
private suspend fun updateUi(s: Any) {
withContext(UI) {
//...
}F
}1
override fun onCleared() {
job.cancel()
}G
}H
RxJava Coroutines
service.getTopUsers()
.subscribeOn(io())
.observeOn(mainThread())
.subscribe(
{ users -> updateUi(users) },
{ e -> updateUi(e) }
)1
launch(CommonPool + job) {
try {
val users = service.getTopUsers().await()
updateUi(users)
} catch (e: Exception) {
updateUi(e)
}4
}5
RxJava Coroutines
service.getTopUsers()
.map_{_it.first()_}_
.flatMap_{_firstUser_->_
service.getBadges(firstUser.id)
}0
.subscribeOn(io())
.observeOn(mainThread())
.subscribe(
{_badges_->_updateUi(badges)_},
{ e -> updateUi(e) }
)1
launch(CommonPool + job) {
try {
val users = service.getTopUsers().await()
val firstUser = users.first()
val badges = service.getBadges(
firstUser.id).await()
updateUi(badges)
} catch (e: Exception) {
updateUi(e)
}4
}5
RxJava Coroutines
updateUi("loading users")
service.getTopUsers()
.observeOn(mainThread())
.doOnSuccess { updateUi("loading badges") }
.observeOn(io())
.map_{_it.first()_}_
.flatMap_{_firstUser_->_
service.getBadges(firstUser.id)
}0
.subscribeOn(io())
.observeOn(mainThread())
.subscribe(
{_badges_->_updateUi(badges)_},
{ e -> updateUi(e) }
)1
launch(CommonPool + job) {
try {
updateUi("loading users")
val users = service.getTopUsers().await()
updateUi("loading badges")
val firstUser = users.first()
val badges = service.getBadges(
firstUser.id).await()
updateUi(badges)
} catch (e: Exception) {
updateUi(e)
}4
}5
RxJava Coroutines
service.getTopUsers()
.map_{_it.first()_}_
.flatMap_{_firstUser_->_
service.getBadges(firstUser.id)
.map { badges ->
UserStats(firstUser, badges)
}p
}0
.subscribeOn(io())
.observeOn(mainThread())
.subscribe(
{_user_->_updateUi(user)_},
{ e -> updateUi(e) }
)1
launch(CommonPool + job) {
try {
val users = service.getTopUsers().await()
val firstUser = users.first()
val badges = service.getBadges(
firstUser.id).await()
val user = UserStats(firstUser, badges)
updateUi(user)
} catch (e: Exception) {
updateUi(e)
}4
}5
RxJava Coroutines
service.getTopUsers()
.flattenAsObservable { it.take(5) }
.concatMapEager { user ->
service.getBadges(user.id)
.map { badges ->
UserStats(user, badges)
}p
.toObservable()
}0
.toList()
.subscribeOn(io())
.observeOn(mainThread())
.subscribe(
{ usersWithBadges ->
updateUi(usersWithBadges)
},
{ e -> updateUi(e) }
)1
launch(CommonPool + job) {
try {
val users = service.getTopUsers().await()
val usersWithBadges =
users.take(5)
.map { it to service.getBadges(it.id) }
.map { (user, badges) ->
UserStats(user, badges.await())
}
updateUi(usersWithBadges)1
} catch (e: Exception) {
updateUi(e)
}4
}5
RxJava Coroutines
service.getTopUsers()
.flattenAsObservable { it.take(5) }
.concatMapEager { user ->
service.getBadges(user.id)
.map { badges ->
UserStats(user, badges)
}p
.toObservable()
}0
.toList()
.subscribeOn(io())
.observeOn(mainThread())
.subscribe(
{ usersWithBadges ->
updateUi(usersWithBadges)
},
{ e -> updateUi(e) }
)1
launch(CommonPool + job) {
try {
val users = service.getTopUsers().await()
val usersWithBadges: List<UserStats> =
users.take(5)
.map { user ->
async(coroutineContext) {
val badges = service.getBadges(user.id)
UserStats(user, badges.await())
}r
}t
.map { it.await() }
updateUi(usersWithBadges)1
} catch (e: Exception) {
updateUi(e)
}4
}5
RxJava Coroutines
service.getTopUsers()
.flattenAsObservable { it.take(5) }
.concatMapEager { user ->
userDetail(user).toObservable()
}0
.toList()
.subscribeOn(io())
.observeOn(mainThread())
.subscribe(
{ users ->
updateUi(users)
},
{ e -> updateUi(e) }
)1
fun userDetail(user: User): Single<UserStats> {
return service.getBadges(user.id)
.map { badges ->
UserStats(user, badges)
}7
}8
launch(CommonPool + job) {
try {
val users = service.getTopUsers().await()
val usersWithBadges: List<UserStats> =
users.take(5)
.map { user ->
async(coroutineContext) {
userDetail(user)
}r
}t
.map { it.await() }
updateUi(usersWithBadges)1
} catch (e: Exception) {
updateUi(e)
}4
}5
suspend fun userDetail(user: User): UserStats {
val badges = service.getBadges(user.id)
return UserStats(user, badges.await())
}9
RxJava Coroutines
fun userDetail(user: User): Single<UserStats> {
return service.getBadges(user.id)
.map { badges ->
UserStats(user, badges)
}7
}8
suspend fun userDetail(user: User): UserStats {
val badges = service.getBadges(user.id)
return UserStats(user, badges.await())
}9
RxJava Coroutines
fun userDetail(user: User): Single<UserStats> {
return Singles.zip(
service.getBadges(user.id).subscribeOn(io()),
service.getTags(user.id).subscribeOn(io()),
{ badges, tags -> UserStats(user, badges, tags) }
)
}8
suspend fun userDetail(it: User): UserStats {
val badges = service.getBadges(it.id)
val tags = service.getTags(it.id)
return UserStats(it, badges.await(), tags.await())
}9
RxJava Coroutines
service.getTopUsers()
.subscribeOn(io())
.observeOn(mainThread())
.subscribe(
{ users -> updateUi(users) },
{ e -> updateUi(e) }
)1
launch(CommonPool + job) {
try {
val users = service.getTopUsers().await()
updateUi(users)
} catch (e: Exception) {
updateUi(e)
}4
}5
RxJava Coroutines
service.getTopUsers()
.subscribeOn(io())
.observeOn(mainThread())
.timeout(10, SECONDS)
.subscribe(
{ users -> updateUi(users) },
{ e -> updateUi(e) }
)1
launch(CommonPool + job) {
try {
withTimeout(10, SECONDS) {
val users = service.getTopUsers().await()
updateUi(users)
}6
} catch (e: Exception) {
updateUi(e)
}4
}5
RxJava Coroutines
service.getTopUsers()
.subscribeOn(io())
.observeOn(mainThread())
.timeout(10, SECONDS)
.retry(3)
.subscribe(
{ users -> updateUi(users) },
{ e -> updateUi(e) }
)1
launch(CommonPool + job) {
try {
retry(3) {
withTimeout(10, SECONDS) {
val users = service.getTopUsers().await()
updateUi(users)
}6
}7
} catch_(e: Exception) {
updateUi(e)
}4
}5
RxJava Coroutines
service.getTopUsers()
.subscribeOn(io())
.observeOn(mainThread())
.timeout(10, SECONDS)
.retry(3)
.subscribe(
{ users -> updateUi(users) },
{ e -> updateUi(e) }
)1
launch(CommonPool + job) {
try {
retry(3) {
withTimeout(10, SECONDS) {
val users = service.getTopUsers().await()
updateUi(users)
}6
}7
} catch_(e: Exception) {
updateUi(e)
}4
}5
suspend fun <T> retry(attempts: Int = 5,
f: suspend () -> T): T {
repeat(attempts - 1) {
try {
return f()
} catch (e: Exception) {
}
}
return f()
}
RxJava Coroutines
service.getTopUsers()
.subscribeOn(io())
.observeOn(mainThread())
.timeout(10, SECONDS)
.retryWhen(ExponentialBackoff(3))
.subscribe(
{ users -> updateUi(users) },
{ e -> updateUi(e) }
)1
launch(CommonPool + job) {
try {
exponentialBackoff(3) {
withTimeout(10, SECONDS) {
val users = service.getTopUsers().await()
updateUi(users)
}6
}7
} catch_(e: Exception) {
updateUi(e)
}4
}5
RxJava Coroutines
service.getTopUsers()
.subscribeOn(io())
.observeOn(mainThread())
.timeout(10, SECONDS)
.retryWhen(ExponentialBackoff(3))
.subscribe(
{ users -> updateUi(users) },
{ e -> updateUi(e) }
)1
class ExponentialBackoff(private val maxRetries: Int) :
Function1<Flowable<out Throwable>, Publisher<*>> {
private var retryCount = 0
private var currentDelay = 100L + Random().nextInt(100)
override fun invoke(attempts: Flowable<out Throwable>): Publisher<*> {
return attempts
.flatMap { throwable ->
if (++retryCount < maxRetries)
Flowable.timer(currentDelay, MILLISECONDS).also {
currentDelay *= 2
}
else
Flowable.error(throwable)
}
}
}
launch(CommonPool + job) {
try {
exponentialBackoff(3) {
withTimeout(10, SECONDS) {
val users = service.getTopUsers().await()
updateUi(users)
}6
}7
} catch_(e: Exception) {
updateUi(e)
}4
}5
suspend fun <T> exponentialBackoff(
times: Int = 5,
f: suspend () -> T): T {
var currentDelay = 100 + Random().nextInt(100)
repeat(times - 1) {
try {
return f()
} catch (e: Exception) {
}
delay(currentDelay)
currentDelay *= 2
}
return f()
}
RxJava Coroutines
Debugging
RxJava Coroutines
Testing
RxJava
JVM
Trampoline scheduler
blockingGet
TestScheduler and TestObserver
Espresso
Schedulers.from(AsyncTask.THREAD_POOL_EXECUTOR)
Coroutines
JVM
runBlocking
Espresso
AsyncTask.THREAD_POOL_EXECUTOR.asCoroutineDispatcher()
11051 io.reactivex
144 kotlin.coroutines
1984 kotlinx.coroutines
Method count - debug
427 io.reactivex
77 kotlin.coroutines
493 kotlinx.coroutines
Method count - release
Links
Demo Project
github.com/fabioCollini/RxJavaVsCoroutines
Guide to kotlinx.coroutines by example
github.com/Kotlin/kotlinx.coroutines/blob/master/coroutines-guide.md
Kotlin coroutines, a deeper look
medium.com/@elizarov/kotlin-coroutines-a-deeper-look-180536305c3f
Async code using Kotlin Coroutines
proandroiddev.com/async-code-using-kotlin-coroutines-233d201099ff
Testing asynchronous RxJava code using Mockito
medium.com/@fabioCollini/testing-asynchronous-rxjava-code-using-mockito-8ad831a16877
THANKS
FOR YOUR
ATTENTION
QUESTIONS?
Android Developers Italia
androiddevs.it

More Related Content

What's hot

L'API Collector dans tous ses états
L'API Collector dans tous ses étatsL'API Collector dans tous ses états
L'API Collector dans tous ses états
José Paumard
 
Real Life Clean Architecture
Real Life Clean ArchitectureReal Life Clean Architecture
Real Life Clean Architecture
Mattia Battiston
 
Spring boot
Spring bootSpring boot
Spring boot
Pradeep Shanmugam
 
Domain Driven Rails
Domain Driven RailsDomain Driven Rails
Domain Driven Rails
Yan Pritzker
 
Java 9 New Features
Java 9 New FeaturesJava 9 New Features
Java 9 New Features
Ali BAKAN
 
Spring Data JPA
Spring Data JPASpring Data JPA
Spring Data JPA
Cheng Ta Yeh
 
Microservices Interview Questions and Answers | Microservices Architecture Tr...
Microservices Interview Questions and Answers | Microservices Architecture Tr...Microservices Interview Questions and Answers | Microservices Architecture Tr...
Microservices Interview Questions and Answers | Microservices Architecture Tr...
Edureka!
 
AngularJS $http Interceptors (Explanation and Examples)
AngularJS $http Interceptors (Explanation and Examples)AngularJS $http Interceptors (Explanation and Examples)
AngularJS $http Interceptors (Explanation and Examples)
Brian Swartzfager
 
Introduction à JPA (Java Persistence API )
Introduction à JPA  (Java Persistence API )Introduction à JPA  (Java Persistence API )
Introduction à JPA (Java Persistence API )
Daniel Rene FOUOMENE PEWO
 
Introduction to Spring Boot!
Introduction to Spring Boot!Introduction to Spring Boot!
Introduction to Spring Boot!
Jakub Kubrynski
 
Java11 New Features
Java11 New FeaturesJava11 New Features
Java11 New Features
Haim Michael
 
Spring Framework - Core
Spring Framework - CoreSpring Framework - Core
Spring Framework - Core
Dzmitry Naskou
 
Understanding Database Transactions and Hibernate Sessions in Grails
Understanding Database Transactions and Hibernate Sessions in GrailsUnderstanding Database Transactions and Hibernate Sessions in Grails
Understanding Database Transactions and Hibernate Sessions in Grails
Jonas Witt
 
CompletableFuture
CompletableFutureCompletableFuture
CompletableFuture
koji lin
 
Angular components
Angular componentsAngular components
Angular components
Sultan Ahmed
 
Spring boot
Spring bootSpring boot
Spring boot
sdeeg
 
Sagas Middleware Architecture
Sagas Middleware ArchitectureSagas Middleware Architecture
Sagas Middleware Architecture
Mateusz Bosek
 
JPA Best Practices
JPA Best PracticesJPA Best Practices
JPA Best Practices
Carol McDonald
 
Java Persistence API (JPA) Step By Step
Java Persistence API (JPA) Step By StepJava Persistence API (JPA) Step By Step
Java Persistence API (JPA) Step By Step
Guo Albert
 
Java 8 presentation
Java 8 presentationJava 8 presentation
Java 8 presentation
Van Huong
 

What's hot (20)

L'API Collector dans tous ses états
L'API Collector dans tous ses étatsL'API Collector dans tous ses états
L'API Collector dans tous ses états
 
Real Life Clean Architecture
Real Life Clean ArchitectureReal Life Clean Architecture
Real Life Clean Architecture
 
Spring boot
Spring bootSpring boot
Spring boot
 
Domain Driven Rails
Domain Driven RailsDomain Driven Rails
Domain Driven Rails
 
Java 9 New Features
Java 9 New FeaturesJava 9 New Features
Java 9 New Features
 
Spring Data JPA
Spring Data JPASpring Data JPA
Spring Data JPA
 
Microservices Interview Questions and Answers | Microservices Architecture Tr...
Microservices Interview Questions and Answers | Microservices Architecture Tr...Microservices Interview Questions and Answers | Microservices Architecture Tr...
Microservices Interview Questions and Answers | Microservices Architecture Tr...
 
AngularJS $http Interceptors (Explanation and Examples)
AngularJS $http Interceptors (Explanation and Examples)AngularJS $http Interceptors (Explanation and Examples)
AngularJS $http Interceptors (Explanation and Examples)
 
Introduction à JPA (Java Persistence API )
Introduction à JPA  (Java Persistence API )Introduction à JPA  (Java Persistence API )
Introduction à JPA (Java Persistence API )
 
Introduction to Spring Boot!
Introduction to Spring Boot!Introduction to Spring Boot!
Introduction to Spring Boot!
 
Java11 New Features
Java11 New FeaturesJava11 New Features
Java11 New Features
 
Spring Framework - Core
Spring Framework - CoreSpring Framework - Core
Spring Framework - Core
 
Understanding Database Transactions and Hibernate Sessions in Grails
Understanding Database Transactions and Hibernate Sessions in GrailsUnderstanding Database Transactions and Hibernate Sessions in Grails
Understanding Database Transactions and Hibernate Sessions in Grails
 
CompletableFuture
CompletableFutureCompletableFuture
CompletableFuture
 
Angular components
Angular componentsAngular components
Angular components
 
Spring boot
Spring bootSpring boot
Spring boot
 
Sagas Middleware Architecture
Sagas Middleware ArchitectureSagas Middleware Architecture
Sagas Middleware Architecture
 
JPA Best Practices
JPA Best PracticesJPA Best Practices
JPA Best Practices
 
Java Persistence API (JPA) Step By Step
Java Persistence API (JPA) Step By StepJava Persistence API (JPA) Step By Step
Java Persistence API (JPA) Step By Step
 
Java 8 presentation
Java 8 presentationJava 8 presentation
Java 8 presentation
 

Similar to Async code on kotlin: rx java or/and coroutines - Kotlin Night Turin

Fabio Collini - Async code on Kotlin: RxJava or/and coroutines - Codemotion M...
Fabio Collini - Async code on Kotlin: RxJava or/and coroutines - Codemotion M...Fabio Collini - Async code on Kotlin: RxJava or/and coroutines - Codemotion M...
Fabio Collini - Async code on Kotlin: RxJava or/and coroutines - Codemotion M...
Codemotion
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
Dmitry Buzdin
 
Kpi driven-java-development
Kpi driven-java-developmentKpi driven-java-development
Kpi driven-java-development
Anirban Bhattacharjee
 
Coroutines in Kotlin. In-depth review
Coroutines in Kotlin. In-depth reviewCoroutines in Kotlin. In-depth review
Coroutines in Kotlin. In-depth review
Dmytro Zaitsev
 
Coroutines in Kotlin. UA Mobile 2017.
Coroutines in Kotlin. UA Mobile 2017.Coroutines in Kotlin. UA Mobile 2017.
Coroutines in Kotlin. UA Mobile 2017.
UA Mobile
 
JavaCro'14 - Scala and Java EE 7 Development Experiences – Peter Pilgrim
JavaCro'14 - Scala and Java EE 7 Development Experiences – Peter PilgrimJavaCro'14 - Scala and Java EE 7 Development Experiences – Peter Pilgrim
JavaCro'14 - Scala and Java EE 7 Development Experiences – Peter Pilgrim
HUJAK - Hrvatska udruga Java korisnika / Croatian Java User Association
 
JavaCro 2014 Scala and Java EE 7 Development Experiences
JavaCro 2014 Scala and Java EE 7 Development ExperiencesJavaCro 2014 Scala and Java EE 7 Development Experiences
JavaCro 2014 Scala and Java EE 7 Development Experiences
Peter Pilgrim
 
Spring into rails
Spring into railsSpring into rails
Spring into rails
Hiro Asari
 
Migrating from Flux to Redux. Why and how.
Migrating from Flux to Redux. Why and how.Migrating from Flux to Redux. Why and how.
Migrating from Flux to Redux. Why and how.
Astrails
 
Droidjam 2019 flutter isolates pdf
Droidjam 2019 flutter isolates pdfDroidjam 2019 flutter isolates pdf
Droidjam 2019 flutter isolates pdf
Anvith Bhat
 
Rx java in action
Rx java in actionRx java in action
Rx java in action
Pratama Nur Wijaya
 
Current State of Coroutines
Current State of CoroutinesCurrent State of Coroutines
Current State of Coroutines
Guido Pio Mariotti
 
Lock? We don't need no stinkin' locks!
Lock? We don't need no stinkin' locks!Lock? We don't need no stinkin' locks!
Lock? We don't need no stinkin' locks!
Michael Barker
 
Locks? We Don't Need No Stinkin' Locks - Michael Barker
Locks? We Don't Need No Stinkin' Locks - Michael BarkerLocks? We Don't Need No Stinkin' Locks - Michael Barker
Locks? We Don't Need No Stinkin' Locks - Michael Barker
JAX London
 
LetSwift RxSwift 시작하기
LetSwift RxSwift 시작하기LetSwift RxSwift 시작하기
LetSwift RxSwift 시작하기
Wanbok Choi
 
Scalaz 8 vs Akka Actors
Scalaz 8 vs Akka ActorsScalaz 8 vs Akka Actors
Scalaz 8 vs Akka Actors
John De Goes
 
Introduction to Scala
Introduction to ScalaIntroduction to Scala
Introduction to Scala
Raúl Raja Martínez
 
RxJS101 - What you need to know to get started with RxJS tomorrow
RxJS101 - What you need to know to get started with RxJS tomorrowRxJS101 - What you need to know to get started with RxJS tomorrow
RxJS101 - What you need to know to get started with RxJS tomorrow
Viliam Elischer
 
Reactive programming on Android
Reactive programming on AndroidReactive programming on Android
Reactive programming on Android
Tomáš Kypta
 
[245] presto 내부구조 파헤치기
[245] presto 내부구조 파헤치기[245] presto 내부구조 파헤치기
[245] presto 내부구조 파헤치기
NAVER D2
 

Similar to Async code on kotlin: rx java or/and coroutines - Kotlin Night Turin (20)

Fabio Collini - Async code on Kotlin: RxJava or/and coroutines - Codemotion M...
Fabio Collini - Async code on Kotlin: RxJava or/and coroutines - Codemotion M...Fabio Collini - Async code on Kotlin: RxJava or/and coroutines - Codemotion M...
Fabio Collini - Async code on Kotlin: RxJava or/and coroutines - Codemotion M...
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
 
Kpi driven-java-development
Kpi driven-java-developmentKpi driven-java-development
Kpi driven-java-development
 
Coroutines in Kotlin. In-depth review
Coroutines in Kotlin. In-depth reviewCoroutines in Kotlin. In-depth review
Coroutines in Kotlin. In-depth review
 
Coroutines in Kotlin. UA Mobile 2017.
Coroutines in Kotlin. UA Mobile 2017.Coroutines in Kotlin. UA Mobile 2017.
Coroutines in Kotlin. UA Mobile 2017.
 
JavaCro'14 - Scala and Java EE 7 Development Experiences – Peter Pilgrim
JavaCro'14 - Scala and Java EE 7 Development Experiences – Peter PilgrimJavaCro'14 - Scala and Java EE 7 Development Experiences – Peter Pilgrim
JavaCro'14 - Scala and Java EE 7 Development Experiences – Peter Pilgrim
 
JavaCro 2014 Scala and Java EE 7 Development Experiences
JavaCro 2014 Scala and Java EE 7 Development ExperiencesJavaCro 2014 Scala and Java EE 7 Development Experiences
JavaCro 2014 Scala and Java EE 7 Development Experiences
 
Spring into rails
Spring into railsSpring into rails
Spring into rails
 
Migrating from Flux to Redux. Why and how.
Migrating from Flux to Redux. Why and how.Migrating from Flux to Redux. Why and how.
Migrating from Flux to Redux. Why and how.
 
Droidjam 2019 flutter isolates pdf
Droidjam 2019 flutter isolates pdfDroidjam 2019 flutter isolates pdf
Droidjam 2019 flutter isolates pdf
 
Rx java in action
Rx java in actionRx java in action
Rx java in action
 
Current State of Coroutines
Current State of CoroutinesCurrent State of Coroutines
Current State of Coroutines
 
Lock? We don't need no stinkin' locks!
Lock? We don't need no stinkin' locks!Lock? We don't need no stinkin' locks!
Lock? We don't need no stinkin' locks!
 
Locks? We Don't Need No Stinkin' Locks - Michael Barker
Locks? We Don't Need No Stinkin' Locks - Michael BarkerLocks? We Don't Need No Stinkin' Locks - Michael Barker
Locks? We Don't Need No Stinkin' Locks - Michael Barker
 
LetSwift RxSwift 시작하기
LetSwift RxSwift 시작하기LetSwift RxSwift 시작하기
LetSwift RxSwift 시작하기
 
Scalaz 8 vs Akka Actors
Scalaz 8 vs Akka ActorsScalaz 8 vs Akka Actors
Scalaz 8 vs Akka Actors
 
Introduction to Scala
Introduction to ScalaIntroduction to Scala
Introduction to Scala
 
RxJS101 - What you need to know to get started with RxJS tomorrow
RxJS101 - What you need to know to get started with RxJS tomorrowRxJS101 - What you need to know to get started with RxJS tomorrow
RxJS101 - What you need to know to get started with RxJS tomorrow
 
Reactive programming on Android
Reactive programming on AndroidReactive programming on Android
Reactive programming on Android
 
[245] presto 내부구조 파헤치기
[245] presto 내부구조 파헤치기[245] presto 내부구조 파헤치기
[245] presto 내부구조 파헤치기
 

More from Fabio Collini

Architectures in the compose world
Architectures in the compose worldArchitectures in the compose world
Architectures in the compose world
Fabio Collini
 
Using hilt in a modularized project
Using hilt in a modularized projectUsing hilt in a modularized project
Using hilt in a modularized project
Fabio Collini
 
Managing parallelism using coroutines
Managing parallelism using coroutinesManaging parallelism using coroutines
Managing parallelism using coroutines
Fabio Collini
 
Kotlin Delegates in practice - Kotlin community conf
Kotlin Delegates in practice - Kotlin community confKotlin Delegates in practice - Kotlin community conf
Kotlin Delegates in practice - Kotlin community conf
Fabio Collini
 
Kotlin delegates in practice - Kotlin Everywhere Stockholm
Kotlin delegates in practice - Kotlin Everywhere StockholmKotlin delegates in practice - Kotlin Everywhere Stockholm
Kotlin delegates in practice - Kotlin Everywhere Stockholm
Fabio Collini
 
Using Dagger in a Clean Architecture project
Using Dagger in a Clean Architecture projectUsing Dagger in a Clean Architecture project
Using Dagger in a Clean Architecture project
Fabio Collini
 
SOLID principles in practice: the Clean Architecture - Devfest Emila Romagna
SOLID principles in practice: the Clean Architecture - Devfest Emila RomagnaSOLID principles in practice: the Clean Architecture - Devfest Emila Romagna
SOLID principles in practice: the Clean Architecture - Devfest Emila Romagna
Fabio Collini
 
SOLID principles in practice: the Clean Architecture
SOLID principles in practice: the Clean ArchitectureSOLID principles in practice: the Clean Architecture
SOLID principles in practice: the Clean Architecture
Fabio Collini
 
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf MilanFrom Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
Fabio Collini
 
Recap Google I/O 2018
Recap Google I/O 2018Recap Google I/O 2018
Recap Google I/O 2018
Fabio Collini
 
From java to kotlin beyond alt+shift+cmd+k - Droidcon italy
From java to kotlin beyond alt+shift+cmd+k - Droidcon italyFrom java to kotlin beyond alt+shift+cmd+k - Droidcon italy
From java to kotlin beyond alt+shift+cmd+k - Droidcon italy
Fabio Collini
 
From java to kotlin beyond alt+shift+cmd+k
From java to kotlin beyond alt+shift+cmd+kFrom java to kotlin beyond alt+shift+cmd+k
From java to kotlin beyond alt+shift+cmd+k
Fabio Collini
 
Testing Android apps based on Dagger and RxJava Droidcon UK
Testing Android apps based on Dagger and RxJava Droidcon UKTesting Android apps based on Dagger and RxJava Droidcon UK
Testing Android apps based on Dagger and RxJava Droidcon UK
Fabio Collini
 
Intro to Retrofit 2 and RxJava2
Intro to Retrofit 2 and RxJava2Intro to Retrofit 2 and RxJava2
Intro to Retrofit 2 and RxJava2
Fabio Collini
 
Testing Android apps based on Dagger and RxJava
Testing Android apps based on Dagger and RxJavaTesting Android apps based on Dagger and RxJava
Testing Android apps based on Dagger and RxJava
Fabio Collini
 
Android Data Binding in action using MVVM pattern - droidconUK
Android Data Binding in action using MVVM pattern - droidconUKAndroid Data Binding in action using MVVM pattern - droidconUK
Android Data Binding in action using MVVM pattern - droidconUK
Fabio Collini
 
Data Binding in Action using MVVM pattern
Data Binding in Action using MVVM patternData Binding in Action using MVVM pattern
Data Binding in Action using MVVM pattern
Fabio Collini
 
Android Wear CodeLab - GDG Firenze
Android Wear CodeLab - GDG FirenzeAndroid Wear CodeLab - GDG Firenze
Android Wear CodeLab - GDG Firenze
Fabio Collini
 
Testable Android Apps using data binding and MVVM
Testable Android Apps using data binding and MVVMTestable Android Apps using data binding and MVVM
Testable Android Apps using data binding and MVVM
Fabio Collini
 
Introduction to Retrofit and RxJava
Introduction to Retrofit and RxJavaIntroduction to Retrofit and RxJava
Introduction to Retrofit and RxJava
Fabio Collini
 

More from Fabio Collini (20)

Architectures in the compose world
Architectures in the compose worldArchitectures in the compose world
Architectures in the compose world
 
Using hilt in a modularized project
Using hilt in a modularized projectUsing hilt in a modularized project
Using hilt in a modularized project
 
Managing parallelism using coroutines
Managing parallelism using coroutinesManaging parallelism using coroutines
Managing parallelism using coroutines
 
Kotlin Delegates in practice - Kotlin community conf
Kotlin Delegates in practice - Kotlin community confKotlin Delegates in practice - Kotlin community conf
Kotlin Delegates in practice - Kotlin community conf
 
Kotlin delegates in practice - Kotlin Everywhere Stockholm
Kotlin delegates in practice - Kotlin Everywhere StockholmKotlin delegates in practice - Kotlin Everywhere Stockholm
Kotlin delegates in practice - Kotlin Everywhere Stockholm
 
Using Dagger in a Clean Architecture project
Using Dagger in a Clean Architecture projectUsing Dagger in a Clean Architecture project
Using Dagger in a Clean Architecture project
 
SOLID principles in practice: the Clean Architecture - Devfest Emila Romagna
SOLID principles in practice: the Clean Architecture - Devfest Emila RomagnaSOLID principles in practice: the Clean Architecture - Devfest Emila Romagna
SOLID principles in practice: the Clean Architecture - Devfest Emila Romagna
 
SOLID principles in practice: the Clean Architecture
SOLID principles in practice: the Clean ArchitectureSOLID principles in practice: the Clean Architecture
SOLID principles in practice: the Clean Architecture
 
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf MilanFrom Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
From Java to Kotlin beyond alt+shift+cmd+k - Kotlin Community Conf Milan
 
Recap Google I/O 2018
Recap Google I/O 2018Recap Google I/O 2018
Recap Google I/O 2018
 
From java to kotlin beyond alt+shift+cmd+k - Droidcon italy
From java to kotlin beyond alt+shift+cmd+k - Droidcon italyFrom java to kotlin beyond alt+shift+cmd+k - Droidcon italy
From java to kotlin beyond alt+shift+cmd+k - Droidcon italy
 
From java to kotlin beyond alt+shift+cmd+k
From java to kotlin beyond alt+shift+cmd+kFrom java to kotlin beyond alt+shift+cmd+k
From java to kotlin beyond alt+shift+cmd+k
 
Testing Android apps based on Dagger and RxJava Droidcon UK
Testing Android apps based on Dagger and RxJava Droidcon UKTesting Android apps based on Dagger and RxJava Droidcon UK
Testing Android apps based on Dagger and RxJava Droidcon UK
 
Intro to Retrofit 2 and RxJava2
Intro to Retrofit 2 and RxJava2Intro to Retrofit 2 and RxJava2
Intro to Retrofit 2 and RxJava2
 
Testing Android apps based on Dagger and RxJava
Testing Android apps based on Dagger and RxJavaTesting Android apps based on Dagger and RxJava
Testing Android apps based on Dagger and RxJava
 
Android Data Binding in action using MVVM pattern - droidconUK
Android Data Binding in action using MVVM pattern - droidconUKAndroid Data Binding in action using MVVM pattern - droidconUK
Android Data Binding in action using MVVM pattern - droidconUK
 
Data Binding in Action using MVVM pattern
Data Binding in Action using MVVM patternData Binding in Action using MVVM pattern
Data Binding in Action using MVVM pattern
 
Android Wear CodeLab - GDG Firenze
Android Wear CodeLab - GDG FirenzeAndroid Wear CodeLab - GDG Firenze
Android Wear CodeLab - GDG Firenze
 
Testable Android Apps using data binding and MVVM
Testable Android Apps using data binding and MVVMTestable Android Apps using data binding and MVVM
Testable Android Apps using data binding and MVVM
 
Introduction to Retrofit and RxJava
Introduction to Retrofit and RxJavaIntroduction to Retrofit and RxJava
Introduction to Retrofit and RxJava
 

Recently uploaded

ACE - Team 24 Wrapup event at ahmedabad.
ACE - Team 24 Wrapup event at ahmedabad.ACE - Team 24 Wrapup event at ahmedabad.
ACE - Team 24 Wrapup event at ahmedabad.
Maitrey Patel
 
TMU毕业证书精仿办理
TMU毕业证书精仿办理TMU毕业证书精仿办理
TMU毕业证书精仿办理
aeeva
 
A Comprehensive Guide on Implementing Real-World Mobile Testing Strategies fo...
A Comprehensive Guide on Implementing Real-World Mobile Testing Strategies fo...A Comprehensive Guide on Implementing Real-World Mobile Testing Strategies fo...
A Comprehensive Guide on Implementing Real-World Mobile Testing Strategies fo...
kalichargn70th171
 
The Rising Future of CPaaS in the Middle East 2024
The Rising Future of CPaaS in the Middle East 2024The Rising Future of CPaaS in the Middle East 2024
The Rising Future of CPaaS in the Middle East 2024
Yara Milbes
 
The Power of Visual Regression Testing_ Why It Is Critical for Enterprise App...
The Power of Visual Regression Testing_ Why It Is Critical for Enterprise App...The Power of Visual Regression Testing_ Why It Is Critical for Enterprise App...
The Power of Visual Regression Testing_ Why It Is Critical for Enterprise App...
kalichargn70th171
 
Assure Contact Center Experiences for Your Customers With ThousandEyes
Assure Contact Center Experiences for Your Customers With ThousandEyesAssure Contact Center Experiences for Your Customers With ThousandEyes
Assure Contact Center Experiences for Your Customers With ThousandEyes
ThousandEyes
 
Enums On Steroids - let's look at sealed classes !
Enums On Steroids - let's look at sealed classes !Enums On Steroids - let's look at sealed classes !
Enums On Steroids - let's look at sealed classes !
Marcin Chrost
 
Superpower Your Apache Kafka Applications Development with Complementary Open...
Superpower Your Apache Kafka Applications Development with Complementary Open...Superpower Your Apache Kafka Applications Development with Complementary Open...
Superpower Your Apache Kafka Applications Development with Complementary Open...
Paul Brebner
 
Alluxio Webinar | 10x Faster Trino Queries on Your Data Platform
Alluxio Webinar | 10x Faster Trino Queries on Your Data PlatformAlluxio Webinar | 10x Faster Trino Queries on Your Data Platform
Alluxio Webinar | 10x Faster Trino Queries on Your Data Platform
Alluxio, Inc.
 
一比一原版(USF毕业证)旧金山大学毕业证如何办理
一比一原版(USF毕业证)旧金山大学毕业证如何办理一比一原版(USF毕业证)旧金山大学毕业证如何办理
一比一原版(USF毕业证)旧金山大学毕业证如何办理
dakas1
 
Operational ease MuleSoft and Salesforce Service Cloud Solution v1.0.pptx
Operational ease MuleSoft and Salesforce Service Cloud Solution v1.0.pptxOperational ease MuleSoft and Salesforce Service Cloud Solution v1.0.pptx
Operational ease MuleSoft and Salesforce Service Cloud Solution v1.0.pptx
sandeepmenon62
 
如何办理(hull学位证书)英国赫尔大学毕业证硕士文凭原版一模一样
如何办理(hull学位证书)英国赫尔大学毕业证硕士文凭原版一模一样如何办理(hull学位证书)英国赫尔大学毕业证硕士文凭原版一模一样
如何办理(hull学位证书)英国赫尔大学毕业证硕士文凭原版一模一样
gapen1
 
一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理
一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理
一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理
dakas1
 
WMF 2024 - Unlocking the Future of Data Powering Next-Gen AI with Vector Data...
WMF 2024 - Unlocking the Future of Data Powering Next-Gen AI with Vector Data...WMF 2024 - Unlocking the Future of Data Powering Next-Gen AI with Vector Data...
WMF 2024 - Unlocking the Future of Data Powering Next-Gen AI with Vector Data...
Luigi Fugaro
 
J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...
J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...
J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...
Bert Jan Schrijver
 
DevOps Consulting Company | Hire DevOps Services
DevOps Consulting Company | Hire DevOps ServicesDevOps Consulting Company | Hire DevOps Services
DevOps Consulting Company | Hire DevOps Services
seospiralmantra
 
The Comprehensive Guide to Validating Audio-Visual Performances.pdf
The Comprehensive Guide to Validating Audio-Visual Performances.pdfThe Comprehensive Guide to Validating Audio-Visual Performances.pdf
The Comprehensive Guide to Validating Audio-Visual Performances.pdf
kalichargn70th171
 
Measures in SQL (SIGMOD 2024, Santiago, Chile)
Measures in SQL (SIGMOD 2024, Santiago, Chile)Measures in SQL (SIGMOD 2024, Santiago, Chile)
Measures in SQL (SIGMOD 2024, Santiago, Chile)
Julian Hyde
 
Unveiling the Advantages of Agile Software Development.pdf
Unveiling the Advantages of Agile Software Development.pdfUnveiling the Advantages of Agile Software Development.pdf
Unveiling the Advantages of Agile Software Development.pdf
brainerhub1
 
Modelling Up - DDDEurope 2024 - Amsterdam
Modelling Up - DDDEurope 2024 - AmsterdamModelling Up - DDDEurope 2024 - Amsterdam
Modelling Up - DDDEurope 2024 - Amsterdam
Alberto Brandolini
 

Recently uploaded (20)

ACE - Team 24 Wrapup event at ahmedabad.
ACE - Team 24 Wrapup event at ahmedabad.ACE - Team 24 Wrapup event at ahmedabad.
ACE - Team 24 Wrapup event at ahmedabad.
 
TMU毕业证书精仿办理
TMU毕业证书精仿办理TMU毕业证书精仿办理
TMU毕业证书精仿办理
 
A Comprehensive Guide on Implementing Real-World Mobile Testing Strategies fo...
A Comprehensive Guide on Implementing Real-World Mobile Testing Strategies fo...A Comprehensive Guide on Implementing Real-World Mobile Testing Strategies fo...
A Comprehensive Guide on Implementing Real-World Mobile Testing Strategies fo...
 
The Rising Future of CPaaS in the Middle East 2024
The Rising Future of CPaaS in the Middle East 2024The Rising Future of CPaaS in the Middle East 2024
The Rising Future of CPaaS in the Middle East 2024
 
The Power of Visual Regression Testing_ Why It Is Critical for Enterprise App...
The Power of Visual Regression Testing_ Why It Is Critical for Enterprise App...The Power of Visual Regression Testing_ Why It Is Critical for Enterprise App...
The Power of Visual Regression Testing_ Why It Is Critical for Enterprise App...
 
Assure Contact Center Experiences for Your Customers With ThousandEyes
Assure Contact Center Experiences for Your Customers With ThousandEyesAssure Contact Center Experiences for Your Customers With ThousandEyes
Assure Contact Center Experiences for Your Customers With ThousandEyes
 
Enums On Steroids - let's look at sealed classes !
Enums On Steroids - let's look at sealed classes !Enums On Steroids - let's look at sealed classes !
Enums On Steroids - let's look at sealed classes !
 
Superpower Your Apache Kafka Applications Development with Complementary Open...
Superpower Your Apache Kafka Applications Development with Complementary Open...Superpower Your Apache Kafka Applications Development with Complementary Open...
Superpower Your Apache Kafka Applications Development with Complementary Open...
 
Alluxio Webinar | 10x Faster Trino Queries on Your Data Platform
Alluxio Webinar | 10x Faster Trino Queries on Your Data PlatformAlluxio Webinar | 10x Faster Trino Queries on Your Data Platform
Alluxio Webinar | 10x Faster Trino Queries on Your Data Platform
 
一比一原版(USF毕业证)旧金山大学毕业证如何办理
一比一原版(USF毕业证)旧金山大学毕业证如何办理一比一原版(USF毕业证)旧金山大学毕业证如何办理
一比一原版(USF毕业证)旧金山大学毕业证如何办理
 
Operational ease MuleSoft and Salesforce Service Cloud Solution v1.0.pptx
Operational ease MuleSoft and Salesforce Service Cloud Solution v1.0.pptxOperational ease MuleSoft and Salesforce Service Cloud Solution v1.0.pptx
Operational ease MuleSoft and Salesforce Service Cloud Solution v1.0.pptx
 
如何办理(hull学位证书)英国赫尔大学毕业证硕士文凭原版一模一样
如何办理(hull学位证书)英国赫尔大学毕业证硕士文凭原版一模一样如何办理(hull学位证书)英国赫尔大学毕业证硕士文凭原版一模一样
如何办理(hull学位证书)英国赫尔大学毕业证硕士文凭原版一模一样
 
一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理
一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理
一比一原版(UMN毕业证)明尼苏达大学毕业证如何办理
 
WMF 2024 - Unlocking the Future of Data Powering Next-Gen AI with Vector Data...
WMF 2024 - Unlocking the Future of Data Powering Next-Gen AI with Vector Data...WMF 2024 - Unlocking the Future of Data Powering Next-Gen AI with Vector Data...
WMF 2024 - Unlocking the Future of Data Powering Next-Gen AI with Vector Data...
 
J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...
J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...
J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...
 
DevOps Consulting Company | Hire DevOps Services
DevOps Consulting Company | Hire DevOps ServicesDevOps Consulting Company | Hire DevOps Services
DevOps Consulting Company | Hire DevOps Services
 
The Comprehensive Guide to Validating Audio-Visual Performances.pdf
The Comprehensive Guide to Validating Audio-Visual Performances.pdfThe Comprehensive Guide to Validating Audio-Visual Performances.pdf
The Comprehensive Guide to Validating Audio-Visual Performances.pdf
 
Measures in SQL (SIGMOD 2024, Santiago, Chile)
Measures in SQL (SIGMOD 2024, Santiago, Chile)Measures in SQL (SIGMOD 2024, Santiago, Chile)
Measures in SQL (SIGMOD 2024, Santiago, Chile)
 
Unveiling the Advantages of Agile Software Development.pdf
Unveiling the Advantages of Agile Software Development.pdfUnveiling the Advantages of Agile Software Development.pdf
Unveiling the Advantages of Agile Software Development.pdf
 
Modelling Up - DDDEurope 2024 - Amsterdam
Modelling Up - DDDEurope 2024 - AmsterdamModelling Up - DDDEurope 2024 - Amsterdam
Modelling Up - DDDEurope 2024 - Amsterdam
 

Async code on kotlin: rx java or/and coroutines - Kotlin Night Turin

  • 1. ASYNC CODE ON KOTLIN: RXJAVA OR/AND COROUTINES Fabio Collini
  • 3.
  • 4.
  • 7. RxJava Coroutines-> RxJavaCoroutines -> rxCompletable, rxMaybe, rxSingle, rxObservable, rxFlowable CompletableSource.await, MaybeSource.await, MaybeSource.awaitOrDefault, MaybeSource.openSubscription, SingleSource.await, ObservableSource.awaitFirst, ObservableSource.awaitFirstOrDefault, ObservableSource.awaitFirstOrElse, ObservableSource.awaitFirstOrNull, ObservableSource.awaitLast, ObservableSource.awaitSingle, ObservableSource.openSubscription, ObservableSource.iterator github.com/Kotlin/kotlinx.coroutines/tree/master/reactive/kotlinx-coroutines-rx2
  • 8. Single Maybe Completable Observable Flowable Cold Vs Hot Subjects suspend methods Job/Deferred Channels Actors Producers Publishers BroadcastChannels
  • 9. Wrapper of a synchronous method fun myPref(): String = prefs.getString("myPref", "") fun myPref(): Single<String> = Single.fromCallable { prefs.getString("myPref", "") }1 suspend fun myPref(): String = withContext(CommonPool) { prefs.getString("myPref", "") }2 RxJavaCoroutines
  • 10. Thread & error management fun myPref(): Single<String> = Single.fromCallable { prefs.getString("myPref", "") }1 suspend fun myPref(): String = withContext(CommonPool) { prefs.getString("myPref", "") }2 myPref() .subscribeOn(io()) .observeOn(mainThread()) .subscribe( { myText.text = it }, { e -> myText.text = e.message } ) launch(CommonPool) { try { val value = myPref() withContext(UI) { myText.text = value } } catch (e: Exception) { withContext(UI) { myText.text = value } } } RxJava Coroutines
  • 11. Wrapper of an asynchronous method fun View.scale(v: Float): ViewPropertyAnimator { return animate() .scaleX(v) .scaleY(v) }4 text.setOnClickListener { text.scale(2f).withEndAction { text.scale(1f) }1 }2
  • 12. Wrapper of an asynchronous method fun View.scale(value: Float): Completable = Completable.create { emitter -> val animator = animate() animator.scaleX(value).scaleY(value).withEndAction { emitter.onComplete() }3 }4 text.setOnClickListener { text.scale(2f) .andThen(text.scale(1f)) .subscribe() }2 RxJava
  • 13. Wrapper of an asynchronous method fun View.scale(value: Float): Completable = Completable.create { emitter -> val animator = animate() animator.scaleX(value).scaleY(value).withEndAction { emitter.setCancellable(null) emitter.onComplete() } emitter.setCancellable { animator.cancel() }3 }4 RxJava
  • 14. Wrapper of an asynchronous method suspend fun View.scale(v: Float) = suspendCoroutine<Unit> { continuation -> animate() .scaleX(v) .scaleY(v) .withEndAction { continuation.resume(Unit) } }1 text.setOnClickListener { launch(UI) { text.scale(2f) text.scale(1f) } } Coroutines
  • 15. Wrapper of an asynchronous method suspend fun View.scale(v: Float) = suspendCancellableCoroutine<Unit> { continuation -> val animator = animate() animator .scaleX(v) .scaleY(v) .withEndAction { continuation.resume(Unit) } continuation.invokeOnCancellation { animator.cancel() } }1 Coroutines
  • 16. suspend fun View.scale(v: Float) = suspendCoroutine<Unit> { continuation -> animate() .scaleX(v) .scaleY(v) .withEndAction { continuation.resume(Unit) }3 }4 launch(UI) { text.scale(2f) println(“Where am I?”) }5 fun View.scale(value: Float): Completable = Completable.create { emitter -> animate() .scaleX(value) .scaleY(value) .withEndAction_{ emitter.onComplete() }1 }2 text.scale(2f) .doOnComplete { println("Where am I?") } .subscribe() Threading RxJava Coroutines
  • 17. suspend fun View.scale(v: Float) = suspendCoroutine<Unit> { continuation -> animate() .scaleX(v) .scaleY(v) .withEndAction { thread { continuation.resume(Unit) } }3 }4 launch(UI) { text.scale(2f) println(“Where am I?”) }5 fun View.scale(value: Float): Completable = Completable.create { emitter -> animate() .scaleX(value) .scaleY(value) .withEndAction_{ thread_{ emitter.onComplete() }_ }1 }2 text.scale(2f) .doOnComplete { println("Where am I?") } .subscribe() Threading RxJava Coroutines
  • 18. fun View.scale(value: Float): Completable = Completable.create { emitter -> animate() .scaleX(value) .scaleY(value) .withEndAction_{ thread_{ emitter.onComplete() }_ }1 }2 text.scale(2f) .observeOn(AndroidSchedulers.mainThread()) .doOnComplete { println("Where am I?") } .subscribe() Threading RxJava
  • 19. interface StackOverflowService { @GET("/users") fun getTopUsers(): Single<List<User>> @GET("/users/{userId}/badges") fun getBadges( @Path("userId") userId: Int ): Single<List<Badge>> @GET("/users/{userId}/top-tags") fun getTags( @Path("userId") userId: Int ): Single<List<Tag>> }0 interface StackOverflowService { @GET("/users") fun getTopUsers(): Deferred<List<User>> @GET("/users/{userId}/badges") fun getBadges( @Path("userId") userId: Int ): Deferred<List<Badge>> @GET("/users/{userId}/top-tags") fun getTags( @Path("userId") userId: Int ): Deferred<List<Tag>> }1 RxJava Coroutines
  • 20. class MyViewModel( private val service: StackOverflowService ) : ViewModel() { private val disposable = CompositeDisposable() fun load() { disposable += service.getTopUsers() .subscribeOn(io()) .observeOn(mainThread()) .subscribe( { users -> updateUi(users) }, { e -> updateUi(e) } )1 }A private fun updateUi(s: Any) { //... }B override fun onCleared() { disposable.clear() }C }D class MyViewModel( private val service: StackOverflowService ) : ViewModel() { private val job = Job() fun load() { launch(CommonPool + job) { try { val users = service.getTopUsers().await() updateUi(users) } catch (e: Exception) { updateUi(e) }4 }5 }E private suspend fun updateUi(s: Any) { withContext(UI) { //... }F }1 override fun onCleared() { job.cancel() }G }H RxJava Coroutines
  • 21. service.getTopUsers() .subscribeOn(io()) .observeOn(mainThread()) .subscribe( { users -> updateUi(users) }, { e -> updateUi(e) } )1 launch(CommonPool + job) { try { val users = service.getTopUsers().await() updateUi(users) } catch (e: Exception) { updateUi(e) }4 }5 RxJava Coroutines
  • 22. service.getTopUsers() .map_{_it.first()_}_ .flatMap_{_firstUser_->_ service.getBadges(firstUser.id) }0 .subscribeOn(io()) .observeOn(mainThread()) .subscribe( {_badges_->_updateUi(badges)_}, { e -> updateUi(e) } )1 launch(CommonPool + job) { try { val users = service.getTopUsers().await() val firstUser = users.first() val badges = service.getBadges( firstUser.id).await() updateUi(badges) } catch (e: Exception) { updateUi(e) }4 }5 RxJava Coroutines
  • 23. updateUi("loading users") service.getTopUsers() .observeOn(mainThread()) .doOnSuccess { updateUi("loading badges") } .observeOn(io()) .map_{_it.first()_}_ .flatMap_{_firstUser_->_ service.getBadges(firstUser.id) }0 .subscribeOn(io()) .observeOn(mainThread()) .subscribe( {_badges_->_updateUi(badges)_}, { e -> updateUi(e) } )1 launch(CommonPool + job) { try { updateUi("loading users") val users = service.getTopUsers().await() updateUi("loading badges") val firstUser = users.first() val badges = service.getBadges( firstUser.id).await() updateUi(badges) } catch (e: Exception) { updateUi(e) }4 }5 RxJava Coroutines
  • 24. service.getTopUsers() .map_{_it.first()_}_ .flatMap_{_firstUser_->_ service.getBadges(firstUser.id) .map { badges -> UserStats(firstUser, badges) }p }0 .subscribeOn(io()) .observeOn(mainThread()) .subscribe( {_user_->_updateUi(user)_}, { e -> updateUi(e) } )1 launch(CommonPool + job) { try { val users = service.getTopUsers().await() val firstUser = users.first() val badges = service.getBadges( firstUser.id).await() val user = UserStats(firstUser, badges) updateUi(user) } catch (e: Exception) { updateUi(e) }4 }5 RxJava Coroutines
  • 25. service.getTopUsers() .flattenAsObservable { it.take(5) } .concatMapEager { user -> service.getBadges(user.id) .map { badges -> UserStats(user, badges) }p .toObservable() }0 .toList() .subscribeOn(io()) .observeOn(mainThread()) .subscribe( { usersWithBadges -> updateUi(usersWithBadges) }, { e -> updateUi(e) } )1 launch(CommonPool + job) { try { val users = service.getTopUsers().await() val usersWithBadges = users.take(5) .map { it to service.getBadges(it.id) } .map { (user, badges) -> UserStats(user, badges.await()) } updateUi(usersWithBadges)1 } catch (e: Exception) { updateUi(e) }4 }5 RxJava Coroutines
  • 26. service.getTopUsers() .flattenAsObservable { it.take(5) } .concatMapEager { user -> service.getBadges(user.id) .map { badges -> UserStats(user, badges) }p .toObservable() }0 .toList() .subscribeOn(io()) .observeOn(mainThread()) .subscribe( { usersWithBadges -> updateUi(usersWithBadges) }, { e -> updateUi(e) } )1 launch(CommonPool + job) { try { val users = service.getTopUsers().await() val usersWithBadges: List<UserStats> = users.take(5) .map { user -> async(coroutineContext) { val badges = service.getBadges(user.id) UserStats(user, badges.await()) }r }t .map { it.await() } updateUi(usersWithBadges)1 } catch (e: Exception) { updateUi(e) }4 }5 RxJava Coroutines
  • 27. service.getTopUsers() .flattenAsObservable { it.take(5) } .concatMapEager { user -> userDetail(user).toObservable() }0 .toList() .subscribeOn(io()) .observeOn(mainThread()) .subscribe( { users -> updateUi(users) }, { e -> updateUi(e) } )1 fun userDetail(user: User): Single<UserStats> { return service.getBadges(user.id) .map { badges -> UserStats(user, badges) }7 }8 launch(CommonPool + job) { try { val users = service.getTopUsers().await() val usersWithBadges: List<UserStats> = users.take(5) .map { user -> async(coroutineContext) { userDetail(user) }r }t .map { it.await() } updateUi(usersWithBadges)1 } catch (e: Exception) { updateUi(e) }4 }5 suspend fun userDetail(user: User): UserStats { val badges = service.getBadges(user.id) return UserStats(user, badges.await()) }9 RxJava Coroutines
  • 28. fun userDetail(user: User): Single<UserStats> { return service.getBadges(user.id) .map { badges -> UserStats(user, badges) }7 }8 suspend fun userDetail(user: User): UserStats { val badges = service.getBadges(user.id) return UserStats(user, badges.await()) }9 RxJava Coroutines
  • 29. fun userDetail(user: User): Single<UserStats> { return Singles.zip( service.getBadges(user.id).subscribeOn(io()), service.getTags(user.id).subscribeOn(io()), { badges, tags -> UserStats(user, badges, tags) } ) }8 suspend fun userDetail(it: User): UserStats { val badges = service.getBadges(it.id) val tags = service.getTags(it.id) return UserStats(it, badges.await(), tags.await()) }9 RxJava Coroutines
  • 30. service.getTopUsers() .subscribeOn(io()) .observeOn(mainThread()) .subscribe( { users -> updateUi(users) }, { e -> updateUi(e) } )1 launch(CommonPool + job) { try { val users = service.getTopUsers().await() updateUi(users) } catch (e: Exception) { updateUi(e) }4 }5 RxJava Coroutines
  • 31. service.getTopUsers() .subscribeOn(io()) .observeOn(mainThread()) .timeout(10, SECONDS) .subscribe( { users -> updateUi(users) }, { e -> updateUi(e) } )1 launch(CommonPool + job) { try { withTimeout(10, SECONDS) { val users = service.getTopUsers().await() updateUi(users) }6 } catch (e: Exception) { updateUi(e) }4 }5 RxJava Coroutines
  • 32. service.getTopUsers() .subscribeOn(io()) .observeOn(mainThread()) .timeout(10, SECONDS) .retry(3) .subscribe( { users -> updateUi(users) }, { e -> updateUi(e) } )1 launch(CommonPool + job) { try { retry(3) { withTimeout(10, SECONDS) { val users = service.getTopUsers().await() updateUi(users) }6 }7 } catch_(e: Exception) { updateUi(e) }4 }5 RxJava Coroutines
  • 33. service.getTopUsers() .subscribeOn(io()) .observeOn(mainThread()) .timeout(10, SECONDS) .retry(3) .subscribe( { users -> updateUi(users) }, { e -> updateUi(e) } )1 launch(CommonPool + job) { try { retry(3) { withTimeout(10, SECONDS) { val users = service.getTopUsers().await() updateUi(users) }6 }7 } catch_(e: Exception) { updateUi(e) }4 }5 suspend fun <T> retry(attempts: Int = 5, f: suspend () -> T): T { repeat(attempts - 1) { try { return f() } catch (e: Exception) { } } return f() } RxJava Coroutines
  • 34. service.getTopUsers() .subscribeOn(io()) .observeOn(mainThread()) .timeout(10, SECONDS) .retryWhen(ExponentialBackoff(3)) .subscribe( { users -> updateUi(users) }, { e -> updateUi(e) } )1 launch(CommonPool + job) { try { exponentialBackoff(3) { withTimeout(10, SECONDS) { val users = service.getTopUsers().await() updateUi(users) }6 }7 } catch_(e: Exception) { updateUi(e) }4 }5 RxJava Coroutines
  • 35. service.getTopUsers() .subscribeOn(io()) .observeOn(mainThread()) .timeout(10, SECONDS) .retryWhen(ExponentialBackoff(3)) .subscribe( { users -> updateUi(users) }, { e -> updateUi(e) } )1 class ExponentialBackoff(private val maxRetries: Int) : Function1<Flowable<out Throwable>, Publisher<*>> { private var retryCount = 0 private var currentDelay = 100L + Random().nextInt(100) override fun invoke(attempts: Flowable<out Throwable>): Publisher<*> { return attempts .flatMap { throwable -> if (++retryCount < maxRetries) Flowable.timer(currentDelay, MILLISECONDS).also { currentDelay *= 2 } else Flowable.error(throwable) } } } launch(CommonPool + job) { try { exponentialBackoff(3) { withTimeout(10, SECONDS) { val users = service.getTopUsers().await() updateUi(users) }6 }7 } catch_(e: Exception) { updateUi(e) }4 }5 suspend fun <T> exponentialBackoff( times: Int = 5, f: suspend () -> T): T { var currentDelay = 100 + Random().nextInt(100) repeat(times - 1) { try { return f() } catch (e: Exception) { } delay(currentDelay) currentDelay *= 2 } return f() } RxJava Coroutines
  • 37. Testing RxJava JVM Trampoline scheduler blockingGet TestScheduler and TestObserver Espresso Schedulers.from(AsyncTask.THREAD_POOL_EXECUTOR) Coroutines JVM runBlocking Espresso AsyncTask.THREAD_POOL_EXECUTOR.asCoroutineDispatcher()
  • 38. 11051 io.reactivex 144 kotlin.coroutines 1984 kotlinx.coroutines Method count - debug
  • 39. 427 io.reactivex 77 kotlin.coroutines 493 kotlinx.coroutines Method count - release
  • 40. Links Demo Project github.com/fabioCollini/RxJavaVsCoroutines Guide to kotlinx.coroutines by example github.com/Kotlin/kotlinx.coroutines/blob/master/coroutines-guide.md Kotlin coroutines, a deeper look medium.com/@elizarov/kotlin-coroutines-a-deeper-look-180536305c3f Async code using Kotlin Coroutines proandroiddev.com/async-code-using-kotlin-coroutines-233d201099ff Testing asynchronous RxJava code using Mockito medium.com/@fabioCollini/testing-asynchronous-rxjava-code-using-mockito-8ad831a16877