a. 用户3和用户4是两个着急下班的同学,他们本地master分支分别是提交3和提交4;
b. 底部灰色的圆圈代表的是服务端一个仓库三个副本的装填,可以看到其中两个master分支指向的是提交2,而其中有一个可能因为网络或者其他原因导致其master的指向为1;
c. 当用户3和用户4前后提交了代码,由于用户3更快达到服务,所以会率先启动写的流程;
d. 在一个写的流程开始,首先会对当前仓库副本的一致性进行检查,系统很容易就发现落后的副本1与其他两个副本不一致,因此会将其标记为unhealthy。对于unhealthy的副本,是不会参与伽利略写或读的任何操作;
e. 当用户4的请求也被受理后,也会触发一致性检查,但是由于副本1已经被标记为unhealthy,所以对于用户4的流程,这个副本就“不可见”了;
f. 在用户3的进程检查后,发现多数副本是一致,则认为是可以写入的,便会将非引用数据传输到副本中;同理用户4的进程也是一样,且因为非引用数据不会变更分支信息,所以不需要加锁,可以同时操作;
g. 当用户3的进程收到非引用的数据传输成功后,便要开始进行引用的更新,这时第一步先去抢占这个仓库的锁。很幸运锁是空闲的,用户3的进程加锁成功,开始改写副本的引用指向;
h. 当用户4的进程也完成了非引用数据传输后也开始进行引用的更新。同样,再更新操作前要去抢锁,但发现锁已经被占用,则用户4的进程进入等待阶段(如果等待超时,则直接告诉用户4提交失败);
i. 当用户3的进程改写引用成功后,会释放掉仓库锁。此时服务端的仓库的master分支已经被修改为指向3。用户3可以开心下班了;
j. 当锁被释放后,用户4的进程快速抢占,并尝试修改引用指向,但发现更改的目标引用master已经和之前不同(之前是2,现在是被用户3更改的3),此时用户4的进程会失败并释放掉锁。在用户4的本地会收到类似“远端分支已经被更新,请拉取最新提交后再推送”的类似提示。