)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"65889d4b3504a12b2cc318ed970ed7bfd21d36f0","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":1,"id":"7f4e7237_5a4d0453","updated":"2023-10-18 05:16:50.000000000","message":"Submit a WIP, would like to get feedback on the changes of new timing metrics.","commit_id":"fb7806b3e964a5a08f2010c105f70296f791493b"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"9576a60f983dff8f6a88187f2b4a8592baa3de4b","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"5a47c0e5_bf67e0cc","updated":"2023-10-20 04:57:12.000000000","message":"thanks for the review.","commit_id":"fb7806b3e964a5a08f2010c105f70296f791493b"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"736e0deb36f367071c944d5d937c894cd5494291","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"c51919b7_bb0a5d9f","in_reply_to":"7f4e7237_5a4d0453","updated":"2023-10-20 04:57:25.000000000","message":"Done","commit_id":"fb7806b3e964a5a08f2010c105f70296f791493b"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"2bdfff47719ce29fa60eea6e62568157e7dafd94","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"16a083ed_ed17925f","updated":"2023-10-27 05:07:19.000000000","message":"thanks for the reviews!","commit_id":"b2e695a1ed16ba61d28caeaf14c4cb33916355aa"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"76a4673f3e039e57781554d508071d16e4ac2962","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"057bbeeb_859aafc6","updated":"2023-10-31 01:00:41.000000000","message":"Ahh this is a chain, and so can\u0027t land until the parent lands.. opps aparently I\u0027m bad at reading :P","commit_id":"05671e14c55241519d169dd911277c1fdbdec4a0"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"94b0b6f2591a1a1b6dc7fb9ef95220ccd10aa570","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"5e3042e1_6c62faab","updated":"2023-10-30 22:43:42.000000000","message":"This is cool guys. So this wont effect our current PUT and GET timing metrics, but will also provide {PUT,GET}_{container,shard,obj} metrics so we can break it down further.\nwho doesn\u0027t want that.\n\nThere are some interesting clean up we can do as a follow up (which Al has already started) and this patch is already clearing will make our lives better so lets get these metrics in.\n\nFurther, it\u0027s a great refactor simplication. I know that obj/shard conditional well in get and put so really glad to see it more readable!","commit_id":"05671e14c55241519d169dd911277c1fdbdec4a0"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"4607efa84fbc49cbe6bd569482f3f163d62b1e27","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"c70b1663_47d9bc44","updated":"2023-10-31 00:59:34.000000000","message":"recheck","commit_id":"05671e14c55241519d169dd911277c1fdbdec4a0"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"dd1a9c2b9f36cc1a24ff694c11624923c77098f3","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":7,"id":"95d7330a_83e990e9","updated":"2023-11-08 23:35:10.000000000","message":"thanks for the reviews.","commit_id":"2dd4a7100cd1cbd019729469e1a17a1b834556e0"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"5798cd3deae167df19b3d61bb705bdf4600701fe","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"ccae3e87_58fc0c96","updated":"2023-11-21 15:39:33.000000000","message":"LGTM!","commit_id":"4ebf87ae4696ba0a74dc2941ad9a7a4e7823c072"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"2ab2341db9409f6f45b4898e010deabe7a5faafb","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":11,"id":"bae0d227_5ca50a8b","updated":"2023-11-27 16:54:44.000000000","message":"I have this nagging feeling that this timing decorator is going to influence how we organize these methods, or at least what code is covered by which metric.\n\nI think in a idealized labeled metrics world we\u0027d only emit the one metric for measuring the WHOLE PUT and then just annotate if the metric represents a shard range or an object update.\n\nBut this is a good compromise with what we have, and I like the refactor, and the new metrics are covered by tests.  Hopefully we don\u0027t feel to hamstrung by them if we want to change it later.","commit_id":"a102055608fe22a807b6e96cbb92c16d5c44dbba"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"92d31f22ae69e913dbe7a986c8a89958d017ae1a","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":11,"id":"229357e6_e8299691","updated":"2023-11-22 12:00:42.000000000","message":"We\u0027ve been carrying this in production and it\u0027s been useful to distinguish the relative timings of shard and object requests.\n\nThe new split methods are faithful to the original.","commit_id":"a102055608fe22a807b6e96cbb92c16d5c44dbba"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"3ca5058c1803769e7badd72cd7a060ac1ae8941f","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":11,"id":"79f5d5d7_78ca749b","updated":"2023-11-22 11:13:54.000000000","message":"this had lots of positive votes so I have moved it to the top of the patch chain to get it merged. I pulled in the refactor of the GET method into GET_object and GET_shard from https://review.opendev.org/c/openstack/swift/+/890470/41","commit_id":"a102055608fe22a807b6e96cbb92c16d5c44dbba"}],"swift/container/server.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"8af4ed859575c21dfc2a4db4793dfc443beaa910","unresolved":true,"context_lines":[{"line_number":494,"context_line":"            self._update_sync_store(broker, method)"},{"line_number":495,"context_line":""},{"line_number":496,"context_line":"    @public"},{"line_number":497,"context_line":"    @timing_stats()"},{"line_number":498,"context_line":"    def PUT(self, req):"},{"line_number":499,"context_line":"        \"\"\"Handle HTTP PUT request.\"\"\""},{"line_number":500,"context_line":"        drive, part, account, container, obj \u003d get_obj_name_and_placement(req)"}],"source_content_type":"text/x-python","patch_set":1,"id":"ab26cb94_3725a6ae","line":497,"updated":"2023-10-19 16:46:46.000000000","message":"it seems ok to nest methods wrapped with timing_stats - they need to all have unique names, and they need to all return a resp obj w/ .status_int attribute","commit_id":"fb7806b3e964a5a08f2010c105f70296f791493b"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"9576a60f983dff8f6a88187f2b4a8592baa3de4b","unresolved":false,"context_lines":[{"line_number":494,"context_line":"            self._update_sync_store(broker, method)"},{"line_number":495,"context_line":""},{"line_number":496,"context_line":"    @public"},{"line_number":497,"context_line":"    @timing_stats()"},{"line_number":498,"context_line":"    def PUT(self, req):"},{"line_number":499,"context_line":"        \"\"\"Handle HTTP PUT request.\"\"\""},{"line_number":500,"context_line":"        drive, part, account, container, obj \u003d get_obj_name_and_placement(req)"}],"source_content_type":"text/x-python","patch_set":1,"id":"e54601e0_98bb70f3","line":497,"in_reply_to":"ab26cb94_3725a6ae","updated":"2023-10-20 04:57:12.000000000","message":"Ack","commit_id":"fb7806b3e964a5a08f2010c105f70296f791493b"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"8af4ed859575c21dfc2a4db4793dfc443beaa910","unresolved":true,"context_lines":[{"line_number":597,"context_line":"        else:"},{"line_number":598,"context_line":"            return HTTPAccepted(request\u003dreq,"},{"line_number":599,"context_line":"                                headers\u003d{\u0027x-backend-storage-policy-index\u0027:"},{"line_number":600,"context_line":"                                         broker.storage_policy_index})"},{"line_number":601,"context_line":""},{"line_number":602,"context_line":"    @public"},{"line_number":603,"context_line":"    @timing_stats(sample_rate\u003d0.1)"}],"source_content_type":"text/x-python","patch_set":1,"id":"e5b45591_640e9783","line":600,"updated":"2023-10-19 16:46:46.000000000","message":"i\u0027d probably extract this bit so it can be re-used in PUT_shard\n\n    return self._return_ok_resp(req, broker, created)","commit_id":"fb7806b3e964a5a08f2010c105f70296f791493b"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"9576a60f983dff8f6a88187f2b4a8592baa3de4b","unresolved":false,"context_lines":[{"line_number":597,"context_line":"        else:"},{"line_number":598,"context_line":"            return HTTPAccepted(request\u003dreq,"},{"line_number":599,"context_line":"                                headers\u003d{\u0027x-backend-storage-policy-index\u0027:"},{"line_number":600,"context_line":"                                         broker.storage_policy_index})"},{"line_number":601,"context_line":""},{"line_number":602,"context_line":"    @public"},{"line_number":603,"context_line":"    @timing_stats(sample_rate\u003d0.1)"}],"source_content_type":"text/x-python","patch_set":1,"id":"0cea9efe_51d2dc9d","line":600,"in_reply_to":"e5b45591_640e9783","updated":"2023-10-20 04:57:12.000000000","message":"Done","commit_id":"fb7806b3e964a5a08f2010c105f70296f791493b"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"56a4e6aad8fb4f2bbef06b5e5d130f2735bc90c2","unresolved":true,"context_lines":[{"line_number":493,"context_line":"            broker.update_metadata(metadata, validate_metadata\u003dTrue)"},{"line_number":494,"context_line":"            self._update_sync_store(broker, method)"},{"line_number":495,"context_line":""},{"line_number":496,"context_line":"    def _return_ok_resp(self, req, broker, created):"},{"line_number":497,"context_line":"        if created:"},{"line_number":498,"context_line":"            return HTTPCreated(request\u003dreq,"},{"line_number":499,"context_line":"                               headers\u003d{\u0027x-backend-storage-policy-index\u0027:"}],"source_content_type":"text/x-python","patch_set":3,"id":"3777d754_c1f0b189","line":496,"updated":"2023-10-26 16:03:46.000000000","message":"For some reason I stumbled on ``_return_*`` as the method name - we tend to use ``create_`` or ``make_`` for methods that construct something and return it.\n\nIDK, my brain is reacting to reading ``return self._return_ok_resp`` with \"wait, this method can\u0027t return on my behalf\".","commit_id":"b2e695a1ed16ba61d28caeaf14c4cb33916355aa"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"2bdfff47719ce29fa60eea6e62568157e7dafd94","unresolved":false,"context_lines":[{"line_number":493,"context_line":"            broker.update_metadata(metadata, validate_metadata\u003dTrue)"},{"line_number":494,"context_line":"            self._update_sync_store(broker, method)"},{"line_number":495,"context_line":""},{"line_number":496,"context_line":"    def _return_ok_resp(self, req, broker, created):"},{"line_number":497,"context_line":"        if created:"},{"line_number":498,"context_line":"            return HTTPCreated(request\u003dreq,"},{"line_number":499,"context_line":"                               headers\u003d{\u0027x-backend-storage-policy-index\u0027:"}],"source_content_type":"text/x-python","patch_set":3,"id":"10ee98f5_7b3d5486","line":496,"in_reply_to":"3777d754_c1f0b189","updated":"2023-10-27 05:07:19.000000000","message":"Done","commit_id":"b2e695a1ed16ba61d28caeaf14c4cb33916355aa"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"56a4e6aad8fb4f2bbef06b5e5d130f2735bc90c2","unresolved":true,"context_lines":[{"line_number":558,"context_line":""},{"line_number":559,"context_line":"    @timing_stats()"},{"line_number":560,"context_line":"    def PUT_shard(self, req, broker, account, req_timestamp):"},{"line_number":561,"context_line":"        \"\"\"Put shard into container.\"\"\""},{"line_number":562,"context_line":"        requested_policy_index \u003d self.get_and_validate_policy_index(req)"},{"line_number":563,"context_line":"        try:"},{"line_number":564,"context_line":"            # validate incoming data..."}],"source_content_type":"text/x-python","patch_set":3,"id":"529d4761_9c0d116e","line":561,"updated":"2023-10-26 16:03:46.000000000","message":"nit: \"PUT shard(s)...\" (i.e plural) unlike object, a PUT can bring multiple shards","commit_id":"b2e695a1ed16ba61d28caeaf14c4cb33916355aa"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"2bdfff47719ce29fa60eea6e62568157e7dafd94","unresolved":false,"context_lines":[{"line_number":558,"context_line":""},{"line_number":559,"context_line":"    @timing_stats()"},{"line_number":560,"context_line":"    def PUT_shard(self, req, broker, account, req_timestamp):"},{"line_number":561,"context_line":"        \"\"\"Put shard into container.\"\"\""},{"line_number":562,"context_line":"        requested_policy_index \u003d self.get_and_validate_policy_index(req)"},{"line_number":563,"context_line":"        try:"},{"line_number":564,"context_line":"            # validate incoming data..."}],"source_content_type":"text/x-python","patch_set":3,"id":"8c4f6ad3_9e629726","line":561,"in_reply_to":"529d4761_9c0d116e","updated":"2023-10-27 05:07:19.000000000","message":"Ack","commit_id":"b2e695a1ed16ba61d28caeaf14c4cb33916355aa"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"56a4e6aad8fb4f2bbef06b5e5d130f2735bc90c2","unresolved":true,"context_lines":[{"line_number":593,"context_line":"        resp \u003d self.account_update(req, account, container, broker)"},{"line_number":594,"context_line":"        if resp:"},{"line_number":595,"context_line":"            return resp"},{"line_number":596,"context_line":"        return self._return_ok_resp(req, broker, created)"},{"line_number":597,"context_line":""},{"line_number":598,"context_line":"    @public"},{"line_number":599,"context_line":"    @timing_stats(sample_rate\u003d0.1)"}],"source_content_type":"text/x-python","patch_set":3,"id":"068ebd4b_c6e8ec86","line":596,"updated":"2023-10-26 16:03:46.000000000","message":"this is all faithful to the original code, just broken into methods. Ideally I\u0027d have the called methods before the caller in the file, but the way it is makes the diff must nicer, so not a big deal.","commit_id":"b2e695a1ed16ba61d28caeaf14c4cb33916355aa"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"2bdfff47719ce29fa60eea6e62568157e7dafd94","unresolved":false,"context_lines":[{"line_number":593,"context_line":"        resp \u003d self.account_update(req, account, container, broker)"},{"line_number":594,"context_line":"        if resp:"},{"line_number":595,"context_line":"            return resp"},{"line_number":596,"context_line":"        return self._return_ok_resp(req, broker, created)"},{"line_number":597,"context_line":""},{"line_number":598,"context_line":"    @public"},{"line_number":599,"context_line":"    @timing_stats(sample_rate\u003d0.1)"}],"source_content_type":"text/x-python","patch_set":3,"id":"6a7d8159_7096b1f1","line":596,"in_reply_to":"068ebd4b_c6e8ec86","updated":"2023-10-27 05:07:19.000000000","message":"Done","commit_id":"b2e695a1ed16ba61d28caeaf14c4cb33916355aa"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e800c5360c600a44899679073948e6a5ede58702","unresolved":true,"context_lines":[{"line_number":769,"context_line":"                                   is_deleted, out_content_type, record_type)"},{"line_number":770,"context_line":""},{"line_number":771,"context_line":"    @timing_stats()"},{"line_number":772,"context_line":"    def GET_shard(self, container, broker, req, params, info,"},{"line_number":773,"context_line":"                  is_deleted, out_content_type, record_type):"},{"line_number":774,"context_line":"        \"\"\""},{"line_number":775,"context_line":"        Returns a list of persisted shard ranges or namespaces in response."}],"source_content_type":"text/x-python","patch_set":4,"id":"63923c5b_9133da39","line":772,"updated":"2023-10-27 15:01:10.000000000","message":"I didn\u0027t notice this before but the PUT_* method signatures are (self, req, broker, account, container...)\n\nI\u0027d prefer these to match that pattern i.e. (self, req, broker, container...) \n\n(a) consistency\n(b) I tend to like args retaining their positional order through a call chain, so GET(req) -\u003e GET_shard(req, broker, ...) - at each call level we\u0027re appending args to those that were passed in.","commit_id":"9858bcdf9ae25d44f704793940c79d63ec9cd53d"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"822a6efbcabb55458983ee8c9400daa07a00cab0","unresolved":false,"context_lines":[{"line_number":769,"context_line":"                                   is_deleted, out_content_type, record_type)"},{"line_number":770,"context_line":""},{"line_number":771,"context_line":"    @timing_stats()"},{"line_number":772,"context_line":"    def GET_shard(self, container, broker, req, params, info,"},{"line_number":773,"context_line":"                  is_deleted, out_content_type, record_type):"},{"line_number":774,"context_line":"        \"\"\""},{"line_number":775,"context_line":"        Returns a list of persisted shard ranges or namespaces in response."}],"source_content_type":"text/x-python","patch_set":4,"id":"b24d2a35_fe60a4ca","line":772,"in_reply_to":"63923c5b_9133da39","updated":"2023-10-28 00:22:48.000000000","message":"Done","commit_id":"9858bcdf9ae25d44f704793940c79d63ec9cd53d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e800c5360c600a44899679073948e6a5ede58702","unresolved":true,"context_lines":[{"line_number":899,"context_line":"                                   broker.metadata, container_list, container,"},{"line_number":900,"context_line":"                                   record_type, shard_format)"},{"line_number":901,"context_line":""},{"line_number":902,"context_line":"    def create_listing(self, req, out_content_type, info, resp_headers,"},{"line_number":903,"context_line":"                       metadata, container_list, container, record_type\u003dNone,"},{"line_number":904,"context_line":"                       shard_record_format\u003dNone):"},{"line_number":905,"context_line":"        for key, (value, _timestamp) in metadata.items():"}],"source_content_type":"text/x-python","patch_set":4,"id":"aec46a80_6a6117ba","line":902,"updated":"2023-10-27 15:01:10.000000000","message":"I wonder how much value there is in retaining this as a shared method?\n\n1. We have to pass in shard_record_format to parameterise update_data_record, instead of having separate update_records for shard and object.\n\n2. xml is not supported for shard/namespace\n\n3. the metadata to headers part could be a helper method","commit_id":"9858bcdf9ae25d44f704793940c79d63ec9cd53d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"48392e8cb568f11f7d49ef9ad2a2f1f6f1850228","unresolved":false,"context_lines":[{"line_number":899,"context_line":"                                   broker.metadata, container_list, container,"},{"line_number":900,"context_line":"                                   record_type, shard_format)"},{"line_number":901,"context_line":""},{"line_number":902,"context_line":"    def create_listing(self, req, out_content_type, info, resp_headers,"},{"line_number":903,"context_line":"                       metadata, container_list, container, record_type\u003dNone,"},{"line_number":904,"context_line":"                       shard_record_format\u003dNone):"},{"line_number":905,"context_line":"        for key, (value, _timestamp) in metadata.items():"}],"source_content_type":"text/x-python","patch_set":4,"id":"f6f81140_f217213d","line":902,"in_reply_to":"aec46a80_6a6117ba","updated":"2023-10-30 13:25:42.000000000","message":"see https://review.opendev.org/c/openstack/swift/+/899583","commit_id":"9858bcdf9ae25d44f704793940c79d63ec9cd53d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"48392e8cb568f11f7d49ef9ad2a2f1f6f1850228","unresolved":false,"context_lines":[{"line_number":861,"context_line":"        Returns a list of persisted shard ranges or namespaces in response."},{"line_number":862,"context_line":""},{"line_number":863,"context_line":"        :param container: container name"},{"line_number":864,"context_line":"        :param broker: container DB broker object"},{"line_number":865,"context_line":"        :param req: swob.Request object"},{"line_number":866,"context_line":"        :param params: the request params."},{"line_number":867,"context_line":"        :param info: the global info for the container"}],"source_content_type":"text/x-python","patch_set":5,"id":"acad0551_3f2e627d","line":864,"updated":"2023-10-30 13:25:42.000000000","message":"params order needs updating","commit_id":"d43d885f251aaaffb9db4102df98b82d5bc98a98"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"a8c70927df00934853aba8de69f69ab63082e71b","unresolved":true,"context_lines":[{"line_number":546,"context_line":"                          wsgi_to_str(req.headers.get(\u0027x-meta-timestamp\u0027)))"},{"line_number":547,"context_line":"        return HTTPCreated(request\u003dreq)"},{"line_number":548,"context_line":""},{"line_number":549,"context_line":"    def _create_ok_resp(self, req, broker, created):"},{"line_number":550,"context_line":"        if created:"},{"line_number":551,"context_line":"            return HTTPCreated(request\u003dreq,"},{"line_number":552,"context_line":"                               headers\u003d{\u0027x-backend-storage-policy-index\u0027:"}],"source_content_type":"text/x-python","patch_set":7,"id":"674d0eab_d9f8959a","line":549,"updated":"2023-11-03 10:07:33.000000000","message":"symmetric comment here https://review.opendev.org/c/openstack/swift/+/890470/34/swift/container/server.py#885\n\ncan we name this _create_PUT_response to disambiguate from a proposed helpert o create a GET response","commit_id":"2dd4a7100cd1cbd019729469e1a17a1b834556e0"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"dd1a9c2b9f36cc1a24ff694c11624923c77098f3","unresolved":false,"context_lines":[{"line_number":546,"context_line":"                          wsgi_to_str(req.headers.get(\u0027x-meta-timestamp\u0027)))"},{"line_number":547,"context_line":"        return HTTPCreated(request\u003dreq)"},{"line_number":548,"context_line":""},{"line_number":549,"context_line":"    def _create_ok_resp(self, req, broker, created):"},{"line_number":550,"context_line":"        if created:"},{"line_number":551,"context_line":"            return HTTPCreated(request\u003dreq,"},{"line_number":552,"context_line":"                               headers\u003d{\u0027x-backend-storage-policy-index\u0027:"}],"source_content_type":"text/x-python","patch_set":7,"id":"c94a059a_fd87c675","line":549,"in_reply_to":"674d0eab_d9f8959a","updated":"2023-11-08 23:35:10.000000000","message":"Ack","commit_id":"2dd4a7100cd1cbd019729469e1a17a1b834556e0"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"0f1e8c7c0629ff3e5646ef8c516e854c1474187f","unresolved":true,"context_lines":[{"line_number":858,"context_line":"    def GET_object(self, req, broker, container, params, info,"},{"line_number":859,"context_line":"                   is_deleted, out_content_type, record_type):"},{"line_number":860,"context_line":"        \"\"\""},{"line_number":861,"context_line":"        Returns a list of persisted shard ranges or namespaces in response."},{"line_number":862,"context_line":""},{"line_number":863,"context_line":"        :param req: swob.Request object"},{"line_number":864,"context_line":"        :param broker: container DB broker object"}],"source_content_type":"text/x-python","patch_set":7,"id":"9b39880a_a4441c90","line":861,"range":{"start_line":861,"start_character":8,"end_line":861,"end_character":75},"updated":"2023-10-31 22:52:21.000000000","message":"Ahh no it doesn\u0027t.. this gets a list of objects.","commit_id":"2dd4a7100cd1cbd019729469e1a17a1b834556e0"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"dd1a9c2b9f36cc1a24ff694c11624923c77098f3","unresolved":false,"context_lines":[{"line_number":858,"context_line":"    def GET_object(self, req, broker, container, params, info,"},{"line_number":859,"context_line":"                   is_deleted, out_content_type, record_type):"},{"line_number":860,"context_line":"        \"\"\""},{"line_number":861,"context_line":"        Returns a list of persisted shard ranges or namespaces in response."},{"line_number":862,"context_line":""},{"line_number":863,"context_line":"        :param req: swob.Request object"},{"line_number":864,"context_line":"        :param broker: container DB broker object"}],"source_content_type":"text/x-python","patch_set":7,"id":"5071e5c7_4688d085","line":861,"range":{"start_line":861,"start_character":8,"end_line":861,"end_character":75},"in_reply_to":"9b39880a_a4441c90","updated":"2023-11-08 23:35:10.000000000","message":"Ack","commit_id":"2dd4a7100cd1cbd019729469e1a17a1b834556e0"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"2ab2341db9409f6f45b4898e010deabe7a5faafb","unresolved":true,"context_lines":[{"line_number":527,"context_line":"        \"\"\"Put object into container.\"\"\""},{"line_number":528,"context_line":"        # obj put expects the policy_index header, default is for"},{"line_number":529,"context_line":"        # legacy support during upgrade."},{"line_number":530,"context_line":"        requested_policy_index \u003d self.get_and_validate_policy_index(req)"},{"line_number":531,"context_line":"        obj_policy_index \u003d requested_policy_index or 0"},{"line_number":532,"context_line":"        self._maybe_autocreate("},{"line_number":533,"context_line":"            broker, req_timestamp, account, obj_policy_index, req)"}],"source_content_type":"text/x-python","patch_set":11,"id":"a07cfd9f_ded47277","line":530,"updated":"2023-11-27 16:54:44.000000000","message":"looks like all the PUT_xxx methods start with get_and_validate_policy_index\n\nmaybe it\u0027s by-design that we want this captured as part of this timing metric","commit_id":"a102055608fe22a807b6e96cbb92c16d5c44dbba"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"2ab2341db9409f6f45b4898e010deabe7a5faafb","unresolved":true,"context_lines":[{"line_number":546,"context_line":"                          wsgi_to_str(req.headers.get(\u0027x-meta-timestamp\u0027)))"},{"line_number":547,"context_line":"        return HTTPCreated(request\u003dreq)"},{"line_number":548,"context_line":""},{"line_number":549,"context_line":"    def _create_ok_resp(self, req, broker, created):"},{"line_number":550,"context_line":"        if created:"},{"line_number":551,"context_line":"            return HTTPCreated(request\u003dreq,"},{"line_number":552,"context_line":"                               headers\u003d{\u0027x-backend-storage-policy-index\u0027:"}],"source_content_type":"text/x-python","patch_set":11,"id":"9dcbd25c_09ceaa28","line":549,"updated":"2023-11-27 16:54:44.000000000","message":"maybe better as _create_PUT_response to match _create_GET_repsonse\n\n... but I guess it\u0027s not used by PUT_object\n\nFWIW the 202 vs 201 behavior is well covered with tests tho","commit_id":"a102055608fe22a807b6e96cbb92c16d5c44dbba"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"2ab2341db9409f6f45b4898e010deabe7a5faafb","unresolved":true,"context_lines":[{"line_number":751,"context_line":"                                            stale_reads_ok\u003dTrue)"},{"line_number":752,"context_line":"        info, is_deleted \u003d broker.get_info_is_deleted()"},{"line_number":753,"context_line":"        record_type \u003d req.headers.get(\u0027x-backend-record-type\u0027, \u0027\u0027).lower()"},{"line_number":754,"context_line":"        db_state \u003d info.get(\u0027db_state\u0027)"},{"line_number":755,"context_line":"        if record_type \u003d\u003d \u0027auto\u0027 and db_state in (SHARDING, SHARDED):"},{"line_number":756,"context_line":"            record_type \u003d \u0027shard\u0027"},{"line_number":757,"context_line":"        if record_type \u003d\u003d \u0027shard\u0027:"}],"source_content_type":"text/x-python","patch_set":11,"id":"9540ae2f_3cb8aab5","line":754,"updated":"2023-11-27 16:54:44.000000000","message":"this roughly matches the pattern in PUT - we have the timing wrap the outer method, which will parse the request, get the broker, and dispatch to METHOD_xxx which also has timing (hopefully only samller than the timing oufo the outer METHOD timing)","commit_id":"a102055608fe22a807b6e96cbb92c16d5c44dbba"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"2ab2341db9409f6f45b4898e010deabe7a5faafb","unresolved":true,"context_lines":[{"line_number":870,"context_line":"                                         container, listing)"},{"line_number":871,"context_line":""},{"line_number":872,"context_line":"    def _create_GET_response(self, req, out_content_type, info, resp_headers,"},{"line_number":873,"context_line":"                             metadata, container, listing):"},{"line_number":874,"context_line":"        for key, (value, _timestamp) in metadata.items():"},{"line_number":875,"context_line":"            if value and (key.lower() in self.save_headers or"},{"line_number":876,"context_line":"                          is_sys_or_user_meta(\u0027container\u0027, key)):"}],"source_content_type":"text/x-python","patch_set":11,"id":"7e35084f_5efbac64","line":873,"updated":"2023-11-27 16:54:44.000000000","message":"this breaks from the PUT pattern where each PUT_xxx helper ends with `create_ok_repsonse`","commit_id":"a102055608fe22a807b6e96cbb92c16d5c44dbba"}],"test/unit/container/test_server.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"56a4e6aad8fb4f2bbef06b5e5d130f2735bc90c2","unresolved":true,"context_lines":[{"line_number":2830,"context_line":"            self.assertEqual(expected, json.loads(resp.body))"},{"line_number":2831,"context_line":"            self.assertIn(\u0027X-Backend-Record-Type\u0027, resp.headers)"},{"line_number":2832,"context_line":"            self.assertEqual(\u0027shard\u0027, resp.headers[\u0027X-Backend-Record-Type\u0027])"},{"line_number":2833,"context_line":"            last_stats \u003d self.logger.statsd_client.calls[\u0027timing_since\u0027][-2]"},{"line_number":2834,"context_line":"            self.assertEqual(\u0027GET_shard.timing\u0027, last_stats[0][0])"},{"line_number":2835,"context_line":"            last_stats \u003d self.logger.statsd_client.calls[\u0027timing_since\u0027][-1]"},{"line_number":2836,"context_line":"            self.assertEqual(\u0027GET.timing\u0027, last_stats[0][0])"}],"source_content_type":"text/x-python","patch_set":3,"id":"360c621c_a43968c4","line":2833,"range":{"start_line":2833,"start_character":12,"end_line":2833,"end_character":23},"updated":"2023-10-26 16:03:46.000000000","message":"I don\u0027t understand the significance of \u0027last\u0027 in \u0027last_stats\u0027 - this is the penultimate call","commit_id":"b2e695a1ed16ba61d28caeaf14c4cb33916355aa"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"2bdfff47719ce29fa60eea6e62568157e7dafd94","unresolved":false,"context_lines":[{"line_number":2830,"context_line":"            self.assertEqual(expected, json.loads(resp.body))"},{"line_number":2831,"context_line":"            self.assertIn(\u0027X-Backend-Record-Type\u0027, resp.headers)"},{"line_number":2832,"context_line":"            self.assertEqual(\u0027shard\u0027, resp.headers[\u0027X-Backend-Record-Type\u0027])"},{"line_number":2833,"context_line":"            last_stats \u003d self.logger.statsd_client.calls[\u0027timing_since\u0027][-2]"},{"line_number":2834,"context_line":"            self.assertEqual(\u0027GET_shard.timing\u0027, last_stats[0][0])"},{"line_number":2835,"context_line":"            last_stats \u003d self.logger.statsd_client.calls[\u0027timing_since\u0027][-1]"},{"line_number":2836,"context_line":"            self.assertEqual(\u0027GET.timing\u0027, last_stats[0][0])"}],"source_content_type":"text/x-python","patch_set":3,"id":"8a1d8dc5_2279f9e2","line":2833,"range":{"start_line":2833,"start_character":12,"end_line":2833,"end_character":23},"in_reply_to":"360c621c_a43968c4","updated":"2023-10-27 05:07:19.000000000","message":"Ack","commit_id":"b2e695a1ed16ba61d28caeaf14c4cb33916355aa"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"56a4e6aad8fb4f2bbef06b5e5d130f2735bc90c2","unresolved":true,"context_lines":[{"line_number":4210,"context_line":"            mock_time.return_value \u003d 1000.99"},{"line_number":4211,"context_line":"            resp \u003d req.get_response(self.controller)"},{"line_number":4212,"context_line":"        self.assertEqual(resp.status_int, 201)"},{"line_number":4213,"context_line":"        last_stats \u003d self.logger.statsd_client.calls[\u0027timing_since\u0027][-2]"},{"line_number":4214,"context_line":"        self.assertEqual(\u0027PUT_object.timing\u0027, last_stats[0][0])"},{"line_number":4215,"context_line":"        self.assertEqual(last_stats[0][1], 1000.99)"},{"line_number":4216,"context_line":"        last_stats \u003d self.logger.statsd_client.calls[\u0027timing_since\u0027][-1]"}],"source_content_type":"text/x-python","patch_set":3,"id":"2fd9a920_a078d863","line":4213,"updated":"2023-10-26 16:03:46.000000000","message":"I think I might clear the logger for each request and assert that these are the *only* calls: if I add an extra @timing_stats the test still passes e.g.\n\n```\ndiff --git a/swift/container/server.py b/swift/container/server.py\nindex 4ccfdb39c..3f468d2d3 100644\n--- a/swift/container/server.py\n+++ b/swift/container/server.py\n@@ -532,6 +532,7 @@ class ContainerController(BaseStorageServer):\n             return self.PUT_container(req, broker, account,\n                                       container, req_timestamp)\n\n+    @timing_stats()\n     @timing_stats()\n     def PUT_object(self, req, broker, account, obj, req_timestamp):\n         \"\"\"Put object into container.\"\"\"\ndiff --git a/test/unit/container/test_server.py b/test/unit/container/test_server.py\nindex 418dad138..6de17e614 100644\n--- a/test/unit/container/test_server.py\n+++ b/test/unit/container/test_server.py\n@@ -4210,6 +4210,8 @@ class TestContainerController(unittest.TestCase):\n             mock_time.return_value \u003d 1000.99\n             resp \u003d req.get_response(self.controller)\n         self.assertEqual(resp.status_int, 201)\n+        last_stats \u003d self.logger.statsd_client.calls[\u0027timing_since\u0027][-3]\n+        self.assertEqual(\u0027PUT_object.timing\u0027, last_stats[0][0])\n         last_stats \u003d self.logger.statsd_client.calls[\u0027timing_since\u0027][-2]\n         self.assertEqual(\u0027PUT_object.timing\u0027, last_stats[0][0])\n         self.assertEqual(last_stats[0][1], 1000.99)\n```","commit_id":"b2e695a1ed16ba61d28caeaf14c4cb33916355aa"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"2bdfff47719ce29fa60eea6e62568157e7dafd94","unresolved":false,"context_lines":[{"line_number":4210,"context_line":"            mock_time.return_value \u003d 1000.99"},{"line_number":4211,"context_line":"            resp \u003d req.get_response(self.controller)"},{"line_number":4212,"context_line":"        self.assertEqual(resp.status_int, 201)"},{"line_number":4213,"context_line":"        last_stats \u003d self.logger.statsd_client.calls[\u0027timing_since\u0027][-2]"},{"line_number":4214,"context_line":"        self.assertEqual(\u0027PUT_object.timing\u0027, last_stats[0][0])"},{"line_number":4215,"context_line":"        self.assertEqual(last_stats[0][1], 1000.99)"},{"line_number":4216,"context_line":"        last_stats \u003d self.logger.statsd_client.calls[\u0027timing_since\u0027][-1]"}],"source_content_type":"text/x-python","patch_set":3,"id":"4741f4df_d9913ef2","line":4213,"in_reply_to":"2fd9a920_a078d863","updated":"2023-10-27 05:07:19.000000000","message":"Ack","commit_id":"b2e695a1ed16ba61d28caeaf14c4cb33916355aa"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"56a4e6aad8fb4f2bbef06b5e5d130f2735bc90c2","unresolved":true,"context_lines":[{"line_number":4287,"context_line":"        self.assertEqual(last_stats[0][1], 1000.99)"},{"line_number":4288,"context_line":"        last_stats \u003d self.logger.statsd_client.calls[\u0027timing_since\u0027][-1]"},{"line_number":4289,"context_line":"        self.assertEqual(\u0027GET.timing\u0027, last_stats[0][0])"},{"line_number":4290,"context_line":"        self.assertEqual(last_stats[0][1], 1000.99)"},{"line_number":4291,"context_line":""},{"line_number":4292,"context_line":"    def test_DELETE_object_update_redirected_to_shard(self):"},{"line_number":4293,"context_line":"        self._check_object_update_redirected_to_shard(\u0027DELETE\u0027)"}],"source_content_type":"text/x-python","patch_set":3,"id":"7f0b77e3_0b255c41","line":4290,"updated":"2023-10-26 16:03:46.000000000","message":"very comprehensive. nit: each request could be separate test methods, there\u0027s no common setup, and the response status (success) isn\u0027t significant.","commit_id":"b2e695a1ed16ba61d28caeaf14c4cb33916355aa"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"2bdfff47719ce29fa60eea6e62568157e7dafd94","unresolved":false,"context_lines":[{"line_number":4287,"context_line":"        self.assertEqual(last_stats[0][1], 1000.99)"},{"line_number":4288,"context_line":"        last_stats \u003d self.logger.statsd_client.calls[\u0027timing_since\u0027][-1]"},{"line_number":4289,"context_line":"        self.assertEqual(\u0027GET.timing\u0027, last_stats[0][0])"},{"line_number":4290,"context_line":"        self.assertEqual(last_stats[0][1], 1000.99)"},{"line_number":4291,"context_line":""},{"line_number":4292,"context_line":"    def test_DELETE_object_update_redirected_to_shard(self):"},{"line_number":4293,"context_line":"        self._check_object_update_redirected_to_shard(\u0027DELETE\u0027)"}],"source_content_type":"text/x-python","patch_set":3,"id":"74aedef0_9d86a708","line":4290,"in_reply_to":"7f0b77e3_0b255c41","updated":"2023-10-27 05:07:19.000000000","message":"Done","commit_id":"b2e695a1ed16ba61d28caeaf14c4cb33916355aa"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e800c5360c600a44899679073948e6a5ede58702","unresolved":true,"context_lines":[{"line_number":4235,"context_line":"        self.assertEqual(resp.content_type, \u0027application/json\u0027)"},{"line_number":4236,"context_line":"        self.assertEqual(\u0027object\u0027, resp.headers[\u0027X-Backend-Record-Type\u0027])"},{"line_number":4237,"context_line":"        stats \u003d self.logger.statsd_client.calls[\u0027timing_since\u0027]"},{"line_number":4238,"context_line":"        self.assertEqual(2, len(stats))"},{"line_number":4239,"context_line":"        self.assertEqual(\u0027GET_object.timing\u0027, stats[-2][0][0])"},{"line_number":4240,"context_line":"        self.assertEqual(stats[-2][0][1], 1000.99)"},{"line_number":4241,"context_line":"        self.assertEqual(\u0027GET.timing\u0027, stats[-1][0][0])"}],"source_content_type":"text/x-python","patch_set":4,"id":"b32448f0_566f4891","line":4238,"updated":"2023-10-27 15:01:10.000000000","message":"same at line 4223?","commit_id":"9858bcdf9ae25d44f704793940c79d63ec9cd53d"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"822a6efbcabb55458983ee8c9400daa07a00cab0","unresolved":false,"context_lines":[{"line_number":4235,"context_line":"        self.assertEqual(resp.content_type, \u0027application/json\u0027)"},{"line_number":4236,"context_line":"        self.assertEqual(\u0027object\u0027, resp.headers[\u0027X-Backend-Record-Type\u0027])"},{"line_number":4237,"context_line":"        stats \u003d self.logger.statsd_client.calls[\u0027timing_since\u0027]"},{"line_number":4238,"context_line":"        self.assertEqual(2, len(stats))"},{"line_number":4239,"context_line":"        self.assertEqual(\u0027GET_object.timing\u0027, stats[-2][0][0])"},{"line_number":4240,"context_line":"        self.assertEqual(stats[-2][0][1], 1000.99)"},{"line_number":4241,"context_line":"        self.assertEqual(\u0027GET.timing\u0027, stats[-1][0][0])"}],"source_content_type":"text/x-python","patch_set":4,"id":"f1c5f551_b27040d9","line":4238,"in_reply_to":"b32448f0_566f4891","updated":"2023-10-28 00:22:48.000000000","message":"Done","commit_id":"9858bcdf9ae25d44f704793940c79d63ec9cd53d"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"2ab2341db9409f6f45b4898e010deabe7a5faafb","unresolved":true,"context_lines":[{"line_number":4014,"context_line":"        self.assertEqual(\u0027GET_shard.timing\u0027, stats[-2][0][0])"},{"line_number":4015,"context_line":"        self.assertEqual(stats[-2][0][1], 1000.99)"},{"line_number":4016,"context_line":"        self.assertEqual(\u0027GET.timing\u0027, stats[-1][0][0])"},{"line_number":4017,"context_line":"        self.assertEqual(stats[-1][0][1], 1000.99)"},{"line_number":4018,"context_line":""},{"line_number":4019,"context_line":"    def test_DELETE_object_update_redirected_to_shard(self):"},{"line_number":4020,"context_line":"        self._check_object_update_redirected_to_shard(\u0027DELETE\u0027)"}],"source_content_type":"text/x-python","patch_set":11,"id":"b146f577_01421546","line":4017,"updated":"2023-11-27 16:54:44.000000000","message":"i think these new tests cover the new timing metrics the best","commit_id":"a102055608fe22a807b6e96cbb92c16d5c44dbba"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"2ab2341db9409f6f45b4898e010deabe7a5faafb","unresolved":true,"context_lines":[{"line_number":4695,"context_line":"            self.logger.statsd_client.calls[\u0027timing_since\u0027][-2][0][0])"},{"line_number":4696,"context_line":"        self.assertEqual("},{"line_number":4697,"context_line":"            \u0027GET.timing\u0027,"},{"line_number":4698,"context_line":"            self.logger.statsd_client.calls[\u0027timing_since\u0027][-1][0][0])"},{"line_number":4699,"context_line":""},{"line_number":4700,"context_line":"    def test_GET_multichar_delimiter(self):"},{"line_number":4701,"context_line":"        self.maxDiff \u003d None"}],"source_content_type":"text/x-python","patch_set":11,"id":"e2a8b79e_8ec7279d","line":4698,"updated":"2023-11-27 16:54:44.000000000","message":"When writing assertions I like to think about how they fail with the change reverted.  At first glace this one fails like a PUT timing became a GET timing:\n\n    \u003e       self.assertEqual(\n                \u0027GET_object.timing\u0027,\n                self.logger.statsd_client.calls[\u0027timing_since\u0027][-2][0][0])\n    E       AssertionError: \u0027GET_object.timing\u0027 !\u003d \u0027PUT.timing\u0027\n    E       - GET_object.timing\n    E       + PUT.timing\n\nSince we\u0027re just adding these asserts to existing tests it might be more clear as:\n\n    diff --git a/test/unit/container/test_server.py b/test/unit/container/test_server.py\n    index df571ea8a..b759dd8b7 100644\n    --- a/test/unit/container/test_server.py\n    +++ b/test/unit/container/test_server.py\n    @@ -4690,12 +4690,12 @@ class TestContainerController(unittest.TestCase):\n                 [{\"subdir\": \"US-OK-\"},\n                  {\"subdir\": \"US-TX-\"},\n                  {\"subdir\": \"US-UT-\"}])\n    +        actual \u003d [args[0] for args, kwargs\n    +                  in self.logger.statsd_client.calls[\u0027timing_since\u0027]]\n             self.assertEqual(\n    -            \u0027GET_object.timing\u0027,\n    -            self.logger.statsd_client.calls[\u0027timing_since\u0027][-2][0][0])\n    -        self.assertEqual(\n    -            \u0027GET.timing\u0027,\n    -            self.logger.statsd_client.calls[\u0027timing_since\u0027][-1][0][0])\n    +            [\u0027PUT_container.timing\u0027, \u0027PUT.timing\u0027] + [\n    +            \u0027PUT_object.timing\u0027, \u0027PUT.timing\u0027] * 5 + [\n    +            \u0027GET_object.timing\u0027, \u0027GET.timing\u0027], actual)\n     \n         def test_GET_multichar_delimiter(self):\n             self.maxDiff \u003d None\n\nthe failure highlights both of the new `PUT_*` and `GET_*` timings:\n\n    \u003e       self.assertEqual(\n                [\u0027PUT_container.timing\u0027, \u0027PUT.timing\u0027] + [\n                \u0027PUT_object.timing\u0027, \u0027PUT.timing\u0027] * 5 + [\n                \u0027GET_object.timing\u0027, \u0027GET.timing\u0027], actual)\n    E       AssertionError: Lists differ: [\u0027PUT_container.timing\u0027, \u0027PUT.timing\u0027, \u0027PUT_ob[197 chars]ing\u0027] !\u003d [\u0027PUT.timing\u0027, \u0027PUT.timing\u0027, \u0027PUT.timing\u0027, \u0027PU[47 chars]ing\u0027]\n    E       \n    E       First differing element 0:\n    E       \u0027PUT_container.timing\u0027\n    E       \u0027PUT.timing\u0027\n    E       \n    E       First list contains 7 additional elements.\n    E       First extra element 7:\n    E       \u0027PUT.timing\u0027\n    E       \n    E       - [\u0027PUT_container.timing\u0027,\n    E       + [\u0027PUT.timing\u0027,\n    E          \u0027PUT.timing\u0027,\n    E       -  \u0027PUT_object.timing\u0027,\n    E          \u0027PUT.timing\u0027,\n    E       -  \u0027PUT_object.timing\u0027,\n    E          \u0027PUT.timing\u0027,\n    E       -  \u0027PUT_object.timing\u0027,\n    E          \u0027PUT.timing\u0027,\n    E       -  \u0027PUT_object.timing\u0027,\n    E          \u0027PUT.timing\u0027,\n    E       -  \u0027PUT_object.timing\u0027,\n    E       -  \u0027PUT.timing\u0027,\n    E       -  \u0027GET_object.timing\u0027,\n    E          \u0027GET.timing\u0027]\n\n    swift/test/unit/container/test_server.py:4695: AssertionError","commit_id":"a102055608fe22a807b6e96cbb92c16d5c44dbba"}]}
