Noob question - I was under the impression that `F...
# coroutines
u
Noob question - I was under the impression that
Flow
is built on top of `Channel`s, i.e.
Flow
is a higher level and
Channel
is a lower level api. But I was told this was not the case. In which case, if you had some sort of system that generates events, say stock updates and then you want to do analysis on that and execute trades would you use a
Channel
or a
flow { .. }
Copy code
suspend fun foo() = coroutineScope {
	val channel = Channel(BUFFERED)
	launch {
		val library = SomeOldStockMarketLibrary()
		library.setListener { prices ->
			channel.trySend(prices)
		}
		library.initialize()
	}
	for (prices in channel) {
		doAnalysis(prices)
	}
}

suspend fun foo2(): Flow<Prices> = callbackFlow {
	val channel = Channel(BUFFERED)
	val library = SomeOldStockMarketLibrary()
	library.setListener { prices ->
		trySend(prices)
	}
	library.initialize()
	awaitClose { library.close() } 
}

fun run() {
	scope.launch {
		foo()
	}

	scope.launch {
		foo2()
			.collect { prices ->
				doAnalysis(prices)
			}
	}
}
Or is it all just imperative vs functional style?
p
flow
builds on top of Coroutines, the pure flow API is really simple. channels are a coroutine primitive, some flow operators use channels internally but not all operators or flow buiders need a channel. I prefer flow over channels in most cases. For event system design SharedFlow is really good. In your example callbackFlow fits perfect. The problem with channels is when you have more than one consumer. Is hard to manage things like successful delivery or one time delivery guarantee when multiple consumers are connected.
u
when would you then use a Channel? it seems like its just for implementing certain Flow operators?
p
Right, is the only thing comes to my mind. Or cases where only one consumer will be connected
Known as fan-in cases
d
Channel
is more flexible in what you can do with it, and therefore, it's also less structured. Given a
Flow
, you can only
collect
it, and that's it, whereas a
Channel
allows you to try to obtain an element without blocking (
tryReceive
), forbid new elements from entering the channel, force the sender thread and the receiver thread to wait for each other (by using a
RENDEZVOUS
channel)... If your use case can be neatly expressed as a
Flow
, use a
Flow
. When you need a channel, you'll know it.
👍 2
u
In that case of "do analysis (and execute trades)on every stockmarket update", would you use a channel or flow?
z
You could probably use either. Your use case is so vague on technical requirements it’s hard to say anything more that “it depends”