def _write_transaction(self, fp, records, index): fp.seek(0, 2) for i, (oid, record) in enumerate(records): full_record = self._disk_format(record) index[oid] = fp.tell() fp.write(p32(len(full_record))) fp.write(full_record) if i % self._PACK_INCREMENT == 0: yield None fp.write(p32(0)) # terminator
def handle_C(self, s): # commit client = self._find_client(s) s.sendall(p32(len(client.invalid)) + ''.join(client.invalid)) client.invalid.clear() tlen = u32(recv(s, 4)) if tlen == 0: return # client decided not to commit (e.g. conflict) tdata = recv(s, tlen) logging_debug = is_logging(10) logging_debug and log(10, 'Committing %s bytes', tlen) self.storage.begin() i = 0 oids = [] while i < len(tdata): rlen = u32(tdata[i:i+4]) i += 4 oid = tdata[i:i+8] record = tdata[i+8:i+rlen] i += rlen if logging_debug: class_name = extract_class_name(record) log(10, ' oid=%-6s rlen=%-6s %s', u64(oid), rlen, class_name) self.storage.store(oid, record) oids.append(oid) assert i == len(tdata) self.storage.end() log(20, 'Committed %3s objects %s bytes at %s', len(oids), tlen, datetime.now()) s.sendall(STATUS_OKAY) for c in self.clients: if c is not client: c.invalid.update(oids)
def handle_S(self, s): # sync client = self._find_client(s) log(8, 'Sync %s', len(client.invalid)) invalid = self.storage.sync() assert not invalid # should have exclusive access s.sendall(p32(len(client.invalid)) + ''.join(client.invalid)) client.invalid.clear()
def end(self, handle_invalidations=None): self.s.sendall('C') n = u32(recv(self.s, 4)) if n != 0: packed_oids = recv(self.s, n*8) try: handle_invalidations(split_oids(packed_oids)) except ConflictError: self.s.sendall(p32(0)) # Tell server we are done. raise tdata = [] for oid, record in self.records.iteritems(): tdata.append(p32(8 + len(record))) tdata.append(oid) tdata.append(record) tdata = ''.join(tdata) self.s.sendall(p32(len(tdata))) self.s.sendall(tdata) self.records.clear() status = recv(self.s, 1) if status != STATUS_OKAY: raise ProtocolError, 'server returned invalid status %r' % status
def handle_L(self, s): # load oid = recv(s, 8) if oid in self._find_client(s).invalid: s.sendall(STATUS_INVALID) else: try: record = self.storage.load(oid) except KeyError: log(10, 'KeyError %s', u64(oid)) s.sendall(STATUS_KEYERROR) else: if is_logging(5): log(5, 'Load %-7s %s', u64(oid), extract_class_name(record)) s.sendall(STATUS_OKAY + p32(len(record)) + record)
def pack_record(oid, data, refs): """(oid:str, data:str, refs:str) -> record:str """ return ''.join([oid, p32(len(data)), data, refs])