Thread
#multiplatform
    diego-gomez-olvera

    diego-gomez-olvera

    6 days ago
    hello everyone! I was wondering what would be the recommended way to make this code thread safe for multiplatform
    private var currentJob: Job? = null
    
    fun flushData() {
        if (currentJob?.isActive == true) return
        currentJob = scope.launch {
            // Flush data while there is data to flush
        }
    }
    The idea would be to avoid creating new unnecessary
    currentJob
    having
    flushData
    accessed potentially from any thread
    I checke the docs and it shows the usage of
    Atomic
    types but that only works in JVM and
    Mutex.withLock
    already requires to be launched from a Coroutine. The API is exposed to Android and iOS, so it seems best not to require the usage of Coroutines to call this method
    c

    Casey Brooks

    6 days ago
    I would probably buffer the requests through a
    Channel
    , and then you can read from the Channel as a Flow to apply the skipping/restarting logic you need safely. Something like this might work
    val flushDataChannel = Channel<Unit>(RENDEZVOUS, BufferOverflow.DROP_LATEST)
    
    fun flushData() {
        flushDataChannel.trySend(Unit) // returns ChannelResult.Failed if it's already processing a request
    }
    
    fun CoroutineScope.processFlushData() = launch {
        flushDataChannel
            .consumeAsFlow()
            .onEach { /* Perform flush data operation */ }
            .launchIn(this)
    }
    diego-gomez-olvera

    diego-gomez-olvera

    6 days ago
    ah, it seems that
    Channel
    with
    BufferOverflow.DROP_LATEST
    can do the job, let me try. Thanks!
    c

    Casey Brooks

    6 days ago
    Yeah, using a Channel and Flow operators makes it pretty easy to tweak the actual logic to your needs. Whether to cancel and restart, ignore subsequent requests, etc. is all pretty easy to configure and makes it easy to read and understand the intent behind that code
    diego-gomez-olvera

    diego-gomez-olvera

    6 days ago
    how do you use
    processFlushData
    ?
    c

    Casey Brooks

    6 days ago
    Somewhere else in your application, you’d start it so that it’s running in the background
    diego-gomez-olvera

    diego-gomez-olvera

    6 days ago
    I am missing the connection between
    flushData
    (called externally) and
    processFlushData
    extension
    I'll check Channels docs, as I haven't really used them much
    c

    Casey Brooks

    6 days ago
    processFlushData
    is something you’d call once when the application starts up, so that it’s always ready to actually flush the data when you need to, but calling this method itself does not actually flush the data.
    flushData
    can be called from anywhere, on any thread, and it will simply request that the data be flushed by sending an object into the Channel. Only if
    processFlushData
    is currently running in the background will the request actually be accepted and the data flushed
    diego-gomez-olvera

    diego-gomez-olvera

    6 days ago
    ah, I get it now. Thanks once again!