SlideShare a Scribd company logo
1 of 55
Download to read offline
Should it be routine to use
Coroutines?
Stefan Brosteanu
Agenda
• Styles of writing code

• Deep dive into the inner workings of coroutines 

• Integration with other libraries 

• Short comparison to RxJava
Prologue
Refresh token
Post item using refreshed token
Refresh token
Post item using refreshed token
Refresh token
Post item using refreshed token
Refresh token
Post item using refreshed token
fun updateAccount(updatedUser: User) {
val token = refreshToken()
postUpdate(token, updatedUser)
}
fun updateAccount(updatedUser: User) {
val token = refreshToken()
postUpdate(token, updatedUser)
}
Refresh token
Post Item with refreshed
token
fun updateAccount(updatedUser: User) {
val token = refreshToken()
postUpdate(token, updatedUser)
}
Direct style
fun updateAccount(updatedUser: User) {
val token = refreshToken()
postUpdate(token, updatedUser)
}
Direct style
Action
fun updateAccount(updatedUser: User) {
val token = refreshToken()
postUpdate(token, updatedUser)
}
Direct style
Continuation
fun updateAccount(updatedUser: User) {
val token = refreshToken()
postUpdate(token, updatedUser)
}
Direct style
fun updateAccount(updatedUser: User) {
refreshToken { token ->
postUpdate(token, updatedUser)
}
}
fun updateAccount(updatedUser: User) {
refreshToken { token ->
postUpdate(token, updatedUser)
}
}
Continuation Passing Style
Asynchronous programming
Asynchronous Programming
• Async tasks

• Loaders

• Callbacks

• Promises

• Futures

• Reactive Extensions
Async tasks
• Labeled as “Painless Threading”

• Async Tasks don’t work well with orientations changes or might have
problems with the Lifecycle

• Limited to 138 concurrent tasks
Loaders
• Never really caught on

• Trying to solve the problem of running asynchronous operations within the
Activity or Fragments
Callbacks
• Error handling is cumbersome

• The dreaded Callback Hell
Promises/Futures
• introduce concept of operators

• relies on introspecting the value that needs to be returned
fun updateAccount(updatedUser: User) {
refreshToken()
.thenCompose { token ->
postUpdate(token, updatedUser)
}
}
fun refreshToken(): Promise<Token> {
...
return promise
}
Reactive Extensions
• simplifies the way you do async/threaded work

• simple to compose streams of data

• avoid callback hell

• a downside is that you shift from the normal programming model
Coroutines
What are coroutines?
• basically lightweight threads

• provide the same way of writing code both for async and sync

• exceptions handling, loops, etc. work like in synchronous code
What are coroutines?
suspend fun updateAccount(updatedUser: User) {
val token = refreshToken()
postUpdate(token, updatedUser)
}
How do coroutines work?
suspend fun refreshToken(): Token {
...
}
Object refreshToken(Continuation<Token> cont) {
...
}
Callback
interface Continuation<in T> {
val context: CoroutineContext
fun resume(value: T)
fun resumeWithException(exception: Throwable)
}
Is that really it?
suspend fun updateAccount(updatedUser: User) {
0 val token = refreshToken()
1 postUpdate(token, updatedUser)
2 }
class StateMachine(val updatedUser: User,
val updateAccountCallback: Continuation<Unit>)
: Continuation<Any?> {
var label: Int = 0
var token: String? = null
}
Deeper
suspend fun updateAccount(updatedUser: User) {
0 val token = refreshToken()
1 postUpdate(token, updatedUser)
2 }
when (sm.label) {
0 -> { sm.label = 1; refreshToken(sm) }
1 -> { sm.label = 2;
sm.token = value as String;
postUpdate(sm.token!!, updatedUser, sm)
}
2 -> { sm.updateAccountCallback.resume(Unit) }
}
Label is set to 0
Deeper
suspend fun updateAccount(updatedUser: User) {
0 val token = refreshToken()
1 postUpdate(token, updatedUser)
2 }
when (sm.label) {
0 -> { sm.label = 1; refreshToken(sm) }
1 -> { sm.label = 2;
sm.token = value as String;
postUpdate(sm.token!!, updatedUser, sm)
}
2 -> { sm.updateAccountCallback.resume(Unit) }
}
Label is set to 1
Deeper
suspend fun updateAccount(updatedUser: User) {
0 val token = refreshToken()
1 postUpdate(token, updatedUser)
2 }
when (sm.label) {
0 -> { sm.label = 1; refreshToken(sm) }
1 -> { sm.label = 2;
sm.token = value as String;
postUpdate(sm.token!!, updatedUser, sm)
}
2 -> { sm.updateAccountCallback.resume(Unit) }
}
Label is set to 2
Coroutine builders
suspend fun updateAccount(updatedUser: User) {
val token = refreshToken()
postUpdate(token, updatedUser)
}
Coroutine builders
fun updateAccount(updatedUser: User) {
launch {
val token = refreshToken()
postUpdate(token, updatedUser)
}
}
Coroutine builders
• launch 

