简体   繁体   中英

Kotlin Coroutines - Different options for using Coroutine Scope/Context?

I'm new to Kotlin/Coroutines and I've noticed two different ways to use CoroutineScope .

Option 1 is as follows, within any function:

CoroutineScope(Dispatchers.Default).launch { 
    expensiveOperation() 
}

Option 2 is by implementing the CoroutineScope interface in your class, overriding the CoroutineContext , and then you can just launch coroutines easily with launch or async :

@Service
class ServiceImpl() : CoroutineScope {

    override val coroutineContext: CoroutineContext
        get() = Dispatchers.Default + Job()

    fun someFunction() {
        launch {
            expensiveOperation()
        }
    }
}

I am currently developing a backend endpoint that will do the following:

  1. take a request
  2. save the request context to a database
  3. launch a non blocking coroutine in the background to perform an expensive/lengthy operation on the request, and immediately return an http 200. (essentially, once we have the context saved, we can return a response and let the request process in the background)

What is the difference in the two use cases, and for this scenario, which is the preferred method for obtaining a CoroutineScope ?

This endpoint may receive multiple requests per second, and the lengthy operation will take a minute or two, so there will definitely be multiple requests processing at the same time, originating from various requests.

Also, if it's option 2, do I want to pass the scope/context to the function that does the heavy processing? Or is that unnecessary? For example:

class ServiceImpl() : CoroutineScope {

override val coroutineContext: CoroutineContext
    get() = Dispatchers.Default + Job()

fun someFunction() {
    launch {
        expensiveOperation(CoroutineScope(coroutineContext))
    }
}

private fun expensiveOperation(scope: CoroutineScope) 
    {
        // perform expensive operation
    }

}

This is a Spring Boot app, and I'm using version 1.3 of Kotlin .

Please let me know if you have any thoughts/suggestions on how to best structure this service class. Thanks

I would recommend option 2. It will give you chance to clearly define parent Job for all of your coroutines. That gives a chance to shut down the whole execution correctly too.

There are several more coroutine context keys to include - CoroutineName , CoroutineExceptionHandler and so one.

Lastly, the structural concurrency may work better if you pass the CoroutineScope and the associated Job explicitly.
https://medium.com/@elizarov/structured-concurrency-722d765aa952

Also, take a look the explanation on that form Roman: https://medium.com/@elizarov/coroutine-context-and-scope-c8b255d59055

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM