Marko Mitic
07/22/2019, 12:30 PMinternal class BlockedAppsStoreDatabaseImpl(private val blockedAppDao: BlockedAppDao) : BlockedAppsStore {
private val channel = Channel<DbOp>(Channel.UNLIMITED)
init {
GlobalScope.launch {
select {
channel.onReceive { op ->
when (op) {
is Get -> op.cb.complete(blockedAppDao.getAll().toSet())
is Put -> blockedAppDao.putOrReplace(BlockedAppEntity(op.uid))
is Remove -> blockedAppDao.remove(op.uid)
is PutSet -> blockedAppDao.putOrReplace(op.uids)
is Fill -> blockedAppDao.fill(op.uids)
is RemoveAll -> blockedAppDao.removeAll()
}
}
}
}
}
override fun getAll(): Set<Uid> {
val deferred = CompletableDeferred<Set<Uid>>()
channel.sendBlocking(Get(deferred))
return runBlocking { deferred.await() }
}
override fun put(uid: Uid) {
channel.sendBlocking(Put(uid))
}
...
Dominaezzz
07/22/2019, 12:42 PMMarko Mitic
07/22/2019, 12:46 PMDominaezzz
07/22/2019, 1:01 PMMarko Mitic
07/22/2019, 1:14 PMDominaezzz
07/22/2019, 1:21 PMlaunch
in the set function.send
.Marko Mitic
07/22/2019, 1:24 PMsendBlocking
doesn't block unless channel is fullselect
in a while
loop), I'm checking whether I'm missing some big-picture issuembonnin
07/22/2019, 1:30 PMMarko Mitic
07/22/2019, 1:30 PMbdawg.io
07/24/2019, 9:27 PMselect
and just use channel.consumeEach { op ->
directly as well.channel
as well. private val channel = GlobalScope.actor<DbOp>(capacity = Channel.UNLIMITED) {
for (op in channel) { ... }
}
That will ensure that your channel is properly cleaned up when your scope gets cancelled. (Which would make moving away from GlobalScope easier in future refactors)Marko Mitic
07/24/2019, 11:00 PMactor
and consumeEach
are experimental, I can't really use them in my librarybdawg.io
07/25/2019, 5:43 PMconsumeEach
is tentatively graduating in 1.4.0. even if it doesn't, it's implementation is fairly simple
suspend fun <T> ReceiveChannel<T>.consumeEach(block: (T) -> Unit) {
try {
for (item in this) block(item)
} catch (e: Throwable) {
cancel(e as? CancellationException ?: CancellationException("Channel cancelled, consumer failed", e))
} finally {
cancel()
}
}