It's a powerful pattern, and when leveraged properly opens up a completely different programming paradigm. We've used this to do a lot of heavy lifting in consulting, and also to allow different packages to communicate with each other using domain events as glue between services.
Here's an Apex specification for domain-event emitting services: https://github.com/bigassforce/oasis
The benefits include:
- context agnostic code
- platform friendly at high volumes
- the domain events give admins way more visibility than equivalent code
(An event monitor shows unprocessable events, work in progress etc, making everything accessible.)
It's entirely doable. But the main difficulty is one of understanding. Unless the developers or subsequent consultants have experience with event driven systems, it can be really hard to gain traction and get different departments from the organization all plugging in.
The Streaming API makes no guarantee of delivery and Apex code would be a poor consumer, so I'd stay away from that. Persisted events are the way to go.
Your SObject Work Queue is an excellent example of the class of worker process to consume the events. And the Services Package is an orchestrator for event-consuming services.
No doubt you've seen developers try to reinvent that. But they are reinventing the wheel. In fact, not the wheel. Queueing and eventing frameworks are complex and way outstrip the wheel. What they are attempting to reinvent is the jet engine.
The key implementation hurdles are:
- avoiding dependencies
- routing domain events
- hardening the worker processes
The problem is, when reinventing the wheel, most people get that part right but not so much the jet engine. We've spent years reviewing eventing frameworks on Salesforce, and they've all had serious conceptual and performance issues lurking underneath.