)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"dc9ab3e91f9bec682d1b4a53206f8b247b5d0a27","unresolved":false,"context_lines":[{"line_number":20,"context_line":"expirer, container replicator, container server, account replicator,"},{"line_number":21,"context_line":"account server, and account reaper, \"concurrency\" refers to the number"},{"line_number":22,"context_line":"of concurrent tasks performed within one process (for reference, the"},{"line_number":23,"context_line":"container updater and object auditor use \"concurrency\" to mean number"},{"line_number":24,"context_line":"of processes)."},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"On upgrade, each node will still handle async updates N-at-a-time, but"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"5f7c97a3_48570b28","line":23,"range":{"start_line":23,"start_character":0,"end_line":23,"end_character":36},"updated":"2018-06-05 11:34:51.000000000","message":"so we get consistency with most other daemons, but not between the updaters, which is unfortunate.\n\nIf we\u0027re going to change the meaning of concurrency in the object updater, might it be worth considering adding *_workers as an alias to the other two daemons? That way an op could migrate all daemons to the new consistent option naming in one change event.","commit_id":"5082acf8189fa6d2ed6823868b985152e12f8bbe"},{"author":{"_account_id":2622,"name":"Samuel Merritt","email":"spam+launchpad@andcheese.org","username":"torgomatic"},"change_message_id":"8d53a3d5fc53e008256118357887e420cddb83e7","unresolved":false,"context_lines":[{"line_number":20,"context_line":"expirer, container replicator, container server, account replicator,"},{"line_number":21,"context_line":"account server, and account reaper, \"concurrency\" refers to the number"},{"line_number":22,"context_line":"of concurrent tasks performed within one process (for reference, the"},{"line_number":23,"context_line":"container updater and object auditor use \"concurrency\" to mean number"},{"line_number":24,"context_line":"of processes)."},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"On upgrade, each node will still handle async updates N-at-a-time, but"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"5f7c97a3_f078342c","line":23,"range":{"start_line":23,"start_character":0,"end_line":23,"end_character":36},"in_reply_to":"5f7c97a3_48570b28","updated":"2018-06-05 20:22:14.000000000","message":"I think it\u0027s worth doing, though perhaps in a separate patch.","commit_id":"5082acf8189fa6d2ed6823868b985152e12f8bbe"},{"author":{"_account_id":2622,"name":"Samuel Merritt","email":"spam+launchpad@andcheese.org","username":"torgomatic"},"change_message_id":"ee1640bd300eaf2d9aa2d606b95de969ea5ca44a","unresolved":false,"context_lines":[{"line_number":20,"context_line":"expirer, container replicator, container server, account replicator,"},{"line_number":21,"context_line":"account server, and account reaper, \"concurrency\" refers to the number"},{"line_number":22,"context_line":"of concurrent tasks performed within one process (for reference, the"},{"line_number":23,"context_line":"container updater and object auditor use \"concurrency\" to mean number"},{"line_number":24,"context_line":"of processes)."},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"On upgrade, each node will still handle async updates N-at-a-time, but"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"5f7c97a3_d61c1015","line":23,"range":{"start_line":23,"start_character":0,"end_line":23,"end_character":36},"in_reply_to":"5f7c97a3_f078342c","updated":"2018-06-05 22:02:33.000000000","message":"object auditor: https://review.openstack.org/572571","commit_id":"5082acf8189fa6d2ed6823868b985152e12f8bbe"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"dc9ab3e91f9bec682d1b4a53206f8b247b5d0a27","unresolved":false,"context_lines":[{"line_number":23,"context_line":"container updater and object auditor use \"concurrency\" to mean number"},{"line_number":24,"context_line":"of processes)."},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"On upgrade, each node will still handle async updates N-at-a-time, but"},{"line_number":27,"context_line":"will do so using only one process instead of N."},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"Change-Id: I17e18088e61f664e1b9942d66423666d0cae1689"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"5f7c97a3_48fb8b46","line":26,"range":{"start_line":26,"start_character":0,"end_line":26,"end_character":10},"updated":"2018-06-05 11:34:51.000000000","message":"In the past we\u0027ve uses the UpgradeImpact tag to draw attention to this kind of change. If someone were monitoring their updater processes they might be surprised to not see so many after upgrade.","commit_id":"5082acf8189fa6d2ed6823868b985152e12f8bbe"},{"author":{"_account_id":2622,"name":"Samuel Merritt","email":"spam+launchpad@andcheese.org","username":"torgomatic"},"change_message_id":"8d53a3d5fc53e008256118357887e420cddb83e7","unresolved":false,"context_lines":[{"line_number":23,"context_line":"container updater and object auditor use \"concurrency\" to mean number"},{"line_number":24,"context_line":"of processes)."},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"On upgrade, each node will still handle async updates N-at-a-time, but"},{"line_number":27,"context_line":"will do so using only one process instead of N."},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"Change-Id: I17e18088e61f664e1b9942d66423666d0cae1689"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"5f7c97a3_90754035","line":26,"range":{"start_line":26,"start_character":0,"end_line":26,"end_character":10},"in_reply_to":"5f7c97a3_48fb8b46","updated":"2018-06-05 20:22:14.000000000","message":"Done","commit_id":"5082acf8189fa6d2ed6823868b985152e12f8bbe"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"5f243e23d3672d936dcea1f3cf1fb1b48388d1aa","unresolved":false,"context_lines":[{"line_number":24,"context_line":"of processes)."},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"On upgrade, each node will still handle async updates N-at-a-time, but"},{"line_number":27,"context_line":"will do so using only one process instead of N."},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"Change-Id: I17e18088e61f664e1b9942d66423666d0cae1689"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"5f7c97a3_bb171455","line":27,"updated":"2018-06-05 04:55:23.000000000","message":"I think the trade off here is good?  the semantics of the new name make way more sense (with other daemons doing workers) and everything still \"works\" after the upgrade even w/o a config change.","commit_id":"5082acf8189fa6d2ed6823868b985152e12f8bbe"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4a4fe5484d2cb08d952d7aeddaf712a0a540cbfb","unresolved":false,"context_lines":[{"line_number":27,"context_line":"async updates N-at-a-time, but will do so using only one process"},{"line_number":28,"context_line":"instead of N."},{"line_number":29,"context_line":""},{"line_number":30,"context_line":"UpgradeImpact"},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"Change-Id: I17e18088e61f664e1b9942d66423666d0cae1689"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":4,"id":"5f7c97a3_e4c51b5d","line":30,"range":{"start_line":30,"start_character":0,"end_line":30,"end_character":13},"updated":"2018-06-13 23:52:03.000000000","message":"I feel like this should carry a specific call to action, similar to ones I\u0027ve written in the past [1][2][3] -- maybe a recommendation to update concurrency on old nodes to min(desired final concurrency, updater_workers) before upgrading so operators don\u0027t go around hammering their disks needlessly?\n\n[1] https://github.com/openstack/swift/commit/94bac4a\n[2] https://github.com/openstack/swift/commit/2c3ac54\n[3] https://github.com/openstack/swift/commit/f850ff0","commit_id":"a2cc07f57bc58ea0777ebad9d4168658f2c5a465"}],"doc/source/deployment_guide.rst":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c4032393a422e2f2f6ae2497a2942b8bc1ad258e","unresolved":false,"context_lines":[{"line_number":910,"context_line":"log_address         /dev/log            Logging directory"},{"line_number":911,"context_line":"interval            300                 Minimum time for a pass to take"},{"line_number":912,"context_line":"updater_workers     1                   Number of worker processes"},{"line_number":913,"context_line":"concurrency         1                   Number of updates to run concurrently in"},{"line_number":914,"context_line":"                                        each worker process"},{"line_number":915,"context_line":"node_timeout        DEFAULT or 10       Request timeout to external services. This"},{"line_number":916,"context_line":"                                        uses what\u0027s set here, or what\u0027s set in the"}],"source_content_type":"text/x-rst","patch_set":2,"id":"5f7c97a3_f199d1cf","line":913,"range":{"start_line":913,"start_character":20,"end_line":913,"end_character":21},"updated":"2018-06-08 11:46:56.000000000","message":"128","commit_id":"4be8cae7ca18c6482564c629eb627f969ea6009d"},{"author":{"_account_id":2622,"name":"Samuel Merritt","email":"spam+launchpad@andcheese.org","username":"torgomatic"},"change_message_id":"0c177c14a0d913d9ef9ac6ad6ca72674fb3a2085","unresolved":false,"context_lines":[{"line_number":910,"context_line":"log_address         /dev/log            Logging directory"},{"line_number":911,"context_line":"interval            300                 Minimum time for a pass to take"},{"line_number":912,"context_line":"updater_workers     1                   Number of worker processes"},{"line_number":913,"context_line":"concurrency         1                   Number of updates to run concurrently in"},{"line_number":914,"context_line":"                                        each worker process"},{"line_number":915,"context_line":"node_timeout        DEFAULT or 10       Request timeout to external services. This"},{"line_number":916,"context_line":"                                        uses what\u0027s set here, or what\u0027s set in the"}],"source_content_type":"text/x-rst","patch_set":2,"id":"5f7c97a3_d42d9a46","line":913,"range":{"start_line":913,"start_character":20,"end_line":913,"end_character":21},"in_reply_to":"5f7c97a3_f199d1cf","updated":"2018-06-08 18:25:18.000000000","message":"Done","commit_id":"4be8cae7ca18c6482564c629eb627f969ea6009d"}],"etc/object-server.conf-sample":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"dc9ab3e91f9bec682d1b4a53206f8b247b5d0a27","unresolved":false,"context_lines":[{"line_number":373,"context_line":"# interval \u003d 300"},{"line_number":374,"context_line":"# node_timeout \u003d \u003cwhatever\u0027s in the DEFAULT section or 10\u003e"},{"line_number":375,"context_line":"#"},{"line_number":376,"context_line":"# updater_workers controls how many processes the object updater will"},{"line_number":377,"context_line":"# spawn, while concurrency controls how many async_pending records"},{"line_number":378,"context_line":"# each updater process will operate on at any one time. With"},{"line_number":379,"context_line":"# concurrency\u003dC and updater_workers\u003dW, there will be up to W*C"},{"line_number":380,"context_line":"# async_pending records being processed at once."},{"line_number":381,"context_line":"# concurrency \u003d 1"},{"line_number":382,"context_line":"# updater_workers \u003d 128"},{"line_number":383,"context_line":"#"},{"line_number":384,"context_line":"# Send at most this many object updates per second"},{"line_number":385,"context_line":"# objects_per_second \u003d 50"}],"source_content_type":"application/octet-stream","patch_set":1,"id":"5f7c97a3_48b62b41","line":382,"range":{"start_line":376,"start_character":2,"end_line":382,"end_character":23},"updated":"2018-06-05 11:34:51.000000000","message":"the deployment guide also needs to be updated. Fortunately (?) the man page does not enumerate all the options so there\u0027s no change required there, unless you were to fix the lack of triplication ;)","commit_id":"5082acf8189fa6d2ed6823868b985152e12f8bbe"},{"author":{"_account_id":2622,"name":"Samuel Merritt","email":"spam+launchpad@andcheese.org","username":"torgomatic"},"change_message_id":"8d53a3d5fc53e008256118357887e420cddb83e7","unresolved":false,"context_lines":[{"line_number":373,"context_line":"# interval \u003d 300"},{"line_number":374,"context_line":"# node_timeout \u003d \u003cwhatever\u0027s in the DEFAULT section or 10\u003e"},{"line_number":375,"context_line":"#"},{"line_number":376,"context_line":"# updater_workers controls how many processes the object updater will"},{"line_number":377,"context_line":"# spawn, while concurrency controls how many async_pending records"},{"line_number":378,"context_line":"# each updater process will operate on at any one time. With"},{"line_number":379,"context_line":"# concurrency\u003dC and updater_workers\u003dW, there will be up to W*C"},{"line_number":380,"context_line":"# async_pending records being processed at once."},{"line_number":381,"context_line":"# concurrency \u003d 1"},{"line_number":382,"context_line":"# updater_workers \u003d 128"},{"line_number":383,"context_line":"#"},{"line_number":384,"context_line":"# Send at most this many object updates per second"},{"line_number":385,"context_line":"# objects_per_second \u003d 50"}],"source_content_type":"application/octet-stream","patch_set":1,"id":"5f7c97a3_30878c12","line":382,"range":{"start_line":376,"start_character":2,"end_line":382,"end_character":23},"in_reply_to":"5f7c97a3_48b62b41","updated":"2018-06-05 20:22:14.000000000","message":"Done","commit_id":"5082acf8189fa6d2ed6823868b985152e12f8bbe"}],"swift/obj/updater.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"5f243e23d3672d936dcea1f3cf1fb1b48388d1aa","unresolved":false,"context_lines":[{"line_number":151,"context_line":"                    self.logger.warning("},{"line_number":152,"context_line":"                        _(\u0027Skipping %s as it is not mounted\u0027), device)"},{"line_number":153,"context_line":"                    continue"},{"line_number":154,"context_line":"                while len(pids) \u003e\u003d self.updater_workers:"},{"line_number":155,"context_line":"                    pids.remove(os.wait()[0])"},{"line_number":156,"context_line":"                pid \u003d os.fork()"},{"line_number":157,"context_line":"                if pid:"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_3b5d4448","line":154,"updated":"2018-06-05 04:55:23.000000000","message":"so if folks have concurrency set to something low like 4, after they upgrade and restart instead of four workers they get 1 worker...","commit_id":"5082acf8189fa6d2ed6823868b985152e12f8bbe"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"5f243e23d3672d936dcea1f3cf1fb1b48388d1aa","unresolved":false,"context_lines":[{"line_number":291,"context_line":"        ap_iter \u003d RateLimitedIterator("},{"line_number":292,"context_line":"            self._iter_async_pendings(device),"},{"line_number":293,"context_line":"            elements_per_second\u003dself.max_objects_per_second)"},{"line_number":294,"context_line":"        with ContextPool(self.concurrency) as pool:"},{"line_number":295,"context_line":"            for update in ap_iter:"},{"line_number":296,"context_line":"                pool.spawn(self.process_object_update,"},{"line_number":297,"context_line":"                           update[\u0027path\u0027], update[\u0027device\u0027], update[\u0027policy\u0027])"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_7b389ced","line":294,"updated":"2018-06-05 04:55:23.000000000","message":"but all the updates on each device will be processed 128 at a time!","commit_id":"5082acf8189fa6d2ed6823868b985152e12f8bbe"},{"author":{"_account_id":2622,"name":"Samuel Merritt","email":"spam+launchpad@andcheese.org","username":"torgomatic"},"change_message_id":"8d53a3d5fc53e008256118357887e420cddb83e7","unresolved":false,"context_lines":[{"line_number":291,"context_line":"        ap_iter \u003d RateLimitedIterator("},{"line_number":292,"context_line":"            self._iter_async_pendings(device),"},{"line_number":293,"context_line":"            elements_per_second\u003dself.max_objects_per_second)"},{"line_number":294,"context_line":"        with ContextPool(self.concurrency) as pool:"},{"line_number":295,"context_line":"            for update in ap_iter:"},{"line_number":296,"context_line":"                pool.spawn(self.process_object_update,"},{"line_number":297,"context_line":"                           update[\u0027path\u0027], update[\u0027device\u0027], update[\u0027policy\u0027])"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_c76780ea","line":294,"in_reply_to":"5f7c97a3_7b389ced","updated":"2018-06-05 20:22:14.000000000","message":"4 at a time, since they\u0027ve set concurrency\u003d4 in the config. So, same as before, but not so well-spread across disks.","commit_id":"5082acf8189fa6d2ed6823868b985152e12f8bbe"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"dc9ab3e91f9bec682d1b4a53206f8b247b5d0a27","unresolved":false,"context_lines":[{"line_number":297,"context_line":"                           update[\u0027path\u0027], update[\u0027device\u0027], update[\u0027policy\u0027])"},{"line_number":298,"context_line":"                now \u003d time.time()"},{"line_number":299,"context_line":"                if now - last_status_update \u003e\u003d self.report_interval:"},{"line_number":300,"context_line":"                    this_sweep \u003d self.stats.since(start_stats)"},{"line_number":301,"context_line":"                    self.logger.info("},{"line_number":302,"context_line":"                        (\u0027Object update sweep progress on %(device)s: \u0027"},{"line_number":303,"context_line":"                         \u0027%(elapsed).02fs, %(stats)s (pid: %(pid)d)\u0027),"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_c881dbfd","line":300,"range":{"start_line":300,"start_character":33,"end_line":300,"end_character":43},"updated":"2018-06-05 11:34:51.000000000","message":"with stats now being updated in threads, they may not be self-consistent when reported in this thread","commit_id":"5082acf8189fa6d2ed6823868b985152e12f8bbe"},{"author":{"_account_id":2622,"name":"Samuel Merritt","email":"spam+launchpad@andcheese.org","username":"torgomatic"},"change_message_id":"8d53a3d5fc53e008256118357887e420cddb83e7","unresolved":false,"context_lines":[{"line_number":297,"context_line":"                           update[\u0027path\u0027], update[\u0027device\u0027], update[\u0027policy\u0027])"},{"line_number":298,"context_line":"                now \u003d time.time()"},{"line_number":299,"context_line":"                if now - last_status_update \u003e\u003d self.report_interval:"},{"line_number":300,"context_line":"                    this_sweep \u003d self.stats.since(start_stats)"},{"line_number":301,"context_line":"                    self.logger.info("},{"line_number":302,"context_line":"                        (\u0027Object update sweep progress on %(device)s: \u0027"},{"line_number":303,"context_line":"                         \u0027%(elapsed).02fs, %(stats)s (pid: %(pid)d)\u0027),"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_909c606b","line":300,"range":{"start_line":300,"start_character":33,"end_line":300,"end_character":43},"in_reply_to":"5f7c97a3_c881dbfd","updated":"2018-06-05 20:22:14.000000000","message":"They may not be consistent with what\u0027s been dispatched, but they\u0027ll be consistent with what\u0027s been done.\n\nAFAICT, all our stats are independent. That is, there\u0027s no place where we call self.stats.X +\u003d 1 and then self.stats.Y +\u003d 1 but the stats don\u0027t make sense if you peek at them between those two calls.\n\nThe final stats report is after calling pool.waitall(), so that one\u0027s going to report on everything.","commit_id":"5082acf8189fa6d2ed6823868b985152e12f8bbe"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c4032393a422e2f2f6ae2497a2942b8bc1ad258e","unresolved":false,"context_lines":[{"line_number":246,"context_line":"                              \u0027name %s\u0027)"},{"line_number":247,"context_line":"                            % (update_path))"},{"line_number":248,"context_line":"                        continue"},{"line_number":249,"context_line":"                    # Async pendings are stored on disk like this:"},{"line_number":250,"context_line":"                    #"},{"line_number":251,"context_line":"                    # \u003cdevice\u003e/async_pending/\u003csuffix\u003e/\u003cobj_hash\u003e-\u003ctimestamp\u003e"},{"line_number":252,"context_line":"                    #"},{"line_number":253,"context_line":"                    # If there are multiple updates for a given object,"},{"line_number":254,"context_line":"                    # they\u0027ll look like this:"},{"line_number":255,"context_line":"                    #"},{"line_number":256,"context_line":"                    # \u003cdevice\u003e/async_pending/\u003cobj_suffix\u003e/\u003cobj_hash\u003e-\u003ctimestamp1\u003e"},{"line_number":257,"context_line":"                    # \u003cdevice\u003e/async_pending/\u003cobj_suffix\u003e/\u003cobj_hash\u003e-\u003ctimestamp2\u003e"},{"line_number":258,"context_line":"                    # \u003cdevice\u003e/async_pending/\u003cobj_suffix\u003e/\u003cobj_hash\u003e-\u003ctimestamp3\u003e"},{"line_number":259,"context_line":"                    #"},{"line_number":260,"context_line":"                    # Async updates also have the property that newer"},{"line_number":261,"context_line":"                    # updates contain all the information in older updates."},{"line_number":262,"context_line":"                    # Since we sorted the directory listing in reverse"},{"line_number":263,"context_line":"                    # order, we\u0027ll see timestamp3 first, yield it, and then"},{"line_number":264,"context_line":"                    # unlink timestamp2 and timestamp1 since we know they"},{"line_number":265,"context_line":"                    # are obsolete."},{"line_number":266,"context_line":"                    #"},{"line_number":267,"context_line":"                    # This way, our caller only gets useful async_pendings."},{"line_number":268,"context_line":"                    if obj_hash \u003d\u003d last_obj_hash:"},{"line_number":269,"context_line":"                        self.stats.unlinks +\u003d 1"},{"line_number":270,"context_line":"                        self.logger.increment(\u0027unlinks\u0027)"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_2ce5ac38","line":267,"range":{"start_line":249,"start_character":21,"end_line":267,"end_character":75},"updated":"2018-06-08 11:46:56.000000000","message":"+1 very helpful","commit_id":"4be8cae7ca18c6482564c629eb627f969ea6009d"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4a4fe5484d2cb08d952d7aeddaf712a0a540cbfb","unresolved":false,"context_lines":[{"line_number":257,"context_line":"                    # \u003cdevice\u003e/async_pending/\u003cobj_suffix\u003e/\u003cobj_hash\u003e-\u003ctimestamp2\u003e"},{"line_number":258,"context_line":"                    # \u003cdevice\u003e/async_pending/\u003cobj_suffix\u003e/\u003cobj_hash\u003e-\u003ctimestamp3\u003e"},{"line_number":259,"context_line":"                    #"},{"line_number":260,"context_line":"                    # Async updates also have the property that newer"},{"line_number":261,"context_line":"                    # updates contain all the information in older updates."},{"line_number":262,"context_line":"                    # Since we sorted the directory listing in reverse"},{"line_number":263,"context_line":"                    # order, we\u0027ll see timestamp3 first, yield it, and then"},{"line_number":264,"context_line":"                    # unlink timestamp2 and timestamp1 since we know they"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_a92e1c40","line":261,"range":{"start_line":260,"start_character":22,"end_line":261,"end_character":75},"updated":"2018-06-13 23:52:03.000000000","message":"I *was* going to worry about confirming this, but then I noticed that we just preserve existing behavior from object_sweep.","commit_id":"a2cc07f57bc58ea0777ebad9d4168658f2c5a465"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4a4fe5484d2cb08d952d7aeddaf712a0a540cbfb","unresolved":false,"context_lines":[{"line_number":268,"context_line":"                    if obj_hash \u003d\u003d last_obj_hash:"},{"line_number":269,"context_line":"                        self.stats.unlinks +\u003d 1"},{"line_number":270,"context_line":"                        self.logger.increment(\u0027unlinks\u0027)"},{"line_number":271,"context_line":"                        os.unlink(update_path)"},{"line_number":272,"context_line":"                    else:"},{"line_number":273,"context_line":"                        last_obj_hash \u003d obj_hash"},{"line_number":274,"context_line":"                        yield {\u0027device\u0027: device, \u0027policy\u0027: policy,"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_29d0cc1e","line":271,"updated":"2018-06-13 23:52:03.000000000","message":"We could\u0027ve left this in place... but I think I like it better here.","commit_id":"a2cc07f57bc58ea0777ebad9d4168658f2c5a465"}],"test/unit/obj/test_updater.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c4032393a422e2f2f6ae2497a2942b8bc1ad258e","unresolved":false,"context_lines":[{"line_number":237,"context_line":"                self.assertTrue(os.path.exists(prefix_dir))"},{"line_number":238,"context_line":"                self.assertEqual(set(), seen)"},{"line_number":239,"context_line":"            else:"},{"line_number":240,"context_line":"                self.assertTrue(not os.path.exists(prefix_dir))"},{"line_number":241,"context_line":"                self.assertEqual(expected, seen)"},{"line_number":242,"context_line":""},{"line_number":243,"context_line":"            # test cleanup: the tempdir gets cleaned up between runs, but this"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_87385b3b","side":"PARENT","line":240,"range":{"start_line":240,"start_character":16,"end_line":240,"end_character":63},"updated":"2018-06-08 11:46:56.000000000","message":"ok. This is no longer true because the prefix_dir unlink has moved to process_object_update which this test mocks. The unlink could alternatively have been added to MockObjectUpdater, but there is still coverage of the prefix_dir unlink in for example test_run_once","commit_id":"3e9fdfceb449c0f9aabf9de6e5e3002aafe2de3b"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4a4fe5484d2cb08d952d7aeddaf712a0a540cbfb","unresolved":false,"context_lines":[{"line_number":310,"context_line":"        # lines."},{"line_number":311,"context_line":"        with mock.patch(\u0027swift.obj.updater.time\u0027,"},{"line_number":312,"context_line":"                        mock.MagicMock(time\u003dmock_time_function)), \\"},{"line_number":313,"context_line":"                mock.patch.object(object_updater, \u0027ContextPool\u0027, MockPool):"},{"line_number":314,"context_line":"            ou.object_sweep(self.sda1)"},{"line_number":315,"context_line":""},{"line_number":316,"context_line":"        info_lines \u003d logger.get_lines_for_level(\u0027info\u0027)"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_09a4f0a1","line":313,"updated":"2018-06-13 23:52:03.000000000","message":"Why? Oh, I see -- because we don\u0027t trampoline until the second spawn... Maybe better to just update the test?\n\nhttp://paste.openstack.org/show/723418/","commit_id":"a2cc07f57bc58ea0777ebad9d4168658f2c5a465"},{"author":{"_account_id":2622,"name":"Samuel Merritt","email":"spam+launchpad@andcheese.org","username":"torgomatic"},"change_message_id":"cc645512e453c32e0f963c30ad8a53181c60fe43","unresolved":false,"context_lines":[{"line_number":310,"context_line":"        # lines."},{"line_number":311,"context_line":"        with mock.patch(\u0027swift.obj.updater.time\u0027,"},{"line_number":312,"context_line":"                        mock.MagicMock(time\u003dmock_time_function)), \\"},{"line_number":313,"context_line":"                mock.patch.object(object_updater, \u0027ContextPool\u0027, MockPool):"},{"line_number":314,"context_line":"            ou.object_sweep(self.sda1)"},{"line_number":315,"context_line":""},{"line_number":316,"context_line":"        info_lines \u003d logger.get_lines_for_level(\u0027info\u0027)"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_e4c19b30","line":313,"in_reply_to":"5f7c97a3_09a4f0a1","updated":"2018-06-14 00:30:09.000000000","message":"I thought that was pretty confusing, to be honest. I started off with that, but then we write out two pending files, call object_sweep(), and then only one of them is done because of some concurrency thingy.","commit_id":"a2cc07f57bc58ea0777ebad9d4168658f2c5a465"}]}
