Refactoring Sync
I would like to refactor sync!
First some terms. This is the member state state-machine. The goal is to have as few unique transitions as possible. If two actions can be done by the same transition, even better...
waiting --[join]--> active ---[pause ]---> inactive --[exit]--> terminated --[cleanup]--> 0
<---[activate]---
<--------------------[activate]-------
If some attribute except state
changes we have an attribute_changed
event.
To find out which transition we do, we add a last_state
to the user. Then the sync logic is:
enum SyncState { Unchanged, Updated, Error }
// Functions must be idempotent!
// I.g. if the member is already in the desired state they should return Unchanged.
interface SyncAdapter {
ensure_created(member) : SyncState
ensure_active(member) : SyncState
ensure_inactive(member) : SyncState
ensure_terminated(member) : SyncState
ensure_updated(member) : SyncState
ensure_deleted(member) : SyncState
}
get_transition(old_state, new_state) : Transition = /* see above state machine */
sync_member(transition, adapter, member) : SyncState =
transition.match
case join:
if adapter.ensure_created(member) != kError
adapter.ensure_active(member)
case activate:
adapter.ensure_active(member)
case pause
adapter.ensure_inactive(member)
case terminate:
adapter.ensure_terminated(member)
case cleanup:
adapter.ensure_deleted(member)
case attribute_changed:
adapter.ensure_updated(member)
sync_members(members, adapters) :
members.each member =>
if member.last_sync < member.last_change
transition = get_transition(member.last_state, member.state)
bool update = false
adapters.each adapter =>
sync_member(transition, adapter, member).match
case Updated:
update = true
case Error:
update = false
break
case Unchanged:
continue
if update
if transition == delete
member.delete
else
member.last_state = member.state
member.last_sync = now
member.update
What do you think?