What would be best way to emit events? I guess `Mu...
# getting-started
p
What would be best way to emit events? I guess
MutableSharedFlow
, but I would like to have event collected only once, for every new subscriber (collection).
Copy code
val flow = MutableSharedFlow<String>()
launch {
	flow.emit("x")
}

delay(500)

// I want this to receive "x"
launch {
    flow.collect {
        println("rx1: $it")
    }
}

delay(500)

// I don't want this to receive event again
launch {
    flow.collect {
        println("rx2: $it")
    }
}
If I add
MutableSharedFlow<String>(replay = 1)
, both collect calls will receive "x", which I don't want
g
I think you can use
Channel
for this purpose:
Copy code
val channel = Channel<String>()

launch {
    channel.send("x")
}

delay(500)

// This one will receive the element
launch {
    channel.receiveAsFlow().collect {
        println("rx1: $it")
    }
}

delay(500)

// This one won't receive any element
launch {
    channel.receiveAsFlow().collect {
        println("rx2: $it")
    }
}
p
ah, that works yeah, tnx!
v
hey @Peter, since this is similar (not 100% the same though) to what you asked, I also suggest you watch

this video

on one-off events by Philipp Lackner ✌️
p
I actually already have implemented, what Philipp suggested 🙈
🙌 1
I was not using suspending
send()
or buffer capacity
r
I think if you use
Channel
, the second collector will never receive the events. Channels can only deliver to one subscriber. If you want your second collector to receive future events (not the one that was previously emitted), then a
SharedFlow
with
extraBufferCapacity=1
would work.
g
@Ratul Sarna It's not true. The moment the first collector is not fast enough to collect the element, the second collector will collect it. For exaample, the snippet
Copy code
val channel = Channel<String>()

launch {
    channel.send("x1")
    channel.send("x2")
    channel.send("x3")
    channel.send("x4")
    channel.send("x5")
}

delay(500)

// This one will receive the element
launch {
    channel.receiveAsFlow().collect {
        println("rx1: $it")
        delay(1000)
    }
}

delay(500)

// This one won't receive any element
launch {
    channel.receiveAsFlow().collect {
        println("rx2: $it")
        delay(1000)
    }
}
prints
Copy code
rx1: x1
rx2: x2
rx1: x3
rx2: x4
rx1: x5
that shows both collectors had their time to collect the elements.
r
Understood, thanks for this nugget of info!
b
I'm using buffered channel and for now it has been the best solution for me so far
Copy code
private val mutableEvents = Channel<Event>(Channel.Buffered)
val events: Flow<Event> = mutableEvents.receiveAsFlow()