def between_checkpoints(old, new): for x in new.keys(): max_slot = new.get(x, Slot(x, 0)) low_slot = old.get(x, Slot(x, 0)) for y in range(low_slot.instance_id, max_slot.instance_id): yield Slot(x, y)
def main(): dph = DepthFirstHelper() a = Slot(0, 1) b = Slot(0, 2) c = Slot(0, 3) d = Slot(0, 4) e = Slot(0, 5) f = Slot(0, 6) print('a', dph.ready('b', ['a'])) print('a', dph.ready('b', ['d'])) print(dph.ccs) print('b', dph.ready('c', ['b'])) print(dph.ccs) print('c', dph.ready('a', ['c'])) print('c', dph.ready('d', [])) print(dph.ccs) # print(dph.expected_ready_count_by, dph.expected_ready_from, dph.visited) # dph.log_state() print('=====') print('c', dph.ready('b', [])) # dph.log_state() print('=A1===') print(dph.ready(1, [2])) print(dph.ready(4, [5])) print(dph.ready(2, [3])) print(dph.ready(3, [4])) print(dph.ready(5, [])) print(dph.ccs) # print(dph.expected_ready_count_by, dph.expected_ready_from, dph.visited) print('=A2===') print(dph.ready(Slot(1, 10), [Slot(2, 3)])) print(dph.ready(Slot(2, 3), [Slot(1, 4)])) print(dph.ccs) # print(dph.expected_ready_count_by, dph.expected_ready_from, dph.visited) print('=B===') print('d', dph.ready('c', [])) # dph.log_state() # print(dph.commit(d, [a])) # print(dph.commit(e, [d])) # print(dph.commit(b, [a, c])) # print(dph.commit(b, [a, c])) # print(dph.commit(b, [a, c, d])) # dph.log_state() # print(dph.commit(c, [b, a])) print('DONE')
def set_executed(self, slot: Slot): assert self.is_committed(slot), (slot, self.store.load(slot)) assert not self.is_executed(slot), (slot, self.store.load(slot)) self.executed[slot] = True self.st_exec += 1 slot = slot while self.is_executed(self.executed_cut.get(slot.replica_id, Slot(slot.replica_id, -1)).next()): self.executed_cut[slot.replica_id] = slot del self.executed[slot] slot = slot.next()
def event(self, x): if isinstance(x, packet.Packet) and isinstance(x.payload, PACKET_LEADER): slot = x.payload.slot # type: Slot if slot in self.waiting_for: yield from self.run_sub( slot, (x.origin, Receive.from_waiting(self.waiting_for.pop(slot), x.payload))) yield Reply() elif isinstance(x, InstanceState): if x.inst.state.stage >= Stage.Committed: if x.slot in self.waiting_for: del self.waiting_for[x.slot] if x.slot in self.subs: del self.subs[x.slot] yield Reply() elif isinstance(x, LeaderStart): slot = Slot(self.quorum.replica_id, self.next_instance_id) self.next_instance_id += 1 self.subs[slot] = leader_client_request(self.quorum, slot, x.command) yield from self.run_sub(slot) yield Reply(slot) elif isinstance(x, LeaderStop): if x.slot in self.waiting_for: del self.waiting_for[x.slot] if x.slot in self.subs: del self.subs[x.slot] yield Reply() elif isinstance(x, LeaderExplicitPrepare): prev = self.subs.get(x.slot) is not None self.subs[x.slot] = leader_explicit_prepare( self.quorum, x.slot, x.reason) yield from self.run_sub(x.slot) yield Reply(prev) elif isinstance(x, CheckpointEvent): ctr = 0 for slot in between_checkpoints(*self.cp.cycle(x.at)): if slot in self.subs: ctr += 1 del self.subs[slot] if slot in self.waiting_for: ctr += 1 del self.waiting_for[slot] logger.error( f'{self.quorum.replica_id} cleaned old things between {ctr}: {self.cp}' ) yield Reply() else: assert False, x
def load(self, slot: Slot): if self.cp.earlier(slot): raise SlotTooOld(slot, None, None) r = self.inst.get(slot) exists = True if r is None: exists = False r = InstanceStoreState(slot.ballot_initial(), State(Stage.Prepared, None, -1, [])) return LoadResult(exists, r)
def leader_client_request(q: Quorum, slot: Slot, cmd: Command): inst = yield Store( slot, InstanceStoreState( slot.ballot_initial(q.epoch), State( Stage.PreAccepted, cmd, 0, [] ) ) ) yield from leader_pre_accept(q, slot, inst, True)
def earlier(self, slot: Slot): return slot < self.cp_old.get(slot.replica_id, Slot( slot.replica_id, -1))
from uuid import uuid4 import tarjan from dsm.epaxos.cmd.state import Command, Mutator, Checkpoint from dsm.epaxos.inst.deps.cache import KeyedDepsCache from dsm.epaxos.inst.state import Slot IN = [ Command(uuid4(), Mutator('SET', [1, 2])), Command(uuid4(), Mutator('SET', [1, 2, 4])), Command(uuid4(), Mutator('SET', [10])), Command(uuid4(), Checkpoint(5)), ] IN = [(Slot(0, i), x) for i, x in enumerate(IN)] IN_LAST = [ Command(uuid4(), Checkpoint(6)), ] IN_LAST = [(Slot(1, i), x) for i, x in enumerate(IN_LAST)] store = KeyedDepsCache() def xchange(slot: Slot, cmd: Command): return store.xchange(slot, cmd) def shuffle(x):
def is_cut(self, slot: Slot): return self.executed_cut.get(slot.replica_id, Slot(slot.replica_id, -1)) >= slot