Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Discussion] Why syncing actions instead of data model? #1

Closed
coodoo opened this issue Aug 5, 2016 · 6 comments
Closed

[Discussion] Why syncing actions instead of data model? #1

coodoo opened this issue Aug 5, 2016 · 6 comments
Labels

Comments

@coodoo
Copy link

coodoo commented Aug 5, 2016

I have significant experience with scuttlebutt and related data types (crdt in particular), and redux-scuttlebutt looks like a really interesting way to approach syncing among users, just wondering why you choose to sync the actions, instead of the underlying data structures, say the store or state itself? Wouldn't it be simpler to keep one single source of truth and sync it across users?

@grrowl
Copy link
Owner

grrowl commented Aug 6, 2016

Great question! For background, I have significant experience with React and Redux and am only getting into scuttlebutt and CRDTs in general so I greatly appreciate feedback about this.

To me it was by default — researching how CRDTs (the Commutative kind) work I noticed that CmRDT "operations" are kinda like "actions", they're applied to the state. Redux time travel allows updates to be commutative since we can apply the update at any point in time. The underlying data structure is a pure result of the actions (
and a lot smaller/cheaper to sync over a network edit: not strictly true)

The "Conflict-free" part is up to your reducer. If you have conflict-free actions and reducers, you have a conflict-free app. This is not always the case — two peers might dispatch PICK_UP_ITEM, which [precondition] requires an item to exist and then [result] removes it from the world. One of these peers/players will conflict and their action will be un-done. Conversely, INSERT_TEXT_AT_POSITION is a conflict free action: you can always insert text at a string position, if the string exists.

@coodoo
Copy link
Author

coodoo commented Aug 6, 2016

Thanks for the explanation, mostly make sense to me 👍

As a side note, earlier this year I built a prototype along this train of thought but synced the underlying data model, scuttlebutt/Model in that case, between clients, on top of that it updates the redux store, and in turn refreshes the app, the idea was taking data model as the single source of truth and let it handles conflict resolution and stuff, hence making redux store a passive actor.

Goal of that POC was offline-ready, when clients went offline, changes they made could be persisted locally and guaranteed to sync and converge once online, scuttlebutt and crdt makes this really easy to implement.

I would assume in your approach you will persist multiple actions while offline and batch apply those once online and synced, wondering how's it working so far (performance, correctness, scalability)?

@grrowl
Copy link
Owner

grrowl commented Aug 6, 2016

Actions dispatched while offline are stored in the history all the same, and upon new connection are synced. This is all scuttlebutt, we just return all "new" updates through the history(sources) implementation.

We currently persist all actions forever, and a snapshot of the state after each action was applied. This makes it more efficient to replay actions since we walk back through history until thisTimestamp > historyItemTimestamp, reset the state to the snapshot, and replay all actions including the new one.

Otherwise: it's as fast as Redux/JS (very fast), actions/updates are emitted to peers at dispatch time (the scuttlebutt protocol is designed to be low latency), and there's very little "heavy lifting" going on, so it's efficient*

* With the exception of having to sync all actions on application start — It calls reduxStore.subscribe handlers for every update. I'm fixing this up today.

@grrowl grrowl added the question label Aug 6, 2016
@coodoo
Copy link
Author

coodoo commented Aug 6, 2016

Sounds good, is that project up somewhere to see?

@grrowl
Copy link
Owner

grrowl commented Aug 6, 2016

We currently ensure ordering of actions in the reducer by adding a meta.@@scuttlebutt/TIMESTAMP key to the action when it first enters the Dispatcher, and referring to this at reduce time. The reducer is here

@grrowl
Copy link
Owner

grrowl commented Nov 20, 2016

Closing this as I think we've addressed the questions :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants