|
| 1 | +# Clustered SWISH |
| 2 | + |
| 3 | +## Syncing the gitty store |
| 4 | + |
| 5 | +The gitty store is a directed graph of commits. Each commit is linked to |
| 6 | +a _data object_. Both commits and data objects are hashed by content and |
| 7 | +read-only. This implies they are easily replicated over the network. The |
| 8 | +replication takes two forms: |
| 9 | + |
| 10 | + - A node may _announce_ an object by sending the objects content as |
| 11 | + a series of chunks. |
| 12 | + - A node may _request_ for an entire object or a missing object |
| 13 | + chunk. Receiving nodes that have the object will broadcast the |
| 14 | + missing object. |
| 15 | + |
| 16 | +The real problem is updating the _head pointer_. This is a central |
| 17 | +database that defines the latest version of a file with a certain name. |
| 18 | +This notion must be syncronised. This is implemented as follows: |
| 19 | + |
| 20 | + - A node asks the cluster for their current head. |
| 21 | + - If all nodes agree on the current head we are done, but some |
| 22 | + nodes may not have the indicated file. |
| 23 | + - If some nodes have no head, _announce_ the head |
| 24 | + - Else |
| 25 | + - Ask all nodes to produce a backward path of commits that |
| 26 | + includes all reported heads from the other nodes. |
| 27 | + - Work out the last common hash, possibly by majority vote. |
| 28 | + - Work out the changes since this common hash. |
| 29 | + - If nodes agree or have no info, fine |
| 30 | + - If nodes disagree, go with the majority. |
| 31 | + - Propose the new head to all nodes that agreed on the majority |
| 32 | + path. These nodes will _accept_ if nothing changed since their |
| 33 | + report, blocking further changes for a specified time. |
| 34 | + - If all accept, send a new head notion. Else restart from the |
| 35 | + beginning. |
| 36 | + |
| 37 | +The above deals with a life cluster. Nodes that have missed a |
| 38 | +conversation or joined the network later may miss a file or the latest |
| 39 | +version of a file. |
| 40 | + |
| 41 | +## Remote syncing |
| 42 | + |
| 43 | +Remote syncing is necessary for both new cluster members and for cluster |
| 44 | +members that have been offline for some time. |
| 45 | + |
| 46 | + - Find the node with most changes using a request. |
| 47 | + - Ask this node to start the process. |
| 48 | + - Each cluster member checks it has the change. If not, it starts |
| 49 | + a negotiation using gitty_remote_head/2. |
| 50 | + |
| 51 | +## Profile management and login |
| 52 | + |
| 53 | +FIXME |
| 54 | + |
| 55 | +Remote sync of library(persistency)? |
| 56 | + |
| 57 | + - Realise a distributed ledger of changes. |
| 58 | + - Apply these. |
| 59 | + |
| 60 | + |
| 61 | + - Add serial to each event |
| 62 | + - Broadcast them |
| 63 | + - Adding an event |
| 64 | + - Propos |
| 65 | + |
| 66 | + |
| 67 | +## Email notifications |
| 68 | + |
| 69 | +FIXME |
| 70 | + |
| 71 | +## Chat subsystem |
| 72 | + |
| 73 | +### Maintain a global overview of visitor count |
| 74 | + |
| 75 | +Visitor change messages cary a `local_visitors` and `visitors` field and |
| 76 | +are relayed. Nodes receiving such a message uses the `local_visitors` to |
| 77 | +update their count of visitors on that node. Nodes composing such a |
| 78 | +message count the local visitors and add the known totals from the other |
| 79 | +nodes. |
| 80 | + |
| 81 | +### Subscribed files |
| 82 | + |
| 83 | +WSID joining a file, leaving a file or logging out is broadcasted and |
| 84 | +each node maintains a view of the remote users by WSID. |
| 85 | + |
| 86 | +FIXME: need to deal with joining nodes and missed updates. |
| 87 | + |
| 88 | +### Profile changes |
| 89 | + |
| 90 | +Profile changes, login, logout are sent to all nodes and each nodes |
| 91 | +sends them to the browsers that have the WSID watching some file. |
| 92 | + |
| 93 | +### Chat syncing |
| 94 | + |
| 95 | + - Find the last message of all nodes for DocID. |
| 96 | + - If Serial-ID matches, we are done |
| 97 | + - Else |
| 98 | + - Ask each node for the history as chat(Serial,ID,Time) triples. |
| 99 | + - Asses agreement (= no info or same) |
| 100 | + - If all agree, send an sync request for the serial range that |
| 101 | + is not known everywhere. |
| 102 | + - Else, send an agreement _serial_ and a list of Serial-ID |
| 103 | + pairs constructed from a chronologically ordered list of |
| 104 | + chat messages about which there is no agreement. |
0 commit comments