• async

• withContext

• runBlocking
Coroutine context
fun updateAccount(updatedUser: User) {
launch {
val token = refreshToken()
postUpdate(token, updatedUser)
withContext (UI) {
// update UI
}
}
}
Coroutine context
• Unconfined

• CommonPool

• UI
Can they play well with others?
• Short answer: YES

• Long answer: with most or all libraries that use some sort of Future or
expose some kind of callback

• basically you need to create and/or apply a await extension function
How?
interface ApiService {
fun postUpdate(token: Token, updatedUser: User): Call<User>
}
How?
interface ApiService {
fun postUpdate(token: Token, updatedUser: User): Call<User>
}
suspend fun updateAccount(token: Token, updatedUser: User): User {
apiServiceInstance.updateAccount(token, updatedUser).await()
}
How?
suspend fun <T> Call.<T>.await(): T {
...
}
How?
suspend fun <T> Call<T>.await(): T {
enqueue(object : Callback<T> {
override fun onFailure(call: Call<T>, t: Throwable) {
TODO("not implemented")
}
override fun onResponse(call: Call<T>, response: Response<T>) {
TODO("not implemented")
}
})
}
How?
public suspend inline fun <T> suspendCoroutine(crossinline block: (Continuation<T>) -> Unit): T =
suspendCoroutineOrReturn { c: Continuation<T> ->
val safe = SafeContinuation(c)
block(safe)
safe.getResult()
}
How?
suspend fun <T> Call<T>.await(): T = suspendCoroutine { continuation ->
enqueue(object : Callback<T> {
override fun onFailure(call: Call<T>, t: Throwable) {
continuation.resumeWithException(t)
}
override fun onResponse(call: Call<T>, response: Response<T>) {
if (response.isSuccessful) {
continuation.resume(response.body()!!)
} else {
continuation.resumeWithException(Error(response.errorBody()!!))
}
}
})
}
How? - Sidenote
• JetBrains provides some out of the box integrations
How does it stack up against RxJava?
• Does it replace Rx?

• Is it better than Rx?
Why shouldn’t you use Rx?
• fluent API, but it leads to hard to read code and changing it might be
complex

• creating modular code that can be composed and still be readable is a
pain

• it’s overkill, most of the times
Why shouldn’t you use coroutines?
• if you’ve already learned Rx and the codebase is heavily relying on it

• sometimes composing and pub/sub-ing is easier with Rx

• if you’re codebase is written in Java

• community of developers using Rx is a tad larger (more questions on SO)
What else is there?
What else is there?
• Cancellation

• Composition

• Channels 

• Actors

• Coroutine scope
Epilogue
Epilogue
• Direct Style and Continuation Passing Style ✅ 

• Deep dive into the inner workings of coroutines ✅ 

• Integration with other libraries ✅ 

• Short comparison to RxJava ✅
Should it be routine to use
coroutines?
Resources
• https://kotlinlang.org/docs/reference/coroutines.html

• https://github.com/Kotlin/kotlin-coroutines/blob/master/kotlin-coroutines-
informal.md

