I'm trying to design an asynchronous component. Requirements on this component are :
- Component might receive events at any point in time
- Component might start a long-running operation and wait for its result. This operation is executed by outside system.
- Long running operation might be cancelled, either by the component or externally
- Events might come while long-running operation is running, which might start the long-running operation again, possibly cancelling previous invocation
- Components needs to decide what to do with event that comes during long-running operation, if to ignore it, queue it or something else
- Component might start different operations in reaction to different events
- Component can have multiple "backing values", where each has current value and its change request is an event component needs to react to
- It must be possible to unit test the component in isolation (this is important!)
- There will be multiple different components, some might share behaviors. For example ability to turn the component on/off.
So far I have tried/thought of:
- Reactive observables
- This is what is used right now
- I really like how testing can be done in virtual time
- Long running operations are represented as function that transforms "request" observable into "response" observable
- But it rest of the team considers this solution too complex
- Plain objects with methods for event handlers
- Overall simple, but some constructions might be complex
- Doesn't require additional libraries
- Testing is not straightforward, as it is required to explicitly write every response to event instead of saying "for every request, respond in 5 ticks" like in reactive
- Tasks with async/await
- I don't know how would it be possible to implement situation that happens when event happens during long-running operation and how to test this situation, which is why I choose reactive instead
- Actor framework (Akka)
- This seems to be best fit for my requirements
- But I don't like how testing is made, as it is using real time
- And I believe Akka is way overkill for this use case, as we don't need per-component threading and the whole instrumentations to create actors and communicate between them
- And I'm afraid my team would consider it too complex too
What I'm looking for are suggestions of possible other solutions, I might not have thought of. Or additional advantages/disadvantages of suggested solutions.