)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"311ac3a192a54fa16becfd07a4763f7b697600ae","unresolved":false,"context_lines":[{"line_number":12,"context_line":"While in handoffs_only mode the reconstructor won\u0027t even look at primary"},{"line_number":13,"context_line":"partitions."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"This has a *huge* impact on cycle time once the node has completed"},{"line_number":16,"context_line":"processing handoffs; which results in a much faster and stronger signal"},{"line_number":17,"context_line":"that that it\u0027s either time to rebalance again or turn off handoffs_only."},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"Related-Change-Id: Idde4b6cf92fab6c45f2c0c2733277701eb436898"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":7,"id":"3f1d235d_d3cbe06f","line":16,"range":{"start_line":15,"start_character":11,"end_line":16,"end_character":19},"updated":"2017-07-10 13:59:19.000000000","message":"I made a very, very simple comparison, on SAIO created 1000 empty objects in a 4+2 EC policy, 1024 partitions, no rebalance required, set handoffs_only\u003dTrue. This patch shows approx 4x faster reconstructor cycle time vs master.","commit_id":"44c63c69909e532e383017e7c900e4b7d13e0165"}],"swift/obj/reconstructor.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"220cf0ebcd3165c2ed65b4c1483f19512cb5fdcc","unresolved":false,"context_lines":[{"line_number":750,"context_line":"        jobs \u003d []"},{"line_number":751,"context_line":""},{"line_number":752,"context_line":"        # check the primary nodes - to see if the part belongs here"},{"line_number":753,"context_line":"        part_nodes \u003d policy.object_ring.get_part_nodes(partition)"},{"line_number":754,"context_line":"        for node in part_nodes:"},{"line_number":755,"context_line":"            if node[\u0027id\u0027] \u003d\u003d local_dev[\u0027id\u0027]:"},{"line_number":756,"context_line":"                # this partition belongs here, we\u0027ll need a sync job"}],"source_content_type":"text/x-python","patch_set":2,"id":"3a461143_f8d2815a","line":753,"updated":"2017-02-02 20:50:42.000000000","message":"and of course this is the *other* call to get_part_nodes once we acctually have the frag_indexes and can find the *specific* primary we need to revert to.","commit_id":"ebf94fb60a81ff89636f72900efdbb8d74124e5a"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"220cf0ebcd3165c2ed65b4c1483f19512cb5fdcc","unresolved":false,"context_lines":[{"line_number":886,"context_line":"                        for n in policy.object_ring.get_part_nodes("},{"line_number":887,"context_line":"                            partition))"},{"line_number":888,"context_line":"                    part_info \u003d {"},{"line_number":889,"context_line":"                        \u0027primary\u0027: primary,"},{"line_number":890,"context_line":"                        \u0027local_dev\u0027: local_dev,"},{"line_number":891,"context_line":"                        \u0027policy\u0027: policy,"},{"line_number":892,"context_line":"                        \u0027partition\u0027: partition,"}],"source_content_type":"text/x-python","patch_set":2,"id":"3a461143_7891319a","line":889,"updated":"2017-02-02 20:50:42.000000000","message":"I think this is pretty cheap - I\u0027m more in favor of calling get_part_nodes twice rather than decorating each part_info with references to the primary nodes.  I don\u0027t really believe the difference of burning a few extra cpu cycles vs. the memory overhead of carry around a additional cached reference to the list of dicts is enough to make an objective opinion on which way to go - so it\u0027s more of an aesthetic preference.","commit_id":"ebf94fb60a81ff89636f72900efdbb8d74124e5a"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"c3bc8eeedafb439feb1786c2fa8a0410579737fb","unresolved":false,"context_lines":[{"line_number":674,"context_line":"        self.logger.timing_since(\u0027partition.delete.timing\u0027, begin)"},{"line_number":675,"context_line":""},{"line_number":676,"context_line":"    def _get_part_jobs(self, local_dev, part_path, partition, policy,"},{"line_number":677,"context_line":"                       **kwargs):"},{"line_number":678,"context_line":"        \"\"\""},{"line_number":679,"context_line":"        Helper function to build jobs for a partition, this method will"},{"line_number":680,"context_line":"        read the suffix hashes and create job dictionaries to describe"}],"source_content_type":"text/x-python","patch_set":3,"id":"1a430d35_ab8c6936","line":677,"updated":"2017-02-02 23:06:07.000000000","message":"?","commit_id":"586001b7b1e6a564e42f5daac9069aa8850ae018"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"144dc98860de0fab5f3731fef5a2152101b29564","unresolved":false,"context_lines":[{"line_number":674,"context_line":"        self.logger.timing_since(\u0027partition.delete.timing\u0027, begin)"},{"line_number":675,"context_line":""},{"line_number":676,"context_line":"    def _get_part_jobs(self, local_dev, part_path, partition, policy,"},{"line_number":677,"context_line":"                       **kwargs):"},{"line_number":678,"context_line":"        \"\"\""},{"line_number":679,"context_line":"        Helper function to build jobs for a partition, this method will"},{"line_number":680,"context_line":"        read the suffix hashes and create job dictionaries to describe"}],"source_content_type":"text/x-python","patch_set":3,"id":"1a430d35_eeaf5f92","line":677,"in_reply_to":"1a430d35_ab8c6936","updated":"2017-02-02 23:30:30.000000000","message":"j/c the primary kwarg - I figured we may have reasons to annotate other things about parts in the future maybe?","commit_id":"586001b7b1e6a564e42f5daac9069aa8850ae018"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"becbb30d9fd6e675f57fc13b995b31ebe16f6f1f","unresolved":false,"context_lines":[{"line_number":674,"context_line":"        self.logger.timing_since(\u0027partition.delete.timing\u0027, begin)"},{"line_number":675,"context_line":""},{"line_number":676,"context_line":"    def _get_part_jobs(self, local_dev, part_path, partition, policy,"},{"line_number":677,"context_line":"                       **kwargs):"},{"line_number":678,"context_line":"        \"\"\""},{"line_number":679,"context_line":"        Helper function to build jobs for a partition, this method will"},{"line_number":680,"context_line":"        read the suffix hashes and create job dictionaries to describe"}],"source_content_type":"text/x-python","patch_set":3,"id":"1a430d35_ce0b837c","line":677,"in_reply_to":"1a430d35_eeaf5f92","updated":"2017-02-02 23:37:55.000000000","message":"I think I\u0027d rather we fix the test cases to be *vaguely* representative of reality -- http://paste.openstack.org/show/597457/","commit_id":"586001b7b1e6a564e42f5daac9069aa8850ae018"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"46842d1950d5d19819c9da64a37d12f115cea7cb","unresolved":false,"context_lines":[{"line_number":907,"context_line":"        N.B. If this function ever returns an empty list of jobs the entire"},{"line_number":908,"context_line":"        partition will be deleted."},{"line_number":909,"context_line":"        \"\"\""},{"line_number":910,"context_line":"        jobs \u003d self._get_part_jobs(**part_info)"},{"line_number":911,"context_line":"        random.shuffle(jobs)"},{"line_number":912,"context_line":"        self.job_count +\u003d len(jobs)"},{"line_number":913,"context_line":"        return jobs"}],"source_content_type":"text/x-python","patch_set":5,"id":"1a430d35_31f628d8","line":910,"updated":"2017-02-02 23:53:41.000000000","message":"If using **kwargs to ignore unused kwargs is distasteful to you (it is not to me) I would suggest we just fix the call site to pull apart part_info and pass in the only the keys we mean too here so that adding additional keys to part_info in the future doesn\u0027t require updating the signature of _get_part_jobs.","commit_id":"53e8f1386d8300b8fec3a52332866ed290e23460"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"311ac3a192a54fa16becfd07a4763f7b697600ae","unresolved":false,"context_lines":[{"line_number":967,"context_line":"                            partition)):"},{"line_number":968,"context_line":"                        self.logger.debug(\u0027Skipping %s job for %s \u0027"},{"line_number":969,"context_line":"                                          \u0027while in handoffs_only mode.\u0027,"},{"line_number":970,"context_line":"                                          SYNC, part_path)"},{"line_number":971,"context_line":"                        continue"},{"line_number":972,"context_line":"                    part_info \u003d {"},{"line_number":973,"context_line":"                        \u0027local_dev\u0027: local_dev,"}],"source_content_type":"text/x-python","patch_set":7,"id":"3f1d235d_696546e1","line":970,"updated":"2017-07-10 13:59:19.000000000","message":"(note to self) I think it is possible that after multiple rebalances we could have primary nodes with misplaced frags (used to be primary for frag N but is now primary for frag M). They will still get moved once handoffs_only has been completed. This change accelerates the common case that after rebalance a part needs to move from *handoff* to new primary.","commit_id":"44c63c69909e532e383017e7c900e4b7d13e0165"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"f7054c4bb1f795062511f47eff8cd23d950c78c3","unresolved":false,"context_lines":[{"line_number":967,"context_line":"                            partition)):"},{"line_number":968,"context_line":"                        self.logger.debug(\u0027Skipping %s job for %s \u0027"},{"line_number":969,"context_line":"                                          \u0027while in handoffs_only mode.\u0027,"},{"line_number":970,"context_line":"                                          SYNC, part_path)"},{"line_number":971,"context_line":"                        continue"},{"line_number":972,"context_line":"                    part_info \u003d {"},{"line_number":973,"context_line":"                        \u0027local_dev\u0027: local_dev,"}],"source_content_type":"text/x-python","patch_set":7,"id":"3f1d235d_f334a3fd","line":970,"updated":"2017-07-11 01:51:41.000000000","message":"In the last night, I was concerning about the misplaced fragment in a primary node and it looks my thought (this change affects to prevent the misplace fragment get moved in handoff_only mode) was correct.\n\nAnd the summary looks like it\u0027s acceptable??\nHmm... not sure but it looks the performance gain obviously will be nice to have. So... maybe add small docs here for that case?","commit_id":"44c63c69909e532e383017e7c900e4b7d13e0165"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"3e6bde7edb761045483c042575fda470b628a2a9","unresolved":false,"context_lines":[{"line_number":967,"context_line":"                            partition)):"},{"line_number":968,"context_line":"                        self.logger.debug(\u0027Skipping %s job for %s \u0027"},{"line_number":969,"context_line":"                                          \u0027while in handoffs_only mode.\u0027,"},{"line_number":970,"context_line":"                                          SYNC, part_path)"},{"line_number":971,"context_line":"                        continue"},{"line_number":972,"context_line":"                    part_info \u003d {"},{"line_number":973,"context_line":"                        \u0027local_dev\u0027: local_dev,"}],"source_content_type":"text/x-python","patch_set":7,"id":"3f1d235d_e77053df","line":970,"in_reply_to":"3f1d235d_479a67c5","updated":"2017-07-10 17:04:33.000000000","message":"@Tim yes agree it is unlikely, and less likely if handoffs_only mode is achieving its goal. Maybe if a handoff  node became a primary then we might see what was a handoff frag become \"obscured\" by what is now a primary.","commit_id":"44c63c69909e532e383017e7c900e4b7d13e0165"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"cb439b06d7d56f1f9429457d55753908880f6d0c","unresolved":false,"context_lines":[{"line_number":967,"context_line":"                            partition)):"},{"line_number":968,"context_line":"                        self.logger.debug(\u0027Skipping %s job for %s \u0027"},{"line_number":969,"context_line":"                                          \u0027while in handoffs_only mode.\u0027,"},{"line_number":970,"context_line":"                                          SYNC, part_path)"},{"line_number":971,"context_line":"                        continue"},{"line_number":972,"context_line":"                    part_info \u003d {"},{"line_number":973,"context_line":"                        \u0027local_dev\u0027: local_dev,"}],"source_content_type":"text/x-python","patch_set":7,"id":"3f1d235d_479a67c5","line":970,"in_reply_to":"3f1d235d_696546e1","updated":"2017-07-10 16:43:58.000000000","message":"I\u0027m not actually sure this *will* happen -- at the very least, I feel like it shouldn\u0027t happen much. Partitions inherently have some inertia: they only move if they *need* to, for either balance or dispersion. If it makes sense to move frag M *to* a dev, why\u0027d we ever move frag N *off* it? Sure, that *could* happen in the face some particular sequence of failures near the steady-state, but\n\n* the probability should drop off pretty quickly for #devices \u003e\u003e #frags and\n* there should always be at least one cycle (and more likely, several) where that frag would get picked up in handoffs_only mode.\n\nWe shouldn\u0027t be going around just swapping partitions; if we do, I\u0027d probably consider that a bug in the rebalance code, rather than the reconstructor. (Although fragment duplication somewhat complicates the picture...)","commit_id":"44c63c69909e532e383017e7c900e4b7d13e0165"}],"test/unit/obj/test_reconstructor.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"bc7daa92e7758c6881b52f9b172a696399bc6c36","unresolved":false,"context_lines":[{"line_number":764,"context_line":"            built_jobs.append((part_info, jobs))"},{"line_number":765,"context_line":"            return jobs"},{"line_number":766,"context_line":""},{"line_number":767,"context_line":"        with mock.patch(\u0027swift.obj.reconstructor.random.shuffle\u0027,"},{"line_number":768,"context_line":"                        lambda x: x.sort(reverse\u003dTrue)), mock.patch.object("},{"line_number":769,"context_line":"                            self.reconstructor, \u0027build_reconstruction_jobs\u0027,"},{"line_number":770,"context_line":"                            capture_jobs):"}],"source_content_type":"text/x-python","patch_set":6,"id":"bf091321_61d6ac52","line":767,"range":{"start_line":767,"start_character":49,"end_line":767,"end_character":63},"updated":"2017-06-07 21:10:50.000000000","message":"Is that actually necessary? I can\u0027t see why.","commit_id":"e4e37590ee66328deaf6baccb9e537967dd19290"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"bc7daa92e7758c6881b52f9b172a696399bc6c36","unresolved":false,"context_lines":[{"line_number":1041,"context_line":"        ]))"},{"line_number":1042,"context_line":""},{"line_number":1043,"context_line":"        # failed jobs don\u0027t sync suffixes"},{"line_number":1044,"context_line":"        self.assertEqual(0, len(request_log.requests))"},{"line_number":1045,"context_line":"        self.assertFalse("},{"line_number":1046,"context_line":"            self.reconstructor.logger.get_lines_for_level(\u0027error\u0027))"},{"line_number":1047,"context_line":"        # handoffs remaining and part exists"}],"source_content_type":"text/x-python","patch_set":6,"id":"bf091321_810420c8","line":1044,"updated":"2017-06-07 21:10:50.000000000","message":"We don\u0027t already cover this with the\n\n self.assertFalse(request_log.unexpected_requests)\n\nabove?","commit_id":"e4e37590ee66328deaf6baccb9e537967dd19290"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"bc7daa92e7758c6881b52f9b172a696399bc6c36","unresolved":false,"context_lines":[{"line_number":1077,"context_line":"            self.reconstructor.logger.get_lines_for_level(\u0027error\u0027))"},{"line_number":1078,"context_line":"        # handoffs are cleaned up"},{"line_number":1079,"context_line":"        self.assertEqual(0, self.reconstructor.handoffs_remaining)"},{"line_number":1080,"context_line":"        warning_msgs \u003d self.reconstructor.logger.get_lines_for_level(\u0027warning\u0027)"},{"line_number":1081,"context_line":"        self.assertEqual(1, len(warning_msgs))"},{"line_number":1082,"context_line":"        self.assertIn(\u0027no handoffs remaining\u0027, warning_msgs[0])"},{"line_number":1083,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"bf091321_a11de4be","line":1080,"updated":"2017-06-07 21:10:50.000000000","message":"Should we have a similar warning check above? If the first attempt emitted a warning, I feel like we\u0027d have a very non-obvious failure here...","commit_id":"e4e37590ee66328deaf6baccb9e537967dd19290"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"311ac3a192a54fa16becfd07a4763f7b697600ae","unresolved":false,"context_lines":[{"line_number":1003,"context_line":"        with mock.patch(\u0027swift.obj.reconstructor.ssync_sender\u0027,"},{"line_number":1004,"context_line":"                        self._make_fake_ssync("},{"line_number":1005,"context_line":"                            captured_ssync, fail_jobs\u003dfail_jobs)), \\"},{"line_number":1006,"context_line":"                mocked_http_conn(*[200, 200],"},{"line_number":1007,"context_line":"                                 body\u003dpickle.dumps({})) as request_log:"},{"line_number":1008,"context_line":"            self.reconstructor.reconstruct()"},{"line_number":1009,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"3f1d235d_8a5091d6","side":"PARENT","line":1006,"range":{"start_line":1006,"start_character":34,"end_line":1006,"end_character":44},"updated":"2017-07-10 13:59:19.000000000","message":"yep, not needed because ssync is faked and we don\u0027t expect and REPLICATE\u0027s before a revert job, and these jobs fail so no REPLICATE after either","commit_id":"8d6eb3677958245d71682d83ac621ac3fe6d00a0"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"311ac3a192a54fa16becfd07a4763f7b697600ae","unresolved":false,"context_lines":[{"line_number":1013,"context_line":"            # device, part, frag_index"},{"line_number":1014,"context_line":"            (\u0027sda1\u0027, 2, 2),"},{"line_number":1015,"context_line":"            (\u0027sda1\u0027, 2, 0),"},{"line_number":1016,"context_line":"            (\u0027sda1\u0027, 0, 2),"},{"line_number":1017,"context_line":"            (\u0027sda1\u0027, 1, 1),"},{"line_number":1018,"context_line":"        ])"},{"line_number":1019,"context_line":"        self.assertEqual(expected_ssync_calls, set(["},{"line_number":1020,"context_line":"            (context[\u0027job\u0027][\u0027device\u0027],"}],"source_content_type":"text/x-python","patch_set":7,"id":"3f1d235d_0a13610f","side":"PARENT","line":1017,"range":{"start_line":1016,"start_character":12,"end_line":1017,"end_character":26},"updated":"2017-07-10 13:59:19.000000000","message":"these are misplaced frags on primary nodes. with the change these revert jobs are no longer included in handoffs only mode.","commit_id":"8d6eb3677958245d71682d83ac621ac3fe6d00a0"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"311ac3a192a54fa16becfd07a4763f7b697600ae","unresolved":false,"context_lines":[{"line_number":774,"context_line":"        self.assertEqual(["},{"line_number":775,"context_line":"            # partition, job_types"},{"line_number":776,"context_line":"            (2, {\u0027sync_revert\u0027}),"},{"line_number":777,"context_line":"        ], found)"},{"line_number":778,"context_line":"        self.assertEqual(found_job_types, {object_reconstructor.REVERT})"},{"line_number":779,"context_line":"        # but failures keep handoffs remaining"},{"line_number":780,"context_line":"        msgs \u003d self.reconstructor.logger.get_lines_for_level(\u0027info\u0027)"}],"source_content_type":"text/x-python","patch_set":7,"id":"3f1d235d_2d13d768","line":777,"updated":"2017-07-10 13:59:19.000000000","message":"with master:\n\n  Failure\nTraceback (most recent call last):\n  File \"/Users/anc/0dev/swift/test/unit/obj/test_reconstructor.py\", line 777, in test_handoffs_only\n    ], found)\nAssertionError: Lists differ: [(2, set([\u0027sync_revert\u0027]))] !\u003d [(1, set([\u0027sync_only\u0027, \u0027sync_r...\n\nFirst differing element 0:\n(2, set([\u0027sync_revert\u0027]))\n(1, set([\u0027sync_only\u0027, \u0027sync_revert\u0027]))\n\nSecond list contains 2 additional elements.\nFirst extra element 1:\n(0, set([\u0027sync_only\u0027, \u0027sync_revert\u0027]))\n\n+ [(1, set([\u0027sync_only\u0027, \u0027sync_revert\u0027])),\n+  (0, set([\u0027sync_only\u0027, \u0027sync_revert\u0027])),\n- [(2, set([\u0027sync_revert\u0027]))]\n? ^\n\n+  (2, set([\u0027sync_revert\u0027]))]\n? ^","commit_id":"44c63c69909e532e383017e7c900e4b7d13e0165"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"311ac3a192a54fa16becfd07a4763f7b697600ae","unresolved":false,"context_lines":[{"line_number":1022,"context_line":"                            captured_ssync, fail_jobs\u003dfail_jobs)), \\"},{"line_number":1023,"context_line":"                mocked_http_conn() as request_log:"},{"line_number":1024,"context_line":"            self.reconstructor.reconstruct()"},{"line_number":1025,"context_line":"        self.assertFalse(request_log.unexpected_requests)"},{"line_number":1026,"context_line":""},{"line_number":1027,"context_line":"        # global setup has two handoff parts"},{"line_number":1028,"context_line":"        self.assertEqual(len(captured_ssync), 2)"}],"source_content_type":"text/x-python","patch_set":7,"id":"3f1d235d_ad06c71f","line":1025,"updated":"2017-07-10 13:59:19.000000000","message":"with master:\n\nFailure\nTraceback (most recent call last):\n  File \"/Users/anc/0dev/swift/test/unit/obj/test_reconstructor.py\", line 1025, in test_no_delete_failed_revert\n    self.assertFalse(request_log.unexpected_requests)\nAssertionError: [((\u0027127.0.0.2\u0027, 6200, \u0027REPLICATE\u0027, \u0027/sda1/1/061-3c1\u0027, {\u0027Content-Length\u0027: \u00270\u0027, \u0027X-Backend-Storage-Policy-Index\u0027: 1, \u0027user-agent\u0027: \u0027obj-reconstructor 65380\u0027}, None, False), {\u0027give_connect\u0027: \u003cfunction capture_requests at 0x10fc2bcf8\u003e}), ((\u0027127.0.0.2\u0027, 6200, \u0027REPLICATE\u0027, \u0027/sda1/0/061\u0027, {\u0027Content-Length\u0027: \u00270\u0027, \u0027X-Backend-Storage-Policy-Index\u0027: 1, \u0027user-agent\u0027: \u0027obj-reconstructor 65380\u0027}, None, False), {\u0027give_connect\u0027: \u003cfunction capture_requests at 0x10fc2bcf8\u003e})] is not false","commit_id":"44c63c69909e532e383017e7c900e4b7d13e0165"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"311ac3a192a54fa16becfd07a4763f7b697600ae","unresolved":false,"context_lines":[{"line_number":1052,"context_line":"        with mock.patch(\u0027swift.obj.reconstructor.ssync_sender\u0027,"},{"line_number":1053,"context_line":"                        self._make_fake_ssync(captured_ssync)), \\"},{"line_number":1054,"context_line":"                mocked_http_conn("},{"line_number":1055,"context_line":"                    200, 200, body\u003dpickle.dumps({})) as request_log:"},{"line_number":1056,"context_line":"            self.reconstructor.reconstruct()"},{"line_number":1057,"context_line":"        self.assertFalse(request_log.unexpected_requests)"},{"line_number":1058,"context_line":"        # same jobs"}],"source_content_type":"text/x-python","patch_set":7,"id":"3f1d235d_4df4d35b","line":1055,"range":{"start_line":1055,"start_character":20,"end_line":1055,"end_character":33},"updated":"2017-07-10 13:59:19.000000000","message":"ok. these are the remote_rehash REPLICATE requests after revert succeeds","commit_id":"44c63c69909e532e383017e7c900e4b7d13e0165"}]}