• https://github.com/Kotlin/kotlinx.coroutines/blob/master/coroutines-
guide.md

• KotlinConf 2017 - Deep Dive into Coroutines on JVM by Roman Elizarov
Thank you!
Stefan Brosteanu
@stef.brosteanu
sbrosteanu

More Related Content

What's hot

I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits
I/O, You Own: Regaining Control of Your Disk in the Presence of BootkitsI/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits
I/O, You Own: Regaining Control of Your Disk in the Presence of BootkitsCrowdStrike
 
Multiplayer Java Game
Multiplayer Java GameMultiplayer Java Game
Multiplayer Java Gamekarim baidar
 
Implementações paralelas
Implementações paralelasImplementações paralelas
Implementações paralelasWillian Molinari
 
Kotlin Coroutines Reloaded
Kotlin Coroutines ReloadedKotlin Coroutines Reloaded
Kotlin Coroutines ReloadedRoman Elizarov
 
Treasure Data Summer Internship Final Report
Treasure Data Summer Internship Final ReportTreasure Data Summer Internship Final Report
Treasure Data Summer Internship Final ReportRitta Narita
 
Easy Steps to implement UDP Server and Client Sockets
Easy Steps to implement UDP Server and Client SocketsEasy Steps to implement UDP Server and Client Sockets
Easy Steps to implement UDP Server and Client Socketsbabak danyal
 
4Developers: Michał Szczepanik- Kotlin - Let’s ketchup it
4Developers: Michał Szczepanik- Kotlin - Let’s ketchup it4Developers: Michał Szczepanik- Kotlin - Let’s ketchup it
4Developers: Michał Szczepanik- Kotlin - Let’s ketchup itPROIDEA
 
4Developers: Dominik Przybysz- Message Brokers
4Developers: Dominik Przybysz- Message Brokers4Developers: Dominik Przybysz- Message Brokers
4Developers: Dominik Przybysz- Message BrokersPROIDEA
 
Networking & Socket Programming In Java
Networking & Socket Programming In JavaNetworking & Socket Programming In Java
Networking & Socket Programming In JavaAnkur Agrawal
 
Concurrency Utilities in Java 8
Concurrency Utilities in Java 8Concurrency Utilities in Java 8
Concurrency Utilities in Java 8Martin Toshev
 
Python session.11 By Shanmugam
Python session.11 By ShanmugamPython session.11 By Shanmugam
Python session.11 By ShanmugamNavaneethan Naveen
 
Vapor – Swift is not only for iOS anymore
Vapor – Swift is not only for iOS anymoreVapor – Swift is not only for iOS anymore
Vapor – Swift is not only for iOS anymoreMilan Vít
 
Ruby Concurrency and EventMachine
Ruby Concurrency and EventMachineRuby Concurrency and EventMachine
Ruby Concurrency and EventMachineChristopher Spring
 
Socket programming using java
Socket programming using javaSocket programming using java
Socket programming using javaUC San Diego
 
Concurrency at the Database Layer
Concurrency at the Database Layer Concurrency at the Database Layer
Concurrency at the Database Layer mcwilson1
 
A Short Java Socket Tutorial
A Short Java Socket TutorialA Short Java Socket Tutorial
A Short Java Socket TutorialGuo Albert
 
Communication in Python and the C10k problem
Communication in Python and the C10k problemCommunication in Python and the C10k problem
Communication in Python and the C10k problemJose Galarza
 

What's hot (20)

I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits
I/O, You Own: Regaining Control of Your Disk in the Presence of BootkitsI/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits
I/O, You Own: Regaining Control of Your Disk in the Presence of Bootkits
 
Java sockets
Java socketsJava sockets
Java sockets
 
Multiplayer Java Game
Multiplayer Java GameMultiplayer Java Game
Multiplayer Java Game
 
Implementações paralelas
Implementações paralelasImplementações paralelas
Implementações paralelas
 
Kotlin Coroutines Reloaded
Kotlin Coroutines ReloadedKotlin Coroutines Reloaded
Kotlin Coroutines Reloaded
 
