Hi all. Wanted to see if I’m using `join` in a pro...
# coroutines
b
Hi all. Wanted to see if I’m using
join
in a proper manner and/or if there is a better way to do what I’m doing. I’m launching a coroutine that does some work (makes a few HTTP requests). Then later, in response to some event, I need to launch another coroutine to do some different work. When the 2nd coroutine is launched, I want to make sure the first coroutine is finished before the 2nd one does its work (it’s also ok if the first one was never launched at all). To accomplish this, I’m keeping a reference to the
Job
from the first coroutine, and calling its
join()
method from the second coroutine. A code sample is included in the 🧵 Two questions: 1. Is it OK to do it this way, or are there any problems with it? 2. Is there some better/more efficient way to do it?
My class looks something like this:
Copy code
class MyWorkerClass() {
    private var myJob: Job? = null

    fun doSomeInitialWork() {
        myJob = someCoroutineScope.launch {
            // Some long running work here
        }
    }

    fun doEvenMoreWork() {
        someOtherScope.launch {
            // make sure the initial work is finished
            // before we continue.
            // If the initial work was never started 
            // (myJob is null), that's OK. 
            myJob?.join()

            // Some long running work here
        }
    }
}
And I would use it like so:
Copy code
val worker = MyWorkerClass()

worker.doSomeInitialWork()

...

// then later when some event happens:
worker.doEvenMoreWork()
e
that looks to have potential race conditions around
myJob
if you want to ensure both are not running simultaneously, it would be safer and more typical to use sync primitives,
Copy code
private val mutex = Mutex()
suspend fun doSomeInitialWork() = mutex.withLock { ... }
suspend fun doEvenMoreWork() = mutex.withLock { ... }