Slide 1

Slide 1 text

Offline First Collaboration with Event Sourcing Steven Chan - @stevnchan

Slide 2

Slide 2 text

GoodNotes

Slide 3

Slide 3 text

Syncing is hard

Slide 4

Slide 4 text

What we have tried

Slide 5

Slide 5 text

Apple CloudKit • Remote database API • Need to implement syncing with local cache ourselves • Designing a correct algorithm to sync two object graphs is hard • Limited schema migration support • Undocumented limit for sharing records

Slide 6

Slide 6 text

Google Firebase • Real-time database • Mobile SDKs available • Offline mode: store updates in a queue • Performance become worse as the queue become long

Slide 7

Slide 7 text

Event sourcing to rescue

Slide 8

Slide 8 text

Event sourcing to rescue 1. Store all changes as events in a single queue 2. Only need to sync the event queue 3. Derive the app state from the event queue 4. Migration = rewrite the derivation function

Slide 9

Slide 9 text

Todo app example 1. {inserted, id123, “Buy milk”} 2. {completed, id123} 3. {deleted, id123}

Slide 10

Slide 10 text

Update app state 1. {inserted, id123, “Buy milk”} 2. {completed, id123} 3. {deleted, id123}

Slide 11

Slide 11 text

Update app state 1. {inserted, id123, “Buy milk”} 2. {completed, id123} 3. {deleted, id123}

Slide 12

Slide 12 text

Update app state 1. {inserted, id123, “Buy milk”} 2. {completed, id123} 3. {deleted, id123}

Slide 13

Slide 13 text

Update app state 1. {inserted, id123, “Buy milk”} 2. {completed, id123} 3. {deleted, id123}

Slide 14

Slide 14 text

Syncing • Server: maintain an event queue = the source of truth • Clients: upload local events to server, download unseen events, and then update the app state. • That’s it!

Slide 15

Slide 15 text

Syncing A B C A B C D E F Client Server F D E

Slide 16

Slide 16 text

Syncing A B C A B C D E F Client Server F D E

Slide 17

Slide 17 text

Syncing A B C A B C D E F Client Server F D E

Slide 18

Slide 18 text

Conflicts handling • Pick the latest value by update time • Pick the value with the largest update count • Use vector clocks to detect conflicts

Slide 19

Slide 19 text

Demo

Slide 20

Slide 20 text

Q&A