frankelot
06/21/2021, 7:32 PMsend
something to an actor and “suspend” until the message was processed?frankelot
06/21/2021, 7:37 PMsuspending the caller while the buffer of this channel is full
I want to suspend more time, suspend until the actor picked up the message and processed it (picked up another one)Casey Brooks
06/21/2021, 7:41 PMFlow
is designed around the idea of the sender suspending until the collector finishes processing. If you’re already using an actor pattern, it might be difficult to convert it to a Flow, however, but might be something to look intofrankelot
06/21/2021, 7:45 PMfrankelot
06/21/2021, 7:46 PMfrankelot
06/21/2021, 7:47 PMfrankelot
06/21/2021, 7:47 PMCasey Brooks
06/21/2021, 7:53 PMcoroutineScope.launch { }
)?frankelot
06/21/2021, 7:58 PMval filter = BlurFilter() // expensive to create
fun render(value : Float) = launch {
filter.value = value
renderer.render(bitmap, filter) // Suspending, takes some time
}
// main:
for (i in 0..100) {
render(Math.nextFloat())
}
frankelot
06/21/2021, 7:58 PMfilter
frankelot
06/21/2021, 7:59 PMCasey Brooks
06/21/2021, 8:03 PMval filter = BlurFilter() // expensive to create
suspend fun render(value : Float) {
filter.value = value
renderer.render(bitmap, filter) // Suspending, takes some time
}
// main:
launch {
for (i in 0..100) {
render(Math.nextFloat())
}
}
Since render is marked suspend
, its caller will wait until it completes before continuing. In this example, that means
each iteration of the for
loop in main
will “suspend” until render
returns, so the next iteration of the loop will
only run once render
has finished and the filter is available for use again.frankelot
06/21/2021, 8:06 PMrender
gets called from very different places 🤔 but I’ll give it a tryCasey Brooks
06/21/2021, 8:12 PMfrankelot
06/21/2021, 8:31 PMfrankelot
06/21/2021, 8:37 PMlaunch {
at the top is kinda what I intended to do when using an actor 🙂… I can call render from multiple places and just send a message to the actor to process itfrankelot
06/21/2021, 8:38 PMfrankelot
06/21/2021, 8:40 PMsuspend fun render(target: Bitmap, filters: List<Filter>) {}
to
suspend fun render(target: Bitmap, filters: () -> List<Filter>) {}
frankelot
06/21/2021, 8:41 PMfrankelot
06/21/2021, 8:44 PMCasey Brooks
06/21/2021, 9:54 PMactor
function in the kotlinx.coutines library has been deprecated for quite a while now which suggests there are better ways to express your intent with other coroutines features.
The use-case you have and what you’re looking for definitely sounds more like standard suspending functions are a better way to go. There are several ways you could go with synchronizing the shared filter object that do not break the nice sequential nature of suspend functions: Mutex or Semaphore, for example, which you’d normally use in threading synchronization, but tailored for coroutines. https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.sync/index.htmlErik
06/22/2021, 5:39 AMrender
, then while one is suspended, another might set filter.value = value
concurrently. I don't know if that value is read instantly on set, but otherwise could this lead to race conditions? If so, consider using a rendezvous channel, a mutex or another synchronization primitive, so that operations are atomically processed.frankelot
06/22/2021, 12:27 PM