Reputation: 446
So I have a class that has a lifecycle, containing a start()
and an stop()
function to start and stop the lifecycle. Now in that start()
function I have to start a coroutine and in stop()
I have to cancel it (The coroutine in start()
runs infinitely until it is canceled, kinda like a socket listening for messages).
Because I would like a nice syntax to handle Coroutines I would like this class to implement CoroutineScope
. The thing is that start()
and stop()
can be called multiple times.
My question is if this implementation is valid and does not contain any errors. The purpose is to make a reusable CoroutineScope
.
class ReusableCoroutines() : CoroutineScope {
private var job = Job()
override val coroutineContext: CoroutineContext
get() = job
fun start() {
job = Job()
launch {
println("Started and running!")
while(true) {
}
}
}
fun stop() {
job.cancel()
println("Stoped")
}
}
Upvotes: 0
Views: 1891
Reputation: 30578
Disclaimer: I wouldn't do this. You don't get much out of reusable objects unless you are creating them by the thousands every seconds. I'd just create throwaway classes that are initialized on creation (without a start
function) and then cancel
led when stop
is called. That being said this might work:
class ReusableCoroutines(
private val scope: CoroutineScope = CoroutineScope(Dispatchers.Default)
) : CoroutineScope by scope {
private lateinit var job: Job
private var stopped: Boolean = false
private var started: Boolean = false
@Synchronized
fun start() {
require(stopped.not()) {
"Already stopped!"
}
require(started.not()) {
"Already started!"
}
job = launch {
println("Started and running!")
while (true) {
}
}
}
@Synchronized
fun stop() {
require(stopped.not()) {
"Already stopped!"
}
stopped = true
cancel()
println("Stopped")
}
}
So you need some synchronization @Synchronized
to prevent start being called from multiple threads and ending up in an inconsistent state.
You also take the scope
as a parameter so you can get Structured Concurrency with this. You can also add SupervisorJob
to scope
to prevent the parent from being canceled when you cancel this scope.
Upvotes: 1