From 1d26b15a4eacd34c258376c6e1c27d0abb984cb1 Mon Sep 17 00:00:00 2001 From: Chuck Thier Date: Tue, 21 Sep 2010 20:31:14 +0000 Subject: [PATCH] Updated object updater to keep track of successes so it doesn't retry updating nodes that it has already updated --- swift/obj/updater.py | 12 +++++++++--- test/unit/obj/test_updater.py | 17 ++++++++++++----- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/swift/obj/updater.py b/swift/obj/updater.py index 40121e4b9d..22f259feae 100644 --- a/swift/obj/updater.py +++ b/swift/obj/updater.py @@ -154,16 +154,20 @@ class ObjectUpdater(Daemon): renamer(update_path, os.path.join(device, 'quarantined', 'objects', os.path.basename(update_path))) return + successes = update.get('successes', []) part, nodes = self.get_container_ring().get_nodes( update['account'], update['container']) obj = '/%s/%s/%s' % \ (update['account'], update['container'], update['obj']) success = True for node in nodes: - status = self.object_update(node, part, update['op'], obj, + if node['id'] not in successes: + status = self.object_update(node, part, update['op'], obj, update['headers']) - if not (200 <= status < 300) and status != 404: - success = False + if not (200 <= status < 300) and status != 404: + success = False + else: + successes.append(node['id']) if success: self.successes += 1 self.logger.debug('Update sent for %s %s' % (obj, update_path)) @@ -171,6 +175,8 @@ class ObjectUpdater(Daemon): else: self.failures += 1 self.logger.debug('Update failed for %s %s' % (obj, update_path)) + update['successes'] = successes + pickle.dump(update, open(update_path,'w')) def object_update(self, node, part, op, obj, headers): """ diff --git a/test/unit/obj/test_updater.py b/test/unit/obj/test_updater.py index 0064e2cbd2..dc0dd7129f 100644 --- a/test/unit/obj/test_updater.py +++ b/test/unit/obj/test_updater.py @@ -122,13 +122,15 @@ class TestObjectUpdater(unittest.TestCase): except BaseException, err: return err return None - def accept(return_code): + def accept(return_codes): + codes = iter(return_codes) try: events = [] - for x in xrange(2): + for x in xrange(len(return_codes)): with Timeout(3): sock, addr = bindsock.accept() - events.append(spawn(accepter, sock, return_code)) + events.append( + spawn(accepter, sock, codes.next())) for event in events: err = event.wait() if err: @@ -136,16 +138,21 @@ class TestObjectUpdater(unittest.TestCase): except BaseException, err: return err return None - event = spawn(accept, 201) + event = spawn(accept, [201,500]) for dev in cu.get_container_ring().devs: if dev is not None: dev['port'] = bindsock.getsockname()[1] cu.run_once() err = event.wait() + if err: + raise err + self.assert_(os.path.exists(op_path)) + event = spawn(accept, [201]) + cu.run_once() + err = event.wait() if err: raise err self.assert_(not os.path.exists(op_path)) - if __name__ == '__main__': unittest.main()