Treasure Data Summer Internship Final Report
Treasure Data Summer Internship Final ReportTreasure Data Summer Internship Final Report
Treasure Data Summer Internship Final Report
 
Easy Steps to implement UDP Server and Client Sockets
Easy Steps to implement UDP Server and Client SocketsEasy Steps to implement UDP Server and Client Sockets
Easy Steps to implement UDP Server and Client Sockets
 
4Developers: Michał Szczepanik- Kotlin - Let’s ketchup it
4Developers: Michał Szczepanik- Kotlin - Let’s ketchup it4Developers: Michał Szczepanik- Kotlin - Let’s ketchup it
4Developers: Michał Szczepanik- Kotlin - Let’s ketchup it
 
4Developers: Dominik Przybysz- Message Brokers
4Developers: Dominik Przybysz- Message Brokers4Developers: Dominik Przybysz- Message Brokers
4Developers: Dominik Przybysz- Message Brokers
 
Networking & Socket Programming In Java
Networking & Socket Programming In JavaNetworking & Socket Programming In Java
Networking & Socket Programming In Java
 
Concurrency Utilities in Java 8
Concurrency Utilities in Java 8Concurrency Utilities in Java 8
Concurrency Utilities in Java 8
 
Python session.11 By Shanmugam
Python session.11 By ShanmugamPython session.11 By Shanmugam
Python session.11 By Shanmugam
 
Powershell alias
Powershell aliasPowershell alias
Powershell alias
 
Vapor – Swift is not only for iOS anymore
Vapor – Swift is not only for iOS anymoreVapor – Swift is not only for iOS anymore
Vapor – Swift is not only for iOS anymore
 
Ruby Concurrency and EventMachine
Ruby Concurrency and EventMachineRuby Concurrency and EventMachine
Ruby Concurrency and EventMachine
 
Socket programming using java
Socket programming using javaSocket programming using java
Socket programming using java
 
Concurrency at the Database Layer
Concurrency at the Database Layer Concurrency at the Database Layer
Concurrency at the Database Layer
 
Java NIO.2
Java NIO.2Java NIO.2
Java NIO.2
 
A Short Java Socket Tutorial
A Short Java Socket TutorialA Short Java Socket Tutorial
A Short Java Socket Tutorial
 
Communication in Python and the C10k problem
Communication in Python and the C10k problemCommunication in Python and the C10k problem
Communication in Python and the C10k problem
 

Similar to Should it be routine to use coroutines?

Software Transactioneel Geheugen
Software Transactioneel GeheugenSoftware Transactioneel Geheugen
Software Transactioneel GeheugenDevnology
 
Clojure concurrency
Clojure concurrencyClojure concurrency
Clojure concurrencyAlex Navis
 
JVMLS 2016. Coroutines in Kotlin
JVMLS 2016. Coroutines in KotlinJVMLS 2016. Coroutines in Kotlin
JVMLS 2016. Coroutines in KotlinAndrey Breslav
 
Evolution of asynchrony in (ASP).NET
Evolution of asynchrony in (ASP).NETEvolution of asynchrony in (ASP).NET
Evolution of asynchrony in (ASP).NETAliaksandr Famin
 
Runtime Bytecode Transformation for Smalltalk
Runtime Bytecode Transformation for SmalltalkRuntime Bytecode Transformation for Smalltalk
Runtime Bytecode Transformation for SmalltalkESUG
 
Intro to Asynchronous Javascript
Intro to Asynchronous JavascriptIntro to Asynchronous Javascript
Intro to Asynchronous JavascriptGarrett Welson
 
Reactive cocoa made Simple with Swift
Reactive cocoa made Simple with SwiftReactive cocoa made Simple with Swift
Reactive cocoa made Simple with SwiftColin Eberhardt
 
Is your C# optimized
Is your C# optimizedIs your C# optimized
Is your C# optimizedWoody Pewitt
 
Kamaelia Protocol Walkthrough
Kamaelia Protocol WalkthroughKamaelia Protocol Walkthrough
Kamaelia Protocol Walkthroughkamaelian
 
