10

I've been reading up on Kotlin co-routines but am not finding the answer to a specific problem.

Say I want to iterate over a collection making an API call for each element (in this particular case pushing a file to Amazon S3). I want these calls to be handled by an async coroutine so as not to block the underlying thread while waiting.

I do not need a return value from the request, only to log exceptions.

How would I create a "fire and forget" async coroutine to make one of these requests?

Ilya
  • 21,871
  • 8
  • 73
  • 92
Sherms
  • 1,567
  • 1
  • 15
  • 31

2 Answers2

6

Notice that, if no specific coroutine scope exists already (not a suspend function, i.e.) you can use:

fun Process (item: String): Response {
    GlobalScope.launch {
       ... <YOUR ASYNC (Processing) CODE GOES HERE> ...
    }
    ... <YOUR SYNC CODE GOES HERE> ...
    return Response("Your request for $item is being processed...")
}

This way you can return a quick answer (acting as an Acknowledge) stating that it has been received and you are processing it, without blocking the client/consumer, in a Fire&Forget fashion.

But be careful with posible memory leaks when the async part raises exceptions, for instance. Extending CoroutineScope is a better approach. More info at https://discuss.kotlinlang.org/t/unavoidable-memory-leak-when-using-coroutines/11603/7 and Why not use GlobalScope.launch?

Pau García
  • 151
  • 2
  • 9
-1

maybe kotlinx.coroutines#launch or kotlinx.coroutines#async meet your needs. for examples:

launch(CommonPool) {
    for(item in collection){
      val result = apiCall(item);
      log(result);
    }
}

OR

for(item in collection){
    launch(CommonPool) {
      val result = apiCall(item)
      log(result)
    }
}
holi-java
  • 29,655
  • 7
  • 72
  • 83
  • 9
    `launch` has to be placed inside a coroutine scope. Typical methods for creating scopes are blocking: `runBlocking` runs a new coroutine and blocks the current thread interruptibly until its completion, `coroutineScope` and `withContext` are a suspending functions, and OP wants to avoid suspensions. I believe OP wants to achieve a thing similar to Java's executors, where you can simply write: `executor.submit(job)` and forget. – itachi Sep 16 '21 at 23:45
  • 4
    This is a non-answer if you don't have a way to create a non-blocking scope. – Max Oct 26 '21 at 12:26