Coroutine and Multi-Task Problem

Tram Ho

Hi everybody. In asynchronous programming processing, people often encounter situations where multiple tasks are handled at the same time, or task tasks are processed one after another, one task depends on the results of the other. Today I would like to share some ways to solve this problem using Coroutine.

Consider a situation, where Task_1 is expecting an execution id of Task_2 with the id received from Response of Task_1 and based on the response from Task_2, the conditions and parameters of Task_3 will be changed.

Task_1 → Task_2 with id -> Task_3

How multiple dependent parallel tasks are implemented.

Normally, the first Task will be executed and after receiving the response (Response), data manipulation, the next call will be made.

Like the above implementation with the service tasks that depend on each other. We need to Sync up before manipulating the data, as well as processing with the next task.

With Couroutine there are a number of approaches, more optimal processing to handle data asynchronously and teaming results to implement the Business Logic of the problem.

Here are some approaches.

1. Concurrent Approach with Wait Time async-await with Kotlin Coroutines

Async will expect the Response of the task task. Here, Task_1 will provide data that will be synchronized with Task_2, etc. Then data manipulation can be performed with the received and processed Response. But it will have some waiting time between each call.

There is an implementation where we can combine calling multiple tasks at the same time.

2. Concurrent/ parallel Approach with thread switchingwithContext() will switch to seperate thread

It is similar to async-await. But somewhere will save money. Instead of deploying on the Main Thread, withcontext will switch to a separate Thread and perform the task. It won’t have a timeout like async-await.

If runBlocking is added overlapping withContext(), it will reverse the asynchronous and destructible nature of Coroutines and block the thread. Until the specific task is completed.

There are 5 types of Dispatchers. IO, Main, Default, New Thread, Unconfined

  • Default Dispatcher : This is the default dispatcher in most Coroutine systems. It uses a fixed thread pool to execute coroutines. While it’s useful for simple operations, it’s not suitable for resource-intensive or long-running operations.
  • IO Dispatcher : This Dispatcher is optimized for performing slow I/O operations, such as reading/writing data from disk or the network. Instead of using a fixed thread pool, IO Dispatcher usually uses some special I/O threads to make the most of system resources.
  • Unconfined Dispatcher : This type of dispatcher allows the coroutine to run on any thread. It is not associated with any particular thread and allows the coroutine to switch between threads during execution. This can be useful in some special cases, but can also cause problems with task synchronization and handling.
  • New Thread Dispatcher : This Dispatcher creates a new thread for each coroutine executed. This ensures that each coroutine will run independently on a separate thread. However, creating and managing multiple threads can affect performance and system resources.
  • Main Dispathcher : Special dispatcher type used to execute coroutines on the main thread of the application. The Main Dispatcher ensures that coroutines running on the main thread are not blocked during execution, to ensure user interface responsiveness.

3. Parallel Approach with data merging

The third approach is a bit different and if we want to have two independent tasks and concatenate them together for fresh response, then Zip Operator will help us to process them in parallel and give us the result. the results we need.

summary

Above, I have introduced 3 approaches and implementations, which you can use for each specific problem and requirement:

  • When we want to call multiple Tasks in parallel with timeouts, then the async-await approach will be suitable.
  • When we want a more efficient approach to switching Threads, withcontext will be suitable
  • And to concatenate two Responses together and do some data manipulation, the zip operator method is suitable.

Hope this article helps you more or less about some ways, some options to deal with all tasks, specifically here with Couroutine. See you all in the next post.

Share the news now

Source : Viblo