Davide Giuseppe Farella
06/04/2019, 8:17 PMtseisel
06/05/2019, 8:30 AMactor
function, launch
with a reference to a Channel
is functionally the same thing.Davide Giuseppe Farella
06/05/2019, 8:40 AMactor
is a Channel
, the patterns is slightly different, since I don't think you would pass an actor as function paramtseisel
06/05/2019, 9:01 AMDavide Giuseppe Farella
06/05/2019, 9:32 AMString
and some images on disk to inline in the html, I do the following steps:
• Compress the images
• Base64 the images
• inline the images in html ( Document
from jsoup )
• Stringify the doc and deliver back
Actually my class implements CoroutineScope
from ViewModel’s scope ( constructor scope… : CoroutineScope by ( scope + Default )
) and every step is a val worker = actor { }
.
Actually I want to split some jobs in a N of workers and use the last worker with a “reverse debounce” operator ( when is received drop the current work and start again )tseisel
06/05/2019, 11:41 AMactor
, the returned Channel
matches the capacity
parameter, which is Channel.RendezVous
by default. This means that each step can process one element at the time. capacity = N
to define a worker that can process up to N
tasks in parallel.fun CoroutineScope.reverseDebounceActor() = actor<String>(capacity = Channel.CONFLATED) {
var currentJob: Job? = null
for (element in channel) {
currentJob?.cancel()
currentJob = launch {
// Do your work on element here...
// Make sure that this work is cancellable!
}
}
}
Davide Giuseppe Farella
06/05/2019, 11:50 AMUNLIMITED
.
Something like for element in list, send to queueChannel
, then repeat( WORKERS_COUNT) queueChannel.receiverOrNull -> do async
In this way the elements are processed concurrently in the actor but delivered together to the next one ( since I realised is not a good idea to deliver one by one, since every time the UI is refreshed it bump to the top ).
Have you got any better idea?private val imageCompressor = actor<List<EmbeddedImage>> {
for (embeddedImages in channel) {
val outputs = mutableListOf<ImageStream>()
for (embeddedImage in embeddedImages) {
imageSelector.send(embeddedImage)
}
(1..WORKERS_COUNT).forEachAsync {
<process>
outputs += embeddedImage to output
}
imageStringifier.send(outputs)
}
}
private val imageSelector = Channel<EmbeddedImage>(UNLIMITED)
tseisel
06/05/2019, 11:57 AMcapacity
parameter of actor
actually controls the number of elements that can be queued, not the number of elements processed simultaneously by the actor.
You need to create an actor for each required worker, just like in the example.Davide Giuseppe Farella
06/05/2019, 11:59 AM