tryEmit doesn't attempt to emit a value after first subscriber joined and returns false.
Setting replay or extraBufferCapacity > 0 or replacing tryEmit by emit resolves the issue
@Test
fun tryEmitExample() = runBlocking {
val sharedFlow = MutableSharedFlow<Long>()
val asyncReceiver = async(){
delay(300)
sharedFlow.collect{
println("Received on 1 $it")
}
println("Done")
}
repeat(4) {
delay(100)
val res = sharedFlow.tryEmit(System.currentTimeMillis())
println("Emitted ${System.currentTimeMillis()} Subscribers: ${sharedFlow.subscriptionCount.value} try: $res")
}
asyncReceiver.cancel()
}
Emitted 1605303026489 Subscribers: 0 try: true
Emitted 1605303026592 Subscribers: 0 try: true
Emitted 1605303026693 Subscribers: 1 try: false
Emitted 1605303026799 Subscribers: 1 try: false
md5-7d8650d48dbb2577c830a81b00d45942
@Test
fun emitExample() = runBlocking {
val sharedFlow = MutableSharedFlow<Long>()
val asyncReceiver = async(){
delay(300)
sharedFlow.collect{
println("Received on 1 $it")
}
println("Done")
}
repeat(4) {
delay(100)
sharedFlow.emit(System.currentTimeMillis())
println("Emitted ${System.currentTimeMillis()} Subscribers: ${sharedFlow.subscriptionCount.value}")
}
asyncReceiver.cancel()
}
md5-7d8650d48dbb2577c830a81b00d45942
Emitted 1605303080955 Subscribers: 0
Emitted 1605303081061 Subscribers: 0
Received on 1 1605303081162
Emitted 1605303081166 Subscribers: 1
Received on 1 1605303081267
Emitted 1605303081267 Subscribers: 1
Have a look at #2346
It's not a bug, it's a feature... :)
This kind of implementation feels to me counterintuitive.
tryEmit (unlike emit) is not a suspending function, so it clearly cannot operate without a buffer where it can store emitted value for all the suspending subscribers to process. On the other hand, emit is suspending, so it does not need buffer space, as it can always suspend in case any of the subscribers are not ready yet.
Most helpful comment
It's not a bug, it's a feature... :)
This kind of implementation feels to me counterintuitive.