Kotlin Coroutines - Job and Timeout

Saurabh Pant
Dev Genius
Published in
3 min readJun 23, 2022

--

You got a job to do in time!

https://allf1.in/the-dominance-of-hamilton-bad-for-the-sport/

Coroutines are modern way of performing background processes in Android App Development and Ktor. In one of our articles in this coroutine series, we tried to understand the basics of coroutines. If you haven’t read it yet, have a look at it here.

In this article we’ll take on some basic understanding of the question:

  • Why to control coroutine lifecycle?
  • Ways to control coroutine lifecycle?

If you haven’t opted for them yet, it’s time to get started.

Why to control coroutine lifecycle?

Consider a scenario where we started a coroutine for some process but the user navigate away from the screen and the process is no longer required. In such scenario our coroutine would still be running until it completes.

Another scenario could be where our max execution time limit was say 3 seconds but the process took longer and our purpose of the process is now invalid.

One more could be that some computation is going on indefinitely and we need to exit due to any reason.

In all of the above and more similar scenarios, we need to some mechanism to control our coroutine from proceeding. Not doing so may leak our resources or can cause crashes or instability in our apps.

This brings us to our next question.

Ways to control coroutine lifecycle?

Using Job

We know that coroutine is launched using a coroutine builder. The coroutine builder returns us a job object. This job object is of type Job and can be used to cancel the coroutine.

As shown above, using the job object, we cancelled the job and then waited for its completion. Running the above code will result as

We launched a job which repeated the 0.5 seconds delay for 1000 times. This job is launched concurrently with respect to its parent coroutine which has a delay of 2 seconds and then it cancels this job. Here’s how the events took place:

  • started runBlocking first
  • then started launch block concurrently with parent code
  • parent code waited for 2 seconds and at the same time job executed 4 times 0 to 3
  • parent cancelled the job and waited for it to complete safely and exit
  • job cancelled
  • returned to main thread

So this how we controlled our coroutine execution using the job object.

Using cooperative cancellation

Cancelling a coroutine should be cooperative which means that any suspended computation should check if the coroutine is cancelled or not while executing. In case a coroutine is computing and not checked for cancellation then it can’t be cancelled. Let’s take an example as follow

Running this job and cancelling it won’t stop our coroutine because it is not checking if the coroutine it is called in, is cancelled or not. It’ll continue to run.

To fix this, we need to make sure that every computation should be cancellable by checking cancellation status of coroutine as follows:

Now, we’ve added a isActive flag which is provided by the coroutine scope itself. This flag will stop the execution once the job is cancelled.

In some cases, we need to perform some steps if the job is cancelled and we can do that in finally {} block because a cancelled job throws CancellationException which is an expected behavior in coroutines. That is why we don’t need catch block here.

Using timeout

We might need to cancel a job because it exceeded its time limit. Coroutine are provided with withTimeout function which does exactly the same for us. It throws TimeoutCancellationException on exceeding the time limit.

If you don’t need the exception then use the function withTimeoutOrNull which returns null on timeout.

Bamn! We’re now aware of how can we manage our coroutine execution and take finer control on our background tasks. Implement the code and play around for better understanding.

That is all for now! Stay tuned!

Follow me on medium(if the content is helpful to you) or on github and subscribe to email to be in sync for further interesting topics on Android.

Until next time…

Cheers!

--

--

App Developer (Native & Flutter) | Mentor | Writer | Youtuber @_zaqua | Traveller | Content Author & Course Instructor @Droidcon | Frontend Lead @MahilaMoney