3 ms·
> Replacing a state machine with callbacks... something something something you're gonna have a bad time Having written quite a few networking systems, I fully
by Matthias247 9y ago
> Replacing a state machine with callbacks... something something something you're gonna have a bad time
Having written quite a few networking systems, I fully agree. Especially if it's coupled in this text with "replacing a single-threaded state-machine" with "a multithreaded system, which uses callbacks". IMHO the latter is almost guaranteed a recipe for all kinds of multithreading issues, from race-conditions over deadlock to memory issues. And even if the author of the library gets it right, the issues are often at library user level (didn't expect where the callback is executed and accessed their data without necessary synchronization).
The described model of nanopb sounds very sane compared to that. Pure multithreaded systems without callbacks (like in Go) also work reasonably well. But even those do not work without state-machines in all situations. In all cases where state is manipulated by more than one code-path it's mostly the most reasonable thing to handle this in some kind of state-machine which runs on a single thread, instead of trying to fight it with dozens of fine-grained locks. And just as an example: The HTTP2 implementation in Go uses a state-machine which runs on a goroutine per connection. And user code, frame reader and frame writer code communicate via messaging with that state-machine.
- rumcajz 9y agoThat's interesting. Why do you need state machine if you have goroutine per connection? Isn't the instruction pointer + local variables an equivalent of a state stored in a state machine?
- ezdiy 9y agoHTTP2 is all about "tcp-inside-tcp" states. https://github.com/golang/net/blob/master/http2/http2.go#L81 https://github.com/golang/net/blob/master/http2/http2.go#L81 Wherever possible, they do the sensible thing - just goroutines for each flow, piped into from the muxed frame parser via channels, but the state for each flow must be still tracked as per-flow state in the topmost flow dispatcher - goroutine can't tear itself down on timeouts, inspect OOB signalilng of the topmost stream and such.