Looking for a bit of a code review. I've got this ...
# coroutines
r
Looking for a bit of a code review. I've got this code:
Copy code
suspend fun searchForCard(cardType: Byte) {
        Log.d(TAG, "Search for a card once.")
        writeCharacteristic(readerGatt, comByteManager.AActivityComByte(cardType), WRITE_TYPE_NO_RESPONSE).suspend()
        singleSweepCardJob.cancel()
        singleSweepCardJob = Job()
        val scope = CoroutineScope(singleSweepCardJob)
        scope.launch {
            delay(1000)
            Log.i(TAG, "Repeating searchForCard")
            searchForCard(cardType)
        }
    }
    private var singleSweepCardJob = Job()
Because sometimes, the bluetooth device doesn't answer properly, I'm repeating the request. I'm invoking
singleSweepCardJob.cancel()
as soon as I get a response to the command. Will this blow up in my face somehow? (Code not tested yet, device is a bit further away)
c
This is basically how the
flow.mapLatest
operator is implemented, so in general it’s not necessarily a “bad” pattern. Although in this case, it looks like the launched coroutine has side-effects (searchForCard doesn’t return anything, so it presumably updates a state value internally) which does have the possibility of race conditions if the first scope is cancelled but the coroutine is not fully completed by the time you launch the second one. That said, I saw an elegant solution for “restartable coroutines” recently, that might make it look a bit cleaner and easier to understand the logic, as well as being safe against such side-effects https://kotlinlang.slack.com/archives/C1CFAFJSK/p1690215505119029?thread_ts=1690214570.291329&cid=C1CFAFJSK
r
Oh, neat. Thanks!