)]}'
{"swift/common/db_replicator.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"732223b8aad29f9b434e547c5f6f3a0ec2d1c341","unresolved":false,"context_lines":[{"line_number":233,"context_line":""},{"line_number":234,"context_line":"    def _zero_stats(self):"},{"line_number":235,"context_line":"        \"\"\"Zero out the stats.\"\"\""},{"line_number":236,"context_line":"        self.stats \u003d Stats()"},{"line_number":237,"context_line":""},{"line_number":238,"context_line":"    def _report_stats(self, start):"},{"line_number":239,"context_line":"        \"\"\"Report the current stats to the logs.\"\"\""}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_cdba640a","line":236,"updated":"2018-06-27 23:27:00.000000000","message":"So this no longer resets start? Wait, is stats.start even *used* now?","commit_id":"35b5618ebab87c4e1c06146e2668989fdc4708ab"},{"author":{"_account_id":2622,"name":"Samuel Merritt","email":"spam+launchpad@andcheese.org","username":"torgomatic"},"change_message_id":"53bba342787a1a3e06fbc56a1aa3450ec583370d","unresolved":false,"context_lines":[{"line_number":233,"context_line":""},{"line_number":234,"context_line":"    def _zero_stats(self):"},{"line_number":235,"context_line":"        \"\"\"Zero out the stats.\"\"\""},{"line_number":236,"context_line":"        self.stats \u003d Stats()"},{"line_number":237,"context_line":""},{"line_number":238,"context_line":"    def _report_stats(self, start):"},{"line_number":239,"context_line":"        \"\"\"Report the current stats to the logs.\"\"\""}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_f3a5ac04","line":236,"in_reply_to":"5f7c97a3_cdba640a","updated":"2018-06-28 23:27:15.000000000","message":"Nope, I moved start out of stats. For multiprocess replication, start-time isn\u0027t a particularly useful thing to try to aggregate.\n\nI\u0027ll take it out of the Stats object.","commit_id":"35b5618ebab87c4e1c06146e2668989fdc4708ab"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"732223b8aad29f9b434e547c5f6f3a0ec2d1c341","unresolved":false,"context_lines":[{"line_number":802,"context_line":"            self.logger.warning("},{"line_number":803,"context_line":"                \u0027Finished replication pass with handoffs_only enabled. \u0027"},{"line_number":804,"context_line":"                \u0027If handoffs_only is no longer required, disable it.\u0027)"},{"line_number":805,"context_line":"        self._report_stats(start)"},{"line_number":806,"context_line":""},{"line_number":807,"context_line":"    def run_forever(self, *args, **kwargs):"},{"line_number":808,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_adb848c7","line":805,"updated":"2018-06-27 23:27:00.000000000","message":"So the sharder picks up self.start_time but the replicator has to plumb it through function calls? Could we just pick one way to do it?","commit_id":"35b5618ebab87c4e1c06146e2668989fdc4708ab"}],"swift/common/utils.py":[{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"58fc86d89c2a7e7f7657d049849e7ac0c001a49a","unresolved":false,"context_lines":[{"line_number":4782,"context_line":"        for field in self.simple_fields:"},{"line_number":4783,"context_line":"            setattr(total, field, getattr(self, field) + getattr(other, field))"},{"line_number":4784,"context_line":""},{"line_number":4785,"context_line":"        all_failed_ips \u003d (set(self.failure_nodes.keys() +"},{"line_number":4786,"context_line":"                              other.failure_nodes.keys()))"},{"line_number":4787,"context_line":"        for ip in all_failed_ips:"},{"line_number":4788,"context_line":"            self_devs \u003d self.failure_nodes.get(ip, {})"},{"line_number":4789,"context_line":"            other_devs \u003d other.failure_nodes.get(ip, {})"}],"source_content_type":"text/x-python","patch_set":1,"id":"9f6a8fd7_cf09f395","line":4786,"range":{"start_line":4785,"start_character":30,"end_line":4786,"end_character":56},"updated":"2018-04-27 01:53:43.000000000","message":"These aren\u0027t actually lists or tuples in Python3. So you can concat like this. You need to turn them to list or tuples here and below to get the py3 tests passing.\n\nsomething like: http://paste.openstack.org/show/719982/","commit_id":"b68b62adb2be86a6d49e0983354a514f1e4bbf94"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"58fc86d89c2a7e7f7657d049849e7ac0c001a49a","unresolved":false,"context_lines":[{"line_number":4788,"context_line":"            self_devs \u003d self.failure_nodes.get(ip, {})"},{"line_number":4789,"context_line":"            other_devs \u003d other.failure_nodes.get(ip, {})"},{"line_number":4790,"context_line":"            this_ip_failures \u003d {}"},{"line_number":4791,"context_line":"            for dev in set(self_devs.keys() + other_devs.keys()):"},{"line_number":4792,"context_line":"                this_ip_failures[dev] \u003d ("},{"line_number":4793,"context_line":"                    self_devs.get(dev, 0) + other_devs.get(dev, 0))"},{"line_number":4794,"context_line":"            total.failure_nodes[ip] \u003d this_ip_failures"}],"source_content_type":"text/x-python","patch_set":1,"id":"9f6a8fd7_4ff5e382","line":4791,"range":{"start_line":4791,"start_character":27,"end_line":4791,"end_character":63},"updated":"2018-04-27 01:53:43.000000000","message":"as above.\n\nAnd welcome to the world and fun of Python3 :P","commit_id":"b68b62adb2be86a6d49e0983354a514f1e4bbf94"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"732223b8aad29f9b434e547c5f6f3a0ec2d1c341","unresolved":false,"context_lines":[{"line_number":5411,"context_line":"    return sorted(results)"},{"line_number":5412,"context_line":""},{"line_number":5413,"context_line":""},{"line_number":5414,"context_line":"class StatsBucket(object):"},{"line_number":5415,"context_line":"    # To use this, you must subclass it and provide a class attribute"},{"line_number":5416,"context_line":"    # \u0027simple_fields\u0027 that is a list of statistic names."},{"line_number":5417,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_6d0eb08d","line":5414,"updated":"2018-06-27 23:27:00.000000000","message":"Does anything directly inherit from or otherwise use this *besides* ReplicatorStats? Or is that coming in a later patchset?","commit_id":"35b5618ebab87c4e1c06146e2668989fdc4708ab"},{"author":{"_account_id":2622,"name":"Samuel Merritt","email":"spam+launchpad@andcheese.org","username":"torgomatic"},"change_message_id":"53bba342787a1a3e06fbc56a1aa3450ec583370d","unresolved":false,"context_lines":[{"line_number":5411,"context_line":"    return sorted(results)"},{"line_number":5412,"context_line":""},{"line_number":5413,"context_line":""},{"line_number":5414,"context_line":"class StatsBucket(object):"},{"line_number":5415,"context_line":"    # To use this, you must subclass it and provide a class attribute"},{"line_number":5416,"context_line":"    # \u0027simple_fields\u0027 that is a list of statistic names."},{"line_number":5417,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_c2f3f708","line":5414,"in_reply_to":"5f7c97a3_6d0eb08d","updated":"2018-06-28 23:27:15.000000000","message":"I\u0027d planned for it in a later patchset. I like the stats-object pattern more than the dict-of-stats one, especially defaultdict, because it\u0027s a lot harder to mistype a stat name and silently fail.","commit_id":"35b5618ebab87c4e1c06146e2668989fdc4708ab"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"732223b8aad29f9b434e547c5f6f3a0ec2d1c341","unresolved":false,"context_lines":[{"line_number":5437,"context_line":"        for field in self.simple_fields:"},{"line_number":5438,"context_line":"            setattr(total, field, getattr(self, field) + getattr(other, field))"},{"line_number":5439,"context_line":""},{"line_number":5440,"context_line":"        all_failed_ips \u003d set(self.failure_nodes.keys()).union("},{"line_number":5441,"context_line":"            other.failure_nodes.keys())"},{"line_number":5442,"context_line":"        for ip in all_failed_ips:"},{"line_number":5443,"context_line":"            self_devs \u003d self.failure_nodes.get(ip, {})"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_0df5bc84","line":5440,"range":{"start_line":5440,"start_character":34,"end_line":5440,"end_character":47},"updated":"2018-06-27 23:27:00.000000000","message":"Are we sure this won\u0027t raise AttributeError?","commit_id":"35b5618ebab87c4e1c06146e2668989fdc4708ab"},{"author":{"_account_id":2622,"name":"Samuel Merritt","email":"spam+launchpad@andcheese.org","username":"torgomatic"},"change_message_id":"53bba342787a1a3e06fbc56a1aa3450ec583370d","unresolved":false,"context_lines":[{"line_number":5437,"context_line":"        for field in self.simple_fields:"},{"line_number":5438,"context_line":"            setattr(total, field, getattr(self, field) + getattr(other, field))"},{"line_number":5439,"context_line":""},{"line_number":5440,"context_line":"        all_failed_ips \u003d set(self.failure_nodes.keys()).union("},{"line_number":5441,"context_line":"            other.failure_nodes.keys())"},{"line_number":5442,"context_line":"        for ip in all_failed_ips:"},{"line_number":5443,"context_line":"            self_devs \u003d self.failure_nodes.get(ip, {})"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_e2cdd3ba","line":5440,"range":{"start_line":5440,"start_character":34,"end_line":5440,"end_character":47},"in_reply_to":"5f7c97a3_0df5bc84","updated":"2018-06-28 23:27:15.000000000","message":"No, I just goofed that one up. I even fixed it before, but then I goofed up the rebase and brought it back. :|","commit_id":"35b5618ebab87c4e1c06146e2668989fdc4708ab"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"732223b8aad29f9b434e547c5f6f3a0ec2d1c341","unresolved":false,"context_lines":[{"line_number":5467,"context_line":""},{"line_number":5468,"context_line":"        :param failures: a list of (ip, device-name) pairs that failed"},{"line_number":5469,"context_line":"        \"\"\""},{"line_number":5470,"context_line":"        self.failure +\u003d len(failures)"},{"line_number":5471,"context_line":"        for ip, device in failures:"},{"line_number":5472,"context_line":"            self.failure_nodes[ip][device] +\u003d 1"},{"line_number":5473,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_0df4dccf","line":5470,"updated":"2018-06-27 23:27:00.000000000","message":"So we require that all subclasses include \u0027failure\u0027 in simple_fields, yeah?","commit_id":"35b5618ebab87c4e1c06146e2668989fdc4708ab"},{"author":{"_account_id":2622,"name":"Samuel Merritt","email":"spam+launchpad@andcheese.org","username":"torgomatic"},"change_message_id":"53bba342787a1a3e06fbc56a1aa3450ec583370d","unresolved":false,"context_lines":[{"line_number":5467,"context_line":""},{"line_number":5468,"context_line":"        :param failures: a list of (ip, device-name) pairs that failed"},{"line_number":5469,"context_line":"        \"\"\""},{"line_number":5470,"context_line":"        self.failure +\u003d len(failures)"},{"line_number":5471,"context_line":"        for ip, device in failures:"},{"line_number":5472,"context_line":"            self.failure_nodes[ip][device] +\u003d 1"},{"line_number":5473,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_9b232a59","line":5470,"in_reply_to":"5f7c97a3_0df4dccf","updated":"2018-06-28 23:27:15.000000000","message":"Uh, seems so. Hm. That\u0027s probably not great. I can make it conditional.","commit_id":"35b5618ebab87c4e1c06146e2668989fdc4708ab"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"732223b8aad29f9b434e547c5f6f3a0ec2d1c341","unresolved":false,"context_lines":[{"line_number":5480,"context_line":"    def from_recon(cls, dct):"},{"line_number":5481,"context_line":"        obj \u003d super(ReplicatorStats, cls).from_recon(dct)"},{"line_number":5482,"context_line":"        if \u0027failure_nodes\u0027 in dct:"},{"line_number":5483,"context_line":"            obj.failure_nodes \u003d dct[\u0027failure_nodes\u0027]"},{"line_number":5484,"context_line":"        return obj"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_2d1af817","line":5483,"updated":"2018-06-27 23:27:00.000000000","message":"But we will have lost the defaultdict-ness, yeah?","commit_id":"35b5618ebab87c4e1c06146e2668989fdc4708ab"},{"author":{"_account_id":2622,"name":"Samuel Merritt","email":"spam+launchpad@andcheese.org","username":"torgomatic"},"change_message_id":"53bba342787a1a3e06fbc56a1aa3450ec583370d","unresolved":false,"context_lines":[{"line_number":5480,"context_line":"    def from_recon(cls, dct):"},{"line_number":5481,"context_line":"        obj \u003d super(ReplicatorStats, cls).from_recon(dct)"},{"line_number":5482,"context_line":"        if \u0027failure_nodes\u0027 in dct:"},{"line_number":5483,"context_line":"            obj.failure_nodes \u003d dct[\u0027failure_nodes\u0027]"},{"line_number":5484,"context_line":"        return obj"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_a2c7db98","line":5483,"in_reply_to":"5f7c97a3_2d1af817","updated":"2018-06-28 23:27:15.000000000","message":"Whoops, I\u0027ll go fix that.","commit_id":"35b5618ebab87c4e1c06146e2668989fdc4708ab"}],"swift/container/sharder.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"732223b8aad29f9b434e547c5f6f3a0ec2d1c341","unresolved":false,"context_lines":[{"line_number":485,"context_line":"        statsdump \u003d {\u0027sharding_stats\u0027: self.stats.to_recon(),"},{"line_number":486,"context_line":"                     \u0027sharding_time\u0027: elapsed,"},{"line_number":487,"context_line":"                     \u0027sharding_last\u0027: now}"},{"line_number":488,"context_line":"        statsdump[\u0027sharding_stats\u0027][\u0027sharding\u0027] \u003d self.sharding_stats"},{"line_number":489,"context_line":"        dump_recon_cache(statsdump, self.rcache, self.logger)"},{"line_number":490,"context_line":"        self.reported \u003d now"},{"line_number":491,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_2d9bd864","line":488,"range":{"start_line":488,"start_character":8,"end_line":488,"end_character":69},"updated":"2018-06-27 23:27:00.000000000","message":"These words don\u0027t even mean anything to me anymore...","commit_id":"35b5618ebab87c4e1c06146e2668989fdc4708ab"}],"test/unit/common/test_utils.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"732223b8aad29f9b434e547c5f6f3a0ec2d1c341","unresolved":false,"context_lines":[{"line_number":7742,"context_line":"                         actual)"},{"line_number":7743,"context_line":""},{"line_number":7744,"context_line":""},{"line_number":7745,"context_line":"class ReplStats(utils.ReplicatorStats):"},{"line_number":7746,"context_line":"    simple_fields \u003d [\u0027attempted\u0027, \u0027success\u0027, \u0027failure\u0027, \u0027catastrophe\u0027]"},{"line_number":7747,"context_line":""},{"line_number":7748,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_8dc22c02","line":7745,"range":{"start_line":7745,"start_character":16,"end_line":7745,"end_character":37},"updated":"2018-06-27 23:27:00.000000000","message":"I feel like we should have some tests for StatsBucket, too...","commit_id":"35b5618ebab87c4e1c06146e2668989fdc4708ab"},{"author":{"_account_id":2622,"name":"Samuel Merritt","email":"spam+launchpad@andcheese.org","username":"torgomatic"},"change_message_id":"53bba342787a1a3e06fbc56a1aa3450ec583370d","unresolved":false,"context_lines":[{"line_number":7742,"context_line":"                         actual)"},{"line_number":7743,"context_line":""},{"line_number":7744,"context_line":""},{"line_number":7745,"context_line":"class ReplStats(utils.ReplicatorStats):"},{"line_number":7746,"context_line":"    simple_fields \u003d [\u0027attempted\u0027, \u0027success\u0027, \u0027failure\u0027, \u0027catastrophe\u0027]"},{"line_number":7747,"context_line":""},{"line_number":7748,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_368d4d7c","line":7745,"range":{"start_line":7745,"start_character":16,"end_line":7745,"end_character":37},"in_reply_to":"5f7c97a3_8dc22c02","updated":"2018-06-28 23:27:15.000000000","message":"Done","commit_id":"35b5618ebab87c4e1c06146e2668989fdc4708ab"}]}
