I have Channel<>(Channel.RENDEZVOUS)
It has no buffer, so it automatically blocks send until receive is used.
Is there any way how to block even longer?
I need to do that until the data are processed
I’m now doing this ugly hack
Producer:
do {
... prepare data ...
channel.send(event)
// block until data are processed by consumer
eventProcessingLock.withLock { log("Processing event done") }
} while()
Consumer:
try {
do {
delay(10)
} while (channel.isEmpty)
eventProcessingLock.lock()
val data = channel.receive()
... process data ...
} finally {
eventProcessingLock.unlock()
}
You can not use a Channel at all. You could simply pass a callback, that gives you exactly that behaviour for free.
The only difference, really is that that would be executing on the same coroutine, wether that’s an issue it depends on your use-case.
I’m actually converting callback call to channel.
I’m getting some Events objects from non Kotlin callback API
And I want to write business logic like this using corountines:
send("hallo")
if (waitOnData() == "ready") {
send("asking question")
val reply = waitOnData()
if (reply ....) {
sendData(...)
waitOnData()
}
} else {
...
}
The only issue is that this callback API sadly recycle Events object after callback is finished. So I need to lock callback function until data is processed.
So I rewrote val reply = waitOnData() to
val result = waitOnData {
... process data ...
}
And keep lock in callback until process data block is done.
But I need to keep the lock as short as possible.
Otherwise I will not get new data.
So If I cannot lock producer before I call receive() because I then never get a new data, because producer will be locked forever. So in the moment when Channel is empty I need just wait for new data, but not keep lock open.