Writing Asynchronous Programs with Scala & Akka
Writing Asynchronous Programs with Scala & AkkaWriting Asynchronous Programs with Scala & Akka
Writing Asynchronous Programs with Scala & AkkaYardena Meymann
 
Async Debugging A Practical Guide to survive !
Async Debugging A Practical Guide to survive !Async Debugging A Practical Guide to survive !
Async Debugging A Practical Guide to survive !Mirco Vanini
 
Job Queue in Golang
Job Queue in GolangJob Queue in Golang
Job Queue in GolangBo-Yi Wu
 
Formal Verification of Transactional Interaction Contract
Formal Verification of Transactional Interaction ContractFormal Verification of Transactional Interaction Contract
Formal Verification of Transactional Interaction ContractGera Shegalov
 
Coroutines in Kotlin. In-depth review
Coroutines in Kotlin. In-depth reviewCoroutines in Kotlin. In-depth review
Coroutines in Kotlin. In-depth reviewDmytro 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
 
Runtime Bytecode Transformation for Smalltalk
Runtime Bytecode Transformation for SmalltalkRuntime Bytecode Transformation for Smalltalk
Runtime Bytecode Transformation for SmalltalkMarcus Denker
 
How to build twitter bot using golang from scratch
How to build twitter bot using golang from scratchHow to build twitter bot using golang from scratch
How to build twitter bot using golang from scratchKaty Slemon
 

Similar to Should it be routine to use coroutines? (20)

Software Transactioneel Geheugen
Software Transactioneel GeheugenSoftware Transactioneel Geheugen
Software Transactioneel Geheugen
 
Clojure concurrency
Clojure concurrencyClojure concurrency
Clojure concurrency
 
Little Big Ruby
Little Big RubyLittle Big Ruby
Little Big Ruby
 
JVMLS 2016. Coroutines in Kotlin
JVMLS 2016. Coroutines in KotlinJVMLS 2016. Coroutines in Kotlin
JVMLS 2016. Coroutines in Kotlin
 
Evolution of asynchrony in (ASP).NET
Evolution of asynchrony in (ASP).NETEvolution of asynchrony in (ASP).NET
Evolution of asynchrony in (ASP).NET
 
Runtime Bytecode Transformation for Smalltalk
Runtime Bytecode Transformation for SmalltalkRuntime Bytecode Transformation for Smalltalk
Runtime Bytecode Transformation for Smalltalk
 
Kotlin Coroutines and Rx
Kotlin Coroutines and RxKotlin Coroutines and Rx
Kotlin Coroutines and Rx
 
Intro to Asynchronous Javascript
Intro to Asynchronous JavascriptIntro to Asynchronous Javascript
Intro to Asynchronous Javascript
 
Reactive cocoa made Simple with Swift
Reactive cocoa made Simple with SwiftReactive cocoa made Simple with Swift
Reactive cocoa made Simple with Swift
 
Tdd iPhone For Dummies
Tdd iPhone For DummiesTdd iPhone For Dummies
Tdd iPhone For Dummies
 
Is your C# optimized
Is your C# optimizedIs your C# optimized
Is your C# optimized
 
Kamaelia Protocol Walkthrough
Kamaelia Protocol WalkthroughKamaelia Protocol Walkthrough
Kamaelia Protocol Walkthrough
 
Writing Asynchronous Programs with Scala & Akka
Writing Asynchronous Programs with Scala & AkkaWriting Asynchronous Programs with Scala & Akka
Writing Asynchronous Programs with Scala & Akka
 
Async Debugging A Practical Guide to survive !
Async Debugging A Practical Guide to survive !Async Debugging A Practical Guide to survive !
Async Debugging A Practical Guide to survive !
 
Job Queue in Golang
Job Queue in GolangJob Queue in Golang
Job Queue in Golang
 
Formal Verification of Transactional Interaction Contract
Formal Verification of Transactional Interaction ContractFormal Verification of Transactional Interaction Contract
Formal Verification of Transactional Interaction Contract
 
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.
 
