def _response_get_change(self, s, mid, msg, rstate): lstate = self.socket[s][Response][rstate['ref']] changeset = msg['changeset'] del msg['changeset'] if sha.new(changeset).digest() != rstate['changenum']: self._close(s) return write_changeset(self, rstate['changenum'], changeset, lstate['txn']) changeset = bdecode(changeset) lstate['changes'][rstate['changenum']] = changeset for change in changeset['precursors']: if self.lcrepo.has_key(change): continue if lstate['changes'].has_key(change): continue if lstate['requests'].has_key(change): continue rid = self._get_change(s, lstate, change) self.socket[s][Request][rid] = { 'request': 'get change', 'changenum': change, 'ref': rstate['ref'] } lstate['count'] += 1 lstate['count'] -= 1 del self.socket[s][Request][mid] # record all the diffs we'll need to request diffs = lstate['diffs'] for handle, hinfo in changeset['handles'].items(): if not hinfo.has_key('hash'): continue if not diffs.has_key(handle): diffs[handle] = {} lstate['counts'][handle] = 0 diffs[handle][rstate['changenum']] = 1 lstate['counts'][handle] += 1 changeset = None try: if lstate['count'] == 0: self._commit_phase_1(s, rstate['ref']) if lstate['count'] == 0: self._commit_phase_2(s, rstate['ref']) except HistoryError, msg: self._commit_fail(s, rstate['ref'], str(msg)) return
def _response_get_change(self, s, mid, msg, rstate): lstate = self.socket[s][Response][rstate['ref']] changeset = msg['changeset'] del msg['changeset'] if sha.new(changeset).digest() != rstate['changenum']: self._close(s) return write_changeset(self, rstate['changenum'], changeset, lstate['txn']) changeset = bdecode(changeset) lstate['changes'][rstate['changenum']] = changeset for change in changeset['precursors']: if self.lcrepo.has_key(change): continue if lstate['changes'].has_key(change): continue if lstate['requests'].has_key(change): continue rid = self._get_change(s, lstate, change) self.socket[s][Request][rid] = {'request': 'get change', 'changenum': change, 'ref': rstate['ref']} lstate['count'] += 1 lstate['count'] -= 1 del self.socket[s][Request][mid] # record all the diffs we'll need to request diffs = lstate['diffs'] for handle, hinfo in changeset['handles'].items(): if not hinfo.has_key('hash'): continue if not diffs.has_key(handle): diffs[handle] = {} lstate['counts'][handle] = 0 diffs[handle][rstate['changenum']] = 1 lstate['counts'][handle] += 1 changeset = None try: if lstate['count'] == 0: self._commit_phase_1(s, rstate['ref']) if lstate['count'] == 0: self._commit_phase_2(s, rstate['ref']) except HistoryError, msg: self._commit_fail(s, rstate['ref'], str(msg)) return
def _response_get_change(self, s, mid, msg, rstate): lstate = self.socket[s][Request][rstate['ref']] if sha.new(msg['changeset']).digest() != rstate['changenum']: raise ServerError, 'bad changeset' # write it out, decode and eject from memory write_changeset(self.co, rstate['changenum'], msg['changeset'], lstate['txn']) changeset = bdecode(msg['changeset']) lstate['changes'][rstate['changenum']] = changeset del msg['changeset'] # get any precursors we don't have and haven't yet requested for change in changeset['precursors']: if self.co.lcrepo.has_key(change): continue if lstate['changes'].has_key(change): continue if lstate['requests'].has_key(change): continue rid = self._get_change(s, change) self.socket[s][Request][rid] = {'request': 'get change', 'changenum': change, 'ref': rstate['ref']} lstate['requests'][change] = 1 lstate['count'] += 1 # record all the diffs we'll need to request diffs = lstate['diffs'] for handle, hinfo in changeset['handles'].items(): if not hinfo.has_key('hash'): continue if not diffs.has_key(handle): diffs[handle] = {} lstate['counts'][handle] = 0 diffs[handle][rstate['changenum']] = 1 lstate['counts'][handle] += 1 # clean up state del lstate['requests'][rstate['changenum']] lstate['count'] -= 1 if lstate['count'] == 0: sync_history(self.co, lstate['head'], lstate['txn'], cache=lstate['changes']) named, modified, added, deleted = \ handles_in_branch(self.co, lstate['heads'], [lstate['head']], lstate['txn'], cache=lstate['changes']) del lstate['changes'] self._update_checks(s, rstate['ref'], named, modified) self._update_handle_list(s, lstate, named, modified, added, deleted) handle_list = lstate['handle list'] # get all the related file diffs for i in xrange(len(handle_list)-1, -1, -1): handle = handle_list[i][1] if not diffs.has_key(handle): continue changes = diffs[handle] requested = 0 for change in changes.keys(): requested = 1 self._queue_diff(s, change, handle, rstate['ref']) lstate['count'] += requested self._get_diff(s, rstate['ref']) if lstate['count'] == 0: self._update_finish(s, lstate) del self.socket[s][Request][rstate['ref']] self.rs.doneflag.set() return 1
def _commit_phase_2(self, s, mid): request = self.socket[s][Response][mid] txn = request['txn'] head = request['cur head'] if request.has_key('no phase 2'): self.txn_commit(txn) del self.socket[s][Response][mid] self._send_response(s, mid, {}) return # backup servers don't create clean merge heads req_head = request['head'] if not self.config.getboolean('control', 'backup'): # create new clean merge head changeset = bencode({ 'precursors': [head, req_head], 'user': self.socket[s][User], 'time': int(time()), 'handles': {} }) new_head = request['new head'] = sha.new(changeset).digest() write_changeset(self, new_head, changeset, txn) else: new_head = request['head'] self.repolistdb.put(request['repository'], new_head, txn=txn) sync_history(self, new_head, txn, cache=request['changes']) del request['changes'] # validate all the files for which we already have the diffs locks = [] for handle, checked in request['modified'].items(): locks.append(handle) # did we already validate it? if checked: continue # if there are diffs then some other checkin verified them # we only need to make sure there aren't any implicit merges handle_merge_check(self, handle, new_head, txn) # complete everything and clean up self.txn_commit(txn) del self.socket[s][Response][mid] self._send_response(s, mid, {}) for handle in locks: self._unlock_file(s, handle) for pattern, action in self.post_commit: if not pattern.search(request['repository']): continue try: afd = os.popen(action, 'w') afd.write( dump_changeinfo(self, new_head, repo=request['repository'])) afd.close() except IOError, msg: print 'Command failed' print 'Command: ' + action print 'Error: ' + str(msg)
def _commit_phase_2(self, s, mid): request = self.socket[s][Response][mid] txn = request['txn'] head = request['cur head'] if request.has_key('no phase 2'): self.txn_commit(txn) del self.socket[s][Response][mid] self._send_response(s, mid, {}) return # backup servers don't create clean merge heads req_head = request['head'] if not self.config.getboolean('control', 'backup'): # create new clean merge head changeset = bencode({'precursors': [head, req_head], 'user': self.socket[s][User], 'time': int(time()), 'handles': {}}) new_head = request['new head'] = sha.new(changeset).digest() write_changeset(self, new_head, changeset, txn) else: new_head = request['head'] self.repolistdb.put(request['repository'], new_head, txn=txn) sync_history(self, new_head, txn, cache=request['changes']) del request['changes'] # validate all the files for which we already have the diffs locks = [] for handle, checked in request['modified'].items(): locks.append(handle) # did we already validate it? if checked: continue # if there are diffs then some other checkin verified them # we only need to make sure there aren't any implicit merges handle_merge_check(self, handle, new_head, txn) # complete everything and clean up self.txn_commit(txn) del self.socket[s][Response][mid] self._send_response(s, mid, {}) for handle in locks: self._unlock_file(s, handle) for pattern, action in self.post_commit: if not pattern.search(request['repository']): continue try: afd = os.popen(action, 'w') afd.write(dump_changeinfo(self, new_head, repo=request['repository'])) afd.close() except IOError, msg: print 'Command failed' print 'Command: ' + action print 'Error: ' + str(msg)
def _response_get_change(self, s, mid, msg, rstate): lstate = self.socket[s][Request][rstate['ref']] if sha.new(msg['changeset']).digest() != rstate['changenum']: raise ServerError, 'bad changeset' # write it out, decode and eject from memory write_changeset(self.co, rstate['changenum'], msg['changeset'], lstate['txn']) changeset = bdecode(msg['changeset']) lstate['changes'][rstate['changenum']] = changeset del msg['changeset'] # get any precursors we don't have and haven't yet requested for change in changeset['precursors']: if self.co.lcrepo.has_key(change): continue if lstate['changes'].has_key(change): continue if lstate['requests'].has_key(change): continue rid = self._get_change(s, change) self.socket[s][Request][rid] = { 'request': 'get change', 'changenum': change, 'ref': rstate['ref'] } lstate['requests'][change] = 1 lstate['count'] += 1 # record all the diffs we'll need to request diffs = lstate['diffs'] for handle, hinfo in changeset['handles'].items(): if not hinfo.has_key('hash'): continue if not diffs.has_key(handle): diffs[handle] = {} lstate['counts'][handle] = 0 diffs[handle][rstate['changenum']] = 1 lstate['counts'][handle] += 1 # clean up state del lstate['requests'][rstate['changenum']] lstate['count'] -= 1 if lstate['count'] == 0: sync_history(self.co, lstate['head'], lstate['txn'], cache=lstate['changes']) named, modified, added, deleted = \ handles_in_branch(self.co, lstate['heads'], [lstate['head']], lstate['txn'], cache=lstate['changes']) del lstate['changes'] self._update_checks(s, rstate['ref'], named, modified) self._update_handle_list(s, lstate, named, modified, added, deleted) handle_list = lstate['handle list'] # get all the related file diffs for i in xrange(len(handle_list) - 1, -1, -1): handle = handle_list[i][1] if not diffs.has_key(handle): continue changes = diffs[handle] requested = 0 for change in changes.keys(): requested = 1 self._queue_diff(s, change, handle, rstate['ref']) lstate['count'] += requested self._get_diff(s, rstate['ref']) if lstate['count'] == 0: self._update_finish(s, lstate) del self.socket[s][Request][rstate['ref']] self.rs.doneflag.set() return 1