Thank you for that reference! I will study it. However, being used to communicating sequential processes (occam, local schedulers in small embedded systems, and the bare bone channels and goroutines of go etc) that would be my cognitive starting point (for good or worse), whatâs the basic idea for building all the wrappings around something that may(?) be built simpler?
Weâre using GoFlow, which is really just a specific way of exploiting the Goroutine/Channel power, to recruit all the available hardware resources.
By default, every net component (think actor) is run on a new Goroutine when it receives an item on its input channel. So no item being processed in the network is ever semantically blocked by another. If the infrastructure has headroom, it will be exploited to push volume through the network.
It also comes into its own when you have different load profiles for different components - some can be doing computation while others are doing I/O etc.
Of course I understand the difference between a programming language and a pattern, between bricks and a house. It still puzzles me to see all these frameworks evolving from use with a non-concurrent languages (like Swift) that donât have any notion of process (like gorotines) and communication (like channels) and synchronisation (like zero-buffered or full channels) ported and embraced on concurrent platforms (like go). Whether itâs push or pull with channels is kind of orthogonal to the problem, isnât it? There canât be any reception before production anyhow.
And it puzzles me to read things like the below (quote from ycombinator in my initial question):
â(reubenbond at ycombinator) Channels in Go donât compose: I canât easily take one channel, mutate the values as they arrive, and create another channel from the mutated values. With Rx, thatâs just var uppers = keyPresses.Select(key => key.ToUpper()) and now Iâve got a new stream of data. If keyPresses completes, so does uppers. If it fails, that failure is propagated through uppers. This isnât easy in Go.
goroutines donât have any reasonable kind of monitoring. I canât say âthis routine has completed/failedâ, I have to implement that notion every single time using a WaitGroup or something, and that only handles completion, not failure.â
How correct are the answers? Itâs not excactly the syntax âvar uppers = keyPresses.Select(key => key.ToUpper())â on go, but itâs not much different, is it? Once channels have been connected between goroutines. "Composition: A Way to Make Proofs Harder"
by Leslie Lamport certainly rules CSP to be compositional, and any goroutine (or PROC in occam) can spawn a new process. And with mobile channels (and go channels) you can spawn any channel you like at any time, except youâd have a way to connect that new channel (like sending it over an existing channel). Isnât this enough?
Would a web server framework written in go for go from the onset look different than the others? It looks like GoFlow is one such? How does it differ from how a Reactive Extension for Go would have been?
(As you understand, I see this from an embedded programmerâs bench, but being curious about this)