Search code examples
kotlinkotlin-coroutinescoroutinescope

Is there a way to prevent duplicate coroutine calls?


I'm fairly new to Kotlin coroutines - but is there a way to tag them and make sure only one of them is running at any given time?

GlobalScope.launch(Dispatchers.IO) {
    print("Hello World", timestamp)
}

GlobalScope.launch(Dispatchers.IO) {
    print("Hello World", timestamp)
}

// "Hello World" 1000
// "Hello World" 1000

I was hoping for a solution that resembles something like this

GlobalScope.launch(Dispatchers.IO, "tag_a") {
    print("Hello World", timestamp)
}

GlobalScope.launch(Dispatchers.IO, "tag_a") {
    print("Hello World", timestamp)
}

// "Hello World" 1000

Solution

  • I would suggest to create a nullable variable of type Job and assign a lauсhed job to it:

    private var job: Job? = null
    
    job = GlobalScope.launch(Dispatchers.IO, "tag_a") {
        print("Hello World", timestamp)
    }
    

    When trying to launch another coroutine just check whether this job is finished. So the whole code would look like the following:

    private var job: Job? = null
    
    @Synchronized
    fun doSomething() {
        val currentJob = job
        // launch if job is null or completed
        if (currentJob == null || currentJob.isCompleted) {
            job = GlobalScope.launch(Dispatchers.IO) {
                //print("Hello World", timestamp)
            }
        }
    }
    

    Btw, usage of GlobalScope is discouraged, consider creating your own scope.