)]}'
{"swift/common/storage_policy.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"e779eb37af0e5f0eb0387d0c071b3c738e074a4a","unresolved":false,"context_lines":[{"line_number":156,"context_line":""},{"line_number":157,"context_line":"    @property"},{"line_number":158,"context_line":"    def stores_objects_verbatim(self):"},{"line_number":159,"context_line":"        raise NotImplementedError"},{"line_number":160,"context_line":""},{"line_number":161,"context_line":"    @property"},{"line_number":162,"context_line":"    def needs_trailing_object_metadata(self):"}],"source_content_type":"text/x-python","patch_set":7,"id":"7a8c0949_f7f879c6","line":159,"updated":"2014-10-30 19:45:17.000000000","message":"how does that work?  I know there is like a \u0027return NotImplemented\u0027 and also a \"raise NotImplementedError()\" - what does this do?","commit_id":"c99a45d082b8bc23f288e7cd6cf962fb4e4bb283"},{"author":{"_account_id":2622,"name":"Samuel Merritt","email":"spam+launchpad@andcheese.org","username":"torgomatic"},"change_message_id":"c47edf5f83901a6dda0eb89013c407328d29dee8","unresolved":false,"context_lines":[{"line_number":156,"context_line":""},{"line_number":157,"context_line":"    @property"},{"line_number":158,"context_line":"    def stores_objects_verbatim(self):"},{"line_number":159,"context_line":"        raise NotImplementedError"},{"line_number":160,"context_line":""},{"line_number":161,"context_line":"    @property"},{"line_number":162,"context_line":"    def needs_trailing_object_metadata(self):"}],"source_content_type":"text/x-python","patch_set":7,"id":"7a8c0949_d7729de4","line":159,"in_reply_to":"7a8c0949_f7f879c6","updated":"2014-10-30 20:08:20.000000000","message":"You can raise an exception class if it doesn\u0027t need any arguments, I guess. Check this out:\n\n\n    \u003e\u003e\u003e def ex():\n    ...     raise NotImplementedError\n    ... \n    \u003e\u003e\u003e ex()\n    Traceback (most recent call last):\n      File \"\u003cstdin\u003e\", line 1, in \u003cmodule\u003e\n      File \"\u003cstdin\u003e\", line 2, in ex\n    NotImplementedError\n    \u003e\u003e\u003e","commit_id":"c99a45d082b8bc23f288e7cd6cf962fb4e4bb283"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"e779eb37af0e5f0eb0387d0c071b3c738e074a4a","unresolved":false,"context_lines":[{"line_number":201,"context_line":""},{"line_number":202,"context_line":"    @property"},{"line_number":203,"context_line":"    def stores_objects_verbatim(self):"},{"line_number":204,"context_line":"        return True"},{"line_number":205,"context_line":""},{"line_number":206,"context_line":"    def trailing_metadata(self, *a, **kw):"},{"line_number":207,"context_line":"        # Replicated objects don\u0027t need to store anything extra."}],"source_content_type":"text/x-python","patch_set":7,"id":"7a8c0949_171d0510","line":204,"updated":"2014-10-30 19:45:17.000000000","message":"meh, just make it an attribute on the class.\n\nOnly YOU can prevent python stack bloat (actually you can\u0027t - we\u0027re all screwed; but we don\u0027t have to be jerks about it)","commit_id":"c99a45d082b8bc23f288e7cd6cf962fb4e4bb283"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"e779eb37af0e5f0eb0387d0c071b3c738e074a4a","unresolved":false,"context_lines":[{"line_number":316,"context_line":""},{"line_number":317,"context_line":"    @property"},{"line_number":318,"context_line":"    def ec_segment_size(self):"},{"line_number":319,"context_line":"        return 1048576  # 1 MiB"},{"line_number":320,"context_line":""},{"line_number":321,"context_line":"    @property"},{"line_number":322,"context_line":"    def ec_scheme_description(self):"}],"source_content_type":"text/x-python","patch_set":7,"id":"7a8c0949_17cb4573","line":319,"updated":"2014-10-30 19:45:17.000000000","message":"this is gunna have to be configurable at some point during benchmarking even if we eventually decide there is only one right answer...","commit_id":"c99a45d082b8bc23f288e7cd6cf962fb4e4bb283"},{"author":{"_account_id":7485,"name":"Tushar Gohad","email":"tushar.gohad@intel.com","username":"tsg"},"change_message_id":"e0f2eb8aa94b7f3c5c136eb70e16827e63c4da47","unresolved":false,"context_lines":[{"line_number":316,"context_line":""},{"line_number":317,"context_line":"    @property"},{"line_number":318,"context_line":"    def ec_segment_size(self):"},{"line_number":319,"context_line":"        return 1048576  # 1 MiB"},{"line_number":320,"context_line":""},{"line_number":321,"context_line":"    @property"},{"line_number":322,"context_line":"    def ec_scheme_description(self):"}],"source_content_type":"text/x-python","patch_set":7,"id":"7a8c0949_974f3592","line":319,"in_reply_to":"7a8c0949_17cb4573","updated":"2014-10-30 19:59:47.000000000","message":"@Clay, @Sam, I have it configurable as part of this work:  https://review.openstack.org/#/c/111615/.  Should I submit this as a separate patch?","commit_id":"c99a45d082b8bc23f288e7cd6cf962fb4e4bb283"},{"author":{"_account_id":2622,"name":"Samuel Merritt","email":"spam+launchpad@andcheese.org","username":"torgomatic"},"change_message_id":"c47edf5f83901a6dda0eb89013c407328d29dee8","unresolved":false,"context_lines":[{"line_number":316,"context_line":""},{"line_number":317,"context_line":"    @property"},{"line_number":318,"context_line":"    def ec_segment_size(self):"},{"line_number":319,"context_line":"        return 1048576  # 1 MiB"},{"line_number":320,"context_line":""},{"line_number":321,"context_line":"    @property"},{"line_number":322,"context_line":"    def ec_scheme_description(self):"}],"source_content_type":"text/x-python","patch_set":7,"id":"7a8c0949_177425ce","line":319,"in_reply_to":"7a8c0949_17cb4573","updated":"2014-10-30 20:08:20.000000000","message":"Yup. I just didn\u0027t need it for this commit, so I was lazy and didn\u0027t bother reading it it. If we do end up landing this patch, let\u0027s make it configurable as a separate commit.","commit_id":"c99a45d082b8bc23f288e7cd6cf962fb4e4bb283"},{"author":{"_account_id":7485,"name":"Tushar Gohad","email":"tushar.gohad@intel.com","username":"tsg"},"change_message_id":"e0f2eb8aa94b7f3c5c136eb70e16827e63c4da47","unresolved":false,"context_lines":[{"line_number":396,"context_line":"                          bytes_transferred_from_client,"},{"line_number":397,"context_line":"                          fragment_archive_index):"},{"line_number":398,"context_line":"        return {"},{"line_number":399,"context_line":"            \u0027X-Object-Sysmeta-EC-Etag\u0027: client_obj_hasher.hexdigest(),"},{"line_number":400,"context_line":"            \u0027X-Object-Sysmeta-EC-Content-Length\u0027:"},{"line_number":401,"context_line":"            str(bytes_transferred_from_client),"},{"line_number":402,"context_line":"            \u0027X-Object-Sysmeta-EC-Archive-Index\u0027: str(fragment_archive_index),"}],"source_content_type":"text/x-python","patch_set":7,"id":"7a8c0949_774ac984","line":399,"updated":"2014-10-30 19:59:47.000000000","message":"Should we make these \"X-Object-Sysmeta-ETag\" and \"X-Object-Sysmeta-Content-Lenght\" as this is the etag and content length of the original object, and not specific to EC.","commit_id":"c99a45d082b8bc23f288e7cd6cf962fb4e4bb283"},{"author":{"_account_id":2622,"name":"Samuel Merritt","email":"spam+launchpad@andcheese.org","username":"torgomatic"},"change_message_id":"c47edf5f83901a6dda0eb89013c407328d29dee8","unresolved":false,"context_lines":[{"line_number":396,"context_line":"                          bytes_transferred_from_client,"},{"line_number":397,"context_line":"                          fragment_archive_index):"},{"line_number":398,"context_line":"        return {"},{"line_number":399,"context_line":"            \u0027X-Object-Sysmeta-EC-Etag\u0027: client_obj_hasher.hexdigest(),"},{"line_number":400,"context_line":"            \u0027X-Object-Sysmeta-EC-Content-Length\u0027:"},{"line_number":401,"context_line":"            str(bytes_transferred_from_client),"},{"line_number":402,"context_line":"            \u0027X-Object-Sysmeta-EC-Archive-Index\u0027: str(fragment_archive_index),"}],"source_content_type":"text/x-python","patch_set":7,"id":"7a8c0949_d717fd4f","line":399,"in_reply_to":"7a8c0949_774ac984","updated":"2014-10-30 20:08:20.000000000","message":"I sort of want to keep it namespaced; if Swift ever sprouts crypto or compression or whatever, those change the etag too, and we\u0027ll need to store it at each step of the transformation.","commit_id":"c99a45d082b8bc23f288e7cd6cf962fb4e4bb283"}],"swift/proxy/controllers/base.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"e779eb37af0e5f0eb0387d0c071b3c738e074a4a","unresolved":false,"context_lines":[{"line_number":991,"context_line":"            info[\u0027partition\u0027] \u003d part"},{"line_number":992,"context_line":"            info[\u0027nodes\u0027] \u003d nodes"},{"line_number":993,"context_line":"            if info.get(\u0027storage_policy\u0027) is None:"},{"line_number":994,"context_line":"                info[\u0027storage_policy\u0027] \u003d 0"},{"line_number":995,"context_line":"        return info"},{"line_number":996,"context_line":""},{"line_number":997,"context_line":"    def _make_request(self, nodes, part, method, path, headers, query,"}],"source_content_type":"text/x-python","patch_set":7,"id":"7a8c0949_17926557","line":994,"updated":"2014-10-30 19:45:17.000000000","message":"is there a functional difference between this and:\n\ninfo.setdefault(\u0027storage_policy\u0027, 0)\n\nAlso if you need an int in there, is it like bad if the value in the cache is a string?  I honestly have no idea what this change is for.","commit_id":"c99a45d082b8bc23f288e7cd6cf962fb4e4bb283"},{"author":{"_account_id":2622,"name":"Samuel Merritt","email":"spam+launchpad@andcheese.org","username":"torgomatic"},"change_message_id":"c47edf5f83901a6dda0eb89013c407328d29dee8","unresolved":false,"context_lines":[{"line_number":991,"context_line":"            info[\u0027partition\u0027] \u003d part"},{"line_number":992,"context_line":"            info[\u0027nodes\u0027] \u003d nodes"},{"line_number":993,"context_line":"            if info.get(\u0027storage_policy\u0027) is None:"},{"line_number":994,"context_line":"                info[\u0027storage_policy\u0027] \u003d 0"},{"line_number":995,"context_line":"        return info"},{"line_number":996,"context_line":""},{"line_number":997,"context_line":"    def _make_request(self, nodes, part, method, path, headers, query,"}],"source_content_type":"text/x-python","patch_set":7,"id":"7a8c0949_17ffc535","line":994,"in_reply_to":"7a8c0949_17926557","updated":"2014-10-30 20:08:20.000000000","message":"I\u0027m not sure how, but there was a None in there at one point, and it was screwing things up now that the proxy needs a policy object. The pass-the-index-along thing that we had before didn\u0027t care, but getting a real policy object did.\n\nThe storage policy get_by_index() method converts its argument to int, so the \u00270\u0027 -\u003e 0 change doesn\u0027t really matter; guess I just didn\u0027t type the quotes.","commit_id":"c99a45d082b8bc23f288e7cd6cf962fb4e4bb283"}],"swift/proxy/controllers/obj.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"e779eb37af0e5f0eb0387d0c071b3c738e074a4a","unresolved":false,"context_lines":[{"line_number":950,"context_line":"                    \u0027Object PUT exceptions during\u0027"},{"line_number":951,"context_line":"                    \u0027 send, %(conns)s/%(nodes)s required connections\u0027),"},{"line_number":952,"context_line":"                    {\u0027conns\u0027: len(putters), \u0027nodes\u0027: min_puts})"},{"line_number":953,"context_line":"                raise HTTPServiceUnavailable(request\u003dreq)"},{"line_number":954,"context_line":""},{"line_number":955,"context_line":"        try:"},{"line_number":956,"context_line":"            with ContextPool(len(putters)) as pool:"}],"source_content_type":"text/x-python","patch_set":7,"id":"7a8c0949_57694d8a","line":953,"updated":"2014-10-30 19:45:17.000000000","message":"I think one of the sad sources of bloat in the method is these inline defs - this one at least seems to be mostly lifting some code from outside of the middle of the main storage path - which is a little better - but I wonder why not just extract it while we\u0027re at it!?\n\nwhat do we need....\n\netag_hasher, chunk_transform, putters, chunk_hashers (jesus do we really need hash every fragment archive for the storage server\u0027s too!?), and req\n\nhrmm... etag_hasher and chunk_transform seem to have a similar usage - initialized once for the request and updated on every send \n\nThe chunk_hashers I think could go on the putters same as their index, might actually be simpler.\n\nThe putters list is ugly, but I think the most obvious thing would be to pass by reference with the contract that send_chunk will modify it in the expected way...\n\nProbably reasonable to pass in the request, the len(putters) check could happen on the outside for the send, but I guess you\u0027d have to do it twice, probably reasonable to pass in req.  In fact if you hang the etag_hasher and chunk_transform on the request after you initialize them you could just \"self.send_chunk(chunk, putters, req)\"\n\nBut honestly I can\u0027t help but see just how damn close we are to being able to pull everything from node_iter to best_response out into a separate object... be one hell of an abstraction point.","commit_id":"c99a45d082b8bc23f288e7cd6cf962fb4e4bb283"},{"author":{"_account_id":7485,"name":"Tushar Gohad","email":"tushar.gohad@intel.com","username":"tsg"},"change_message_id":"e0f2eb8aa94b7f3c5c136eb70e16827e63c4da47","unresolved":false,"context_lines":[{"line_number":1009,"context_line":"        statuses, reasons, bodies, etags \u003d self._get_put_responses("},{"line_number":1010,"context_line":"            req, putters, nodes)"},{"line_number":1011,"context_line":""},{"line_number":1012,"context_line":"        if len(etags) \u003e 1 and policy.stores_objects_verbatim:"},{"line_number":1013,"context_line":"            self.app.logger.error("},{"line_number":1014,"context_line":"                _(\u0027Object servers returned %s mismatched etags\u0027), len(etags))"},{"line_number":1015,"context_line":"            return HTTPServerError(request\u003dreq)"}],"source_content_type":"text/x-python","patch_set":7,"id":"7a8c0949_d740dd58","line":1012,"updated":"2014-10-30 19:59:47.000000000","message":"Do we not need to check the etags for fragment archives as those were written to respective object servers?\n\nExample:  Line 956 of https://review.openstack.org/#/c/111615/5/swift/proxy/controllers/obj.py","commit_id":"c99a45d082b8bc23f288e7cd6cf962fb4e4bb283"},{"author":{"_account_id":2622,"name":"Samuel Merritt","email":"spam+launchpad@andcheese.org","username":"torgomatic"},"change_message_id":"c47edf5f83901a6dda0eb89013c407328d29dee8","unresolved":false,"context_lines":[{"line_number":1009,"context_line":"        statuses, reasons, bodies, etags \u003d self._get_put_responses("},{"line_number":1010,"context_line":"            req, putters, nodes)"},{"line_number":1011,"context_line":""},{"line_number":1012,"context_line":"        if len(etags) \u003e 1 and policy.stores_objects_verbatim:"},{"line_number":1013,"context_line":"            self.app.logger.error("},{"line_number":1014,"context_line":"                _(\u0027Object servers returned %s mismatched etags\u0027), len(etags))"},{"line_number":1015,"context_line":"            return HTTPServerError(request\u003dreq)"}],"source_content_type":"text/x-python","patch_set":7,"id":"7a8c0949_92a023f6","line":1012,"in_reply_to":"7a8c0949_d740dd58","updated":"2014-10-30 20:08:20.000000000","message":"We send the FA\u0027s etag in the footer metadata as \u0027Etag\u0027, so we get validation there.\n\nThis check is intended to make sure all the written objects have the same etag. However, each FA is different, so they definitely don\u0027t have the same checksum, and so this check was always triggering and returning a 500 to the client.","commit_id":"c99a45d082b8bc23f288e7cd6cf962fb4e4bb283"}],"test/unit/proxy/test_server.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"e779eb37af0e5f0eb0387d0c071b3c738e074a4a","unresolved":false,"context_lines":[{"line_number":161,"context_line":"    obj3_ring_path \u003d os.path.join(_testdir, POLICIES[3].ring_name + \u0027.ring.gz\u0027)"},{"line_number":162,"context_line":"    part_shift \u003d 30"},{"line_number":163,"context_line":"    with closing(GzipFile(obj3_ring_path, \u0027wb\u0027)) as fh:"},{"line_number":164,"context_line":"        pickle.dump(RingData(pol3_replica2part2dev_id, devs, part_shift), fh)"},{"line_number":165,"context_line":""},{"line_number":166,"context_line":"    prosrv \u003d proxy_server.Application(conf, FakeMemcacheReturnsNone(),"},{"line_number":167,"context_line":"                                      logger\u003ddebug_logger(\u0027proxy\u0027))"}],"source_content_type":"text/x-python","patch_set":7,"id":"7a8c0949_77b649de","line":164,"updated":"2014-10-30 19:45:17.000000000","message":"oh just go ahead and generalize write_fake_ring - it takes *devs, this is exactly the opportunity we needed to find out what a test that wants a three device fake/real ring would actually need out the interface!?","commit_id":"c99a45d082b8bc23f288e7cd6cf962fb4e4bb283"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"e779eb37af0e5f0eb0387d0c071b3c738e074a4a","unresolved":false,"context_lines":[{"line_number":1254,"context_line":"        partition, nodes \u003d prosrv.get_object_ring(3).get_nodes("},{"line_number":1255,"context_line":"            \u0027a\u0027, \u0027ec-con\u0027, \u0027o1\u0027)"},{"line_number":1256,"context_line":"        conf \u003d {\u0027devices\u0027: _testdir, \u0027mount_check\u0027: \u0027false\u0027}"},{"line_number":1257,"context_line":"        df_mgr \u003d diskfile.DiskFileManager(conf, FakeLogger())"},{"line_number":1258,"context_line":""},{"line_number":1259,"context_line":"        got_pieces \u003d set()"},{"line_number":1260,"context_line":"        got_indices \u003d set()"}],"source_content_type":"text/x-python","patch_set":7,"id":"7a8c0949_f7d079f9","line":1257,"updated":"2014-10-30 19:45:17.000000000","message":"How would you feel about this test making requests to the object servers instead of reaching behind it to disk?","commit_id":"c99a45d082b8bc23f288e7cd6cf962fb4e4bb283"}]}
