diff options
author | Jenkins <jenkins@review.openstack.org> | 2015-10-03 02:04:22 +0000 |
---|---|---|
committer | Gerrit Code Review <review@openstack.org> | 2015-10-03 02:04:23 +0000 |
commit | ab78b2409a0c21aab783ce184fadda32bab9d8b3 (patch) | |
tree | 6881ed2da6b59876d81dc4f3bf82ab765c721e99 | |
parent | c799d4de5296056b06e08d8025488472cfcb7d66 (diff) | |
parent | a31ee07bda1a5ba8034277af9647aa21ad10be32 (diff) | |
download | swift-ab78b2409a0c21aab783ce184fadda32bab9d8b3.tar.gz |
Merge "Make sure we have enough .durable's for GETs"
-rw-r--r-- | swift/proxy/controllers/obj.py | 12 | ||||
-rwxr-xr-x | test/unit/proxy/controllers/test_obj.py | 24 |
2 files changed, 29 insertions, 7 deletions
diff --git a/swift/proxy/controllers/obj.py b/swift/proxy/controllers/obj.py index c67edd8a4..bdb2028f3 100644 --- a/swift/proxy/controllers/obj.py +++ b/swift/proxy/controllers/obj.py @@ -2443,10 +2443,14 @@ class ECObjectController(BaseObjectController): final_phase = True need_quorum = False # The .durable file will propagate in a replicated fashion; if - # one exists, the reconstructor will spread it around. Thus, we - # require "parity + 1" .durable files to be successfully written - # as we do fragment archives in order to call the PUT a success. - min_conns = policy.ec_nparity + 1 + # one exists, the reconstructor will spread it around. + # In order to avoid successfully writing an object, but refusing + # to serve it on a subsequent GET because don't have enough + # durable data fragments - we require the same number of durable + # writes as quorum fragment writes. If object servers are in the + # future able to serve their non-durable fragment archives we may + # be able to reduce this quorum count if needed. + min_conns = policy.quorum putters = [p for p in putters if not p.failed] # ignore response etags, and quorum boolean statuses, reasons, bodies, _etags, _quorum = \ diff --git a/test/unit/proxy/controllers/test_obj.py b/test/unit/proxy/controllers/test_obj.py index b7143d789..da3abd0c8 100755 --- a/test/unit/proxy/controllers/test_obj.py +++ b/test/unit/proxy/controllers/test_obj.py @@ -2108,7 +2108,8 @@ class TestECObjController(BaseObjectControllerMixin, unittest.TestCase): codes = [FakeStatus(201, response_sleep=response_sleep) for i in range(self.replicas())] # swap out some with regular fast responses - number_of_fast_responses_needed_to_be_quick_enough = 5 + number_of_fast_responses_needed_to_be_quick_enough = \ + self.policy.quorum fast_indexes = random.sample( range(self.replicas()), number_of_fast_responses_needed_to_be_quick_enough) @@ -2125,12 +2126,29 @@ class TestECObjController(BaseObjectControllerMixin, unittest.TestCase): self.assertEqual(resp.status_int, 201) self.assertTrue(response_time < response_sleep) + def test_PUT_with_just_enough_durable_responses(self): + req = swift.common.swob.Request.blank('/v1/a/c/o', method='PUT', + body='') + + codes = [201] * (self.policy.ec_ndata + 1) + codes += [503] * (self.policy.ec_nparity - 1) + self.assertEqual(len(codes), self.replicas()) + random.shuffle(codes) + expect_headers = { + 'X-Obj-Metadata-Footer': 'yes', + 'X-Obj-Multiphase-Commit': 'yes' + } + with set_http_connect(*codes, expect_headers=expect_headers): + resp = req.get_response(self.app) + self.assertEqual(resp.status_int, 201) + def test_PUT_with_less_durable_responses(self): req = swift.common.swob.Request.blank('/v1/a/c/o', method='PUT', body='') - codes = [201] * self.policy.ec_nparity - codes += [503] * (self.policy.ec_ndata - 1) + codes = [201] * (self.policy.ec_ndata) + codes += [503] * (self.policy.ec_nparity) + self.assertEqual(len(codes), self.replicas()) random.shuffle(codes) expect_headers = { 'X-Obj-Metadata-Footer': 'yes', |