psibr / REstate

Portable state-flows (state-machine based workflows)
MIT License
36 stars 7 forks source link

Introduced GetMachineReference & IOptimisticallyConcurrentStateRepository to reduce IO ops #61

Closed aidapsibr closed 5 years ago

aidapsibr commented 5 years ago

This PR focuses on Request-Response path applications as opposed to long-lived contexts as has previously been the focus. In the case of both new optimizations being adopted, users can see a reduction in 2/3rds of the read operations.

GetMachineReference(string machineId)

In request life-cycles a machine must be retrieved before a signal or input/payload can be sent, which requires I/O to ensure the machine exists. This has been mitigated with a new method on IStateEngine that does not require any I/O and is synchronous: GetMachineReference.

This also opens the door to more usage patterns where a machine reference would have been desired to store, but the I/O requirement meant designs had to instead hold a lower component and lazy initialize.

IOptimisticallyConcurrentStateRepository<TState, TInput>

REstate is designed to minimize the possibility of stale writes for State as it's primary responsibility. The issue arises that each data-store handles concurrency differently, some with optimistic some pessimistic, and many have stale read semantics with eventual consistency. In the case of stale reads, this highly increases the chance of hitting a concurrency exception and needing to go through retry cycles. These differences has meant REstate has had to handle the worst case of each possible implementation previously. This is now being addressed with an optional interface IOptimisticallyConcurrentStateRepository<TState, TInput>that a Repository may implement. When implemented, REstate will send its recently loaded state to the repository so that the repository can avoid another read before making an update.

Current Implementations

Planned Implementations

Why Should This Be In Core?

Required handling of new interface.

Benefits

Best case scenario of no contention reduces database calls by at least 1 and 3 in EntityFramework's case.

Possible Drawbacks

Elevated burden on caller to handle retries in hot paths.

Related Issues