Runtime Bytecode Transformation for Smalltalk
Runtime Bytecode Transformation for SmalltalkRuntime Bytecode Transformation for Smalltalk
Runtime Bytecode Transformation for Smalltalk
 
How to build twitter bot using golang from scratch
How to build twitter bot using golang from scratchHow to build twitter bot using golang from scratch
How to build twitter bot using golang from scratch
 

Recently uploaded

9892124323 | Book Call Girls in Juhu and escort services 24x7
9892124323 | Book Call Girls in Juhu and escort services 24x79892124323 | Book Call Girls in Juhu and escort services 24x7
9892124323 | Book Call Girls in Juhu and escort services 24x7Pooja Nehwal
 
Model Call Girl in Shalimar Bagh Delhi reach out to us at 🔝8264348440🔝
Model Call Girl in Shalimar Bagh Delhi reach out to us at 🔝8264348440🔝Model Call Girl in Shalimar Bagh Delhi reach out to us at 🔝8264348440🔝
Model Call Girl in Shalimar Bagh Delhi reach out to us at 🔝8264348440🔝soniya singh
 
CALL ON ➥8923113531 🔝Call Girls Saharaganj Lucknow best sexual service
CALL ON ➥8923113531 🔝Call Girls Saharaganj Lucknow best sexual serviceCALL ON ➥8923113531 🔝Call Girls Saharaganj Lucknow best sexual service
CALL ON ➥8923113531 🔝Call Girls Saharaganj Lucknow best sexual serviceanilsa9823
 
Call US Pooja 9892124323 ✓Call Girls In Mira Road ( Mumbai ) secure service,
Call US Pooja 9892124323 ✓Call Girls In Mira Road ( Mumbai ) secure service,Call US Pooja 9892124323 ✓Call Girls In Mira Road ( Mumbai ) secure service,
Call US Pooja 9892124323 ✓Call Girls In Mira Road ( Mumbai ) secure service,Pooja Nehwal
 
哪里有卖的《俄亥俄大学学历证书+俄亥俄大学文凭证书+俄亥俄大学学位证书》Q微信741003700《俄亥俄大学学位证书复制》办理俄亥俄大学毕业证成绩单|购买...
哪里有卖的《俄亥俄大学学历证书+俄亥俄大学文凭证书+俄亥俄大学学位证书》Q微信741003700《俄亥俄大学学位证书复制》办理俄亥俄大学毕业证成绩单|购买...哪里有卖的《俄亥俄大学学历证书+俄亥俄大学文凭证书+俄亥俄大学学位证书》Q微信741003700《俄亥俄大学学位证书复制》办理俄亥俄大学毕业证成绩单|购买...
哪里有卖的《俄亥俄大学学历证书+俄亥俄大学文凭证书+俄亥俄大学学位证书》Q微信741003700《俄亥俄大学学位证书复制》办理俄亥俄大学毕业证成绩单|购买...wyqazy
 
Chandigarh Call Girls Service ❤️🍑 9115573837 👄🫦Independent Escort Service Cha...
Chandigarh Call Girls Service ❤️🍑 9115573837 👄🫦Independent Escort Service Cha...Chandigarh Call Girls Service ❤️🍑 9115573837 👄🫦Independent Escort Service Cha...
Chandigarh Call Girls Service ❤️🍑 9115573837 👄🫦Independent Escort Service Cha...Niamh verma
 
CALL ON ➥8923113531 🔝Call Girls Gomti Nagar Lucknow best Night Fun service
CALL ON ➥8923113531 🔝Call Girls Gomti Nagar Lucknow best Night Fun serviceCALL ON ➥8923113531 🔝Call Girls Gomti Nagar Lucknow best Night Fun service
CALL ON ➥8923113531 🔝Call Girls Gomti Nagar Lucknow best Night Fun serviceanilsa9823
 
Powerful Love Spells in Arkansas, AR (310) 882-6330 Bring Back Lost Lover
Powerful Love Spells in Arkansas, AR (310) 882-6330 Bring Back Lost LoverPowerful Love Spells in Arkansas, AR (310) 882-6330 Bring Back Lost Lover
Powerful Love Spells in Arkansas, AR (310) 882-6330 Bring Back Lost LoverPsychicRuben LoveSpells
 

Recently uploaded (8)

9892124323 | Book Call Girls in Juhu and escort services 24x7
9892124323 | Book Call Girls in Juhu and escort services 24x79892124323 | Book Call Girls in Juhu and escort services 24x7
9892124323 | Book Call Girls in Juhu and escort services 24x7
 
Model Call Girl in Shalimar Bagh Delhi reach out to us at 🔝8264348440🔝
Model Call Girl in Shalimar Bagh Delhi reach out to us at 🔝8264348440🔝Model Call Girl in Shalimar Bagh Delhi reach out to us at 🔝8264348440🔝
Model Call Girl in Shalimar Bagh Delhi reach out to us at 🔝8264348440🔝
 
CALL ON ➥8923113531 🔝Call Girls Saharaganj Lucknow best sexual service
CALL ON ➥8923113531 🔝Call Girls Saharaganj Lucknow best sexual serviceCALL ON ➥8923113531 🔝Call Girls Saharaganj Lucknow best sexual service
CALL ON ➥8923113531 🔝Call Girls Saharaganj Lucknow best sexual service
 
Call US Pooja 9892124323 ✓Call Girls In Mira Road ( Mumbai ) secure service,
Call US Pooja 9892124323 ✓Call Girls In Mira Road ( Mumbai ) secure service,Call US Pooja 9892124323 ✓Call Girls In Mira Road ( Mumbai ) secure service,
Call US Pooja 9892124323 ✓Call Girls In Mira Road ( Mumbai ) secure service,
 
哪里有卖的《俄亥俄大学学历证书+俄亥俄大学文凭证书+俄亥俄大学学位证书》Q微信741003700《俄亥俄大学学位证书复制》办理俄亥俄大学毕业证成绩单|购买...
哪里有卖的《俄亥俄大学学历证书+俄亥俄大学文凭证书+俄亥俄大学学位证书》Q微信741003700《俄亥俄大学学位证书复制》办理俄亥俄大学毕业证成绩单|购买...哪里有卖的《俄亥俄大学学历证书+俄亥俄大学文凭证书+俄亥俄大学学位证书》Q微信741003700《俄亥俄大学学位证书复制》办理俄亥俄大学毕业证成绩单|购买...
哪里有卖的《俄亥俄大学学历证书+俄亥俄大学文凭证书+俄亥俄大学学位证书》Q微信741003700《俄亥俄大学学位证书复制》办理俄亥俄大学毕业证成绩单|购买...
 
Chandigarh Call Girls Service ❤️🍑 9115573837 👄🫦Independent Escort Service Cha...
Chandigarh Call Girls Service ❤️🍑 9115573837 👄🫦Independent Escort Service Cha...Chandigarh Call Girls Service ❤️🍑 9115573837 👄🫦Independent Escort Service Cha...
Chandigarh Call Girls Service ❤️🍑 9115573837 👄🫦Independent Escort Service Cha...
 
CALL ON ➥8923113531 🔝Call Girls Gomti Nagar Lucknow best Night Fun service
CALL ON ➥8923113531 🔝Call Girls Gomti Nagar Lucknow best Night Fun serviceCALL ON ➥8923113531 🔝Call Girls Gomti Nagar Lucknow best Night Fun service
CALL ON ➥8923113531 🔝Call Girls Gomti Nagar Lucknow best Night Fun service
 
Powerful Love Spells in Arkansas, AR (310) 882-6330 Bring Back Lost Lover
Powerful Love Spells in Arkansas, AR (310) 882-6330 Bring Back Lost LoverPowerful Love Spells in Arkansas, AR (310) 882-6330 Bring Back Lost Lover
Powerful Love Spells in Arkansas, AR (310) 882-6330 Bring Back Lost Lover
 

Should it be routine to use coroutines?