Direct state machines tend to be avoided or abstracted in such a way as to not require such concrete transitions.
Most modern architectures based around message buses don't have ANY STATE. So they cannot hold a state machine. In fact a state machine in such an architecture outside of the middle ware itself would be forbidden.
...
You make good points, but...
Message bus middleware has a very regrettable tendency to presume "ideal operation" of distributed systems. Convenient when it works, convenient for fast shipping "it works because the unit test light is green", but prone to "random" "subtle" "unreproducible" failures in the field.
Soundly engineered distributed systems should not ignore important failure mechanisms, e.g. subtly impaired behaviour at one end, Byzantine Generals problems, non-ACID behaviour, message reordering, and similar.
In every non-trivial application I have ever seen there has been state in the end application. It may not be explicit, but it is always there. Not making it explicit is a frequent cause of problems found in deployed systems, especially when maintained over several years by different people.
Yes, FSMs can have deadlock and livelock - but that is a consequence of the application. At least FSMs make it very visible when and how deadlock/livelock has occurred, and don't encourage more subtle system failures.
Here is the reality that most MCU types simply forget. Volume. The amounts of data, conditions, processes, types, subtypes, outliers and use-cases that enterprise software supports would cover 100s or 1000s of MCUs in complexity as a single component. This is not the same a "bloat". This is complexity and multiplicity madated by the business processes and data and requirements.
This means you need a lot of people to do it in any sensible period of time. In an ideal world you could go and source yourself 100 top tier distributed engineers and they would produce a master piece that never crashed out.
The reality is VERY different though. So the tendency is to not do that. Instead we use existing frameworks, middleware, DBRMS, message buses, key-value dbs and all manor of "pre-build", "pre-tested" components written by a small subset of highly skilled engineers that understand that level of detail.
The average enterprise experience and skill distribution is very, very pear shaped. The vast majority of coders are basically useless. If you gave them a distributed state machine problem like a Singleton collection in a cluster, they will 100% screw it up.
So we don't give it to them We don't even do it ourselves as principles. We don't want the testing effort for one. We don't want the headaches for two. We make it someone elses problem.
The modern industry is not about writing good code it's about avoiding having to write any code at all, god forbid fiddly concurrency and distribution code.
Could you or I have a good stab at it, of course. Would you trust the "generic team member majority"? Hell no. If you have 6 months to do the full system end to end, you wiil realise that doing the middleware for it is 6 months on it's own. So go use Kafka and even add a higher level pattern/framework on top, like "PubSub".
It is that distributed part that causes the issues. When everything ran in compiled time coupled monoliths it wasn't an issue. "now is now". Once you go distributed the problem multipies in complexity when "now" is really "then". I watched a video recently that pointed out, if you were to stop time and examine the light on the transatlantic fibre you might find a dozen of your packets at a point along it. Tracing back to the source you will find more. These packets exist in a time/space location across thousands of miles and across micro-seconds and nano-seconds. Causality and relativity abound. It was the best way I can think of to really hit home the problem of distributed systems. At which point can you declare "state is consistent"? Consistent with what? Which point in time? None of the nodes exist in the same time context. None of them can even agree on what time it is because of the speed of light and networking delays, the later not being consistent either. Due to dynamnic routing the total distance is also variable.
On that note. For the OP. Some advice. Do not leave "time" to chance and "it will be alright on the night". Think carefully about it and decide if you want a "master clock" or if that should be driven by the CANBus itself or just a free-for-all of devices themselves. Remembering that if a device sends you a timestamp, it's clock could be out of sync.
I took the rather bruttle method of publishing a master clock at 1Hz. ALL services by default subscribe that that heart beat and some use it for scheduling. However, every service shares the same second. All messages that don't have a timstamp on them already, get one off the master clock.