Collaborative Editing
Content: This is an interesting transaction topic:
- how to concurrently work on one document (process) without blocking? e.g. google docs, etc.
- how to synchronize sub-documents (scripts, html, etc.)?
What data is synchronized for collaborative editing?
- the events (name + modification data + author + date) that bpmn-js emits events, if something was changed inside the GUI
- also emit events if something is directly changes inside the BPMN (Constraints, Name, ID, Extensions, etc.)
- Question: can an event also be emitted immediately when there is something changed inside the HTML, Script, Constraint View? (not the whole script)
What needs to be done for synchronizing?
- emit event
- change BPMN process
- verify: check if the changed BPMN is the same on all the other systems
- if not: re-sync and get correct BPMN
How to sync the changes to every client?
- there are two versions: 1. the server has the source of truth, or 2. the client has the source of truth
Main PROBLEMS to solve:
- two clients work concurrently on the same process and should not override any changes from the others
Minor Problems:
- How is the time synchronized over all Client for
lastModificationDate
?
- goal: see the time of the last modification
- the Server can not add a date to the event because the triggering client does not receive its own event, but instead incorporates its changes by himself => but if the client has another time than all the other clients, the process hash is different
- Solution 1: when initialized server sends time to the client, client manages this time and use it (not the system time)
- Solution 2: last modification is not a time, but a unique id
- What happens to the Back- and Forward-Buttons?
- Can everybody revert (back) the changes from others?
The server truth
- the server incorporates all changes into the BPMN process
- every client also does it for itself
Verify that every editing client has the latest version:
- after incorporating all open changes, the server sends a hash of the new process to all registered clients
- Client validate the hash with their version and requests a complete process update, if it is not the same
- PROBLEM: the incorporation is done in parallel on every system (server and clients)
- if there are many change events, one system can be faster than the other
- if the server is faster than the client, the client gets a process hash before it finished the incorporation of all changes
- => the client needs to check against the same “version” as the server had for calculating the hash
- SOLUTION 1 (simple, maybe not sufficient): just compare when the incorporation of all events on the Client is finished (if there is a hash update from the server, just override the existing hash)
- SOLUTION 2 (more complex): in addition to the hash, send which (last 10) events have been incorporated in the hash and compare it
sequenceDiagram
participant C1 as Client1
participant C2 as Client2
participant S as Server
participant Cn as Client-N
note over C1: Start process editing
activate C1
C1->>+S: get process-1 and register for process-1 changes
S-->>-C1: latest process version
note over C2: Start process editing
activate C2
C2->>+S: get process-1 and register for process-1 changes
S-->>-C2: latest process version
par Editing concurrently
C1->>C1: change something in process-1
C1->>S: send change event
activate S
S->>C2: broadcast change event from Client1
note over S,Cn: no broadcast of the change event to other clients
%%because they didn't work on the process (no registration)
S->>S: add change event to process-1 "Change-Queue"
C2->>C2: add change event to process-1 "Change-Queue"
and In Parallel: no change from Client1 received yet
C2->>C2: change something in process-1
C2->>S: send change event
note over S,Cn: no broadcast of the change event to other clients
%%because they didn't work on the process (no registration)
S->>C1: broadcast change event from Client2
S->>S: add change event to process-1 "Change-Queue"
C1->>C1: add change event to process-1 "Change-Queue"
end
par Parallel Change Incorporation
loop until "Change-Queue" is empty
C1->>C1: incorporate change from Client2 into process-1
end
and
loop until "Change-Queue" is empty
C2->>C2: incorporate change from Client1 into process-1
end
and
loop until "Change-Queue" is empty
S->>S: incorporate change from Client1 into process-1
S->>S: incorporate change from Client1 into process-1
end
S->>S: calculate hash of new process
note over S,Cn: send hash only to registered clients
S->>C1: send new process hash
S->>C2: send new process hash
deactivate S
end
par In Parallel
C1->>C1: compare new process-1 hash
opt Client hash != Server hash
C1->>+S: get complete process-1
S-->>-C1: latest process version
end
and
C2->>C2: compare new process-1 hash
opt Client hash != Server hash
C2->>+S: get complete process-1
S-->>-C2: latest process version
end
end
deactivate C1
deactivate C2
The client truth
- the client send the change event to the server, which distributes it
- the client calculates the new BPMN process
- the client sends the new process to the server
- the server stores this version as the latest version
- verification as before with hashes
PROBLEM:
- too many problem with concurrent editing on multiple clients in parallel: if both clients send the BPMN to the server at the same time, which one is then the correct one?
- it would require blocking again, which we want to avoid