Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should be used a CoroutineScope's extension function or a suspending function

I'm writing an app using coroutines (code below is greatly simplified). Recently I've watched Coroutines in Practice talk and got a little confused. Turns out I don't know when to use a CoroutineScope's extension function and when to use a suspending function.

I have a mediator (Presenter/ViewModel/Controller/etc) that implements CoroutineScope:

class UiMediator : CoroutineScope {
    private val lifecycleJob: Job = Job()
    override val coroutineContext = lifecycleJob + CoroutineDispatchersProvider.MAIN
    // cancel parent Job somewhere

    fun getChannel() {
        launch {
            val channel = useCase.execute()
            view.show(channel)
        }
    }
}

Business logic (Interactor/UseCase):

class UseCase {
    suspend fun execute(): RssChannel = repository.getRssChannel()
}

And a repository:

class Repository {
    suspend fun getRssChannel(): RssChannel {
        // `getAllChannels` is a suspending fun that uses `withContext(IO)`
        val channels = localStore.getAllChannels()
        if (channels.isNotEmpty()) {
            return channels[0]
        }

        // `fetchChannel` is a suspending fun that uses `suspendCancellableCoroutine`
        // `saveChannel` is a suspending fun that uses `withContext(IO)`
        return remoteStore.fetchChannel()
            .also { localStore.saveChannel(it) }
    }
}

So I have a few questions:

  1. Should I declare Repository#getRssChannel as a CoroutineScope's extension function (because it spawns new suspending functions: getAllChannels, fetchChannel, saveChannel)? How can I use it in the UseCase then?
  2. Should I just wrap a Repository#getRssChannel into a coroutineScope function in order to make all spawned suspending functions to be children of the latter?
  3. Or maybe it's already fine and I should change nothing. When to declare a function as a CoroutineScope's extension then?
like image 831
Nikolay Kulachenko Avatar asked Oct 26 '25 23:10

Nikolay Kulachenko


1 Answers

A suspending function should return once it has completed its task, it executes something, possibly taking some time while not blocking the UI, and when it's done it returns.

A CoroutineScope extension function is for a fire-and-forget scenario, you call it, it spawns a coroutine and returns immediately, while the task continues to execute.

like image 186
Francesc Avatar answered Oct 29 '25 16:10

Francesc



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!