)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"b7f0e3b8e061e83404a86140b60364d63a058c0e","unresolved":true,"context_lines":[{"line_number":15,"context_line":""},{"line_number":16,"context_line":"  $ curl http://127.0.0.3:6030/recon/relinker |python -mjson.tool"},{"line_number":17,"context_line":"  {"},{"line_number":18,"context_line":"      \"progress\": {"},{"line_number":19,"context_line":"          \"part_power\": 8,"},{"line_number":20,"context_line":"          \"next_part_power\": 9,"},{"line_number":21,"context_line":"          \"sdb3\": {"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":24,"id":"3cb4b337_57703c38","line":18,"updated":"2021-04-14 18:21:26.000000000","message":"N.B. this isn\u0027t a top level key named progress - it only the progress for policy-0","commit_id":"5b355b34ab8c457b2f09734e3a5a6a17330932c9"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"7bdcdb4b282a182ee34e3255b184530551f59485","unresolved":true,"context_lines":[{"line_number":15,"context_line":""},{"line_number":16,"context_line":"  $ curl http://127.0.0.3:6030/recon/relinker |python -mjson.tool"},{"line_number":17,"context_line":"  {"},{"line_number":18,"context_line":"      \"progress\": {"},{"line_number":19,"context_line":"          \"part_power\": 8,"},{"line_number":20,"context_line":"          \"next_part_power\": 9,"},{"line_number":21,"context_line":"          \"sdb3\": {"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":24,"id":"eef4d720_f548f557","line":18,"in_reply_to":"3cb4b337_57703c38","updated":"2021-04-15 07:15:32.000000000","message":"yup, maybe I should add an progress-1 to the commit message to make it obvious.","commit_id":"5b355b34ab8c457b2f09734e3a5a6a17330932c9"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"b7f0e3b8e061e83404a86140b60364d63a058c0e","unresolved":true,"context_lines":[{"line_number":34,"context_line":"              \"total_time\": 3.657404899597168,"},{"line_number":35,"context_line":"              \"timestamp\": 1615426134.692052"},{"line_number":36,"context_line":"          }"},{"line_number":37,"context_line":"      }"},{"line_number":38,"context_line":"      \"start_time\": 1615426134.692052,"},{"line_number":39,"context_line":"      \"total_time\": 300.0,"},{"line_number":40,"context_line":"      \"stats\": {"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":24,"id":"615e7ac1_e8156b54","line":37,"updated":"2021-04-14 18:21:26.000000000","message":"did we explicitly decide not to attempt to aggregate parts_done across devices?\n\nI understand that \"total_parts\" would become \"discovered_parts\" in aggregate and could change more than once before the end of the run as workers pick up new devices","commit_id":"5b355b34ab8c457b2f09734e3a5a6a17330932c9"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"7bdcdb4b282a182ee34e3255b184530551f59485","unresolved":true,"context_lines":[{"line_number":34,"context_line":"              \"total_time\": 3.657404899597168,"},{"line_number":35,"context_line":"              \"timestamp\": 1615426134.692052"},{"line_number":36,"context_line":"          }"},{"line_number":37,"context_line":"      }"},{"line_number":38,"context_line":"      \"start_time\": 1615426134.692052,"},{"line_number":39,"context_line":"      \"total_time\": 300.0,"},{"line_number":40,"context_line":"      \"stats\": {"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":24,"id":"be350f31_65fcf9f9","line":37,"in_reply_to":"615e7ac1_e8156b54","updated":"2021-04-15 07:15:32.000000000","message":"Hadn\u0027t even thought of that! Not a bad idea, I\u0027ll have a play with it.","commit_id":"5b355b34ab8c457b2f09734e3a5a6a17330932c9"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"b7f0e3b8e061e83404a86140b60364d63a058c0e","unresolved":true,"context_lines":[{"line_number":46,"context_line":"              \"policies\": 1,"},{"line_number":47,"context_line":"              \"removed\": 0,"},{"line_number":48,"context_line":"              \"timestamp\": 1618293049.288847"},{"line_number":49,"context_line":"          },"},{"line_number":50,"context_line":"          \"stats_21239\": {"},{"line_number":51,"context_line":"              \"errors\": 0,"},{"line_number":52,"context_line":"              \"files\": 191,"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":24,"id":"9540821b_68d5f584","line":49,"updated":"2021-04-14 18:21:26.000000000","message":"these are aggregated across workers","commit_id":"5b355b34ab8c457b2f09734e3a5a6a17330932c9"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"b7f0e3b8e061e83404a86140b60364d63a058c0e","unresolved":true,"context_lines":[{"line_number":54,"context_line":"              \"linked\": 0,"},{"line_number":55,"context_line":"              \"policies\": 1,"},{"line_number":56,"context_line":"              \"removed\": 0,"},{"line_number":57,"context_line":"              \"timestamp\": 1618293049.092572"},{"line_number":58,"context_line":"          },"},{"line_number":59,"context_line":"          \"stats_21240\": {"},{"line_number":60,"context_line":"              \"errors\": 0,"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":24,"id":"afd33f98_5a374834","line":57,"updated":"2021-04-14 18:21:26.000000000","message":"AFAIK these are aggregated across devices and policies","commit_id":"5b355b34ab8c457b2f09734e3a5a6a17330932c9"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"7bdcdb4b282a182ee34e3255b184530551f59485","unresolved":true,"context_lines":[{"line_number":54,"context_line":"              \"linked\": 0,"},{"line_number":55,"context_line":"              \"policies\": 1,"},{"line_number":56,"context_line":"              \"removed\": 0,"},{"line_number":57,"context_line":"              \"timestamp\": 1618293049.092572"},{"line_number":58,"context_line":"          },"},{"line_number":59,"context_line":"          \"stats_21240\": {"},{"line_number":60,"context_line":"              \"errors\": 0,"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":24,"id":"194e8a7f_d3321620","line":57,"in_reply_to":"afd33f98_5a374834","updated":"2021-04-15 07:15:32.000000000","message":"Yup, they are the stats gethered over the whole process run.","commit_id":"5b355b34ab8c457b2f09734e3a5a6a17330932c9"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"72285f28b456a777ac294144368935a51eed88ce","unresolved":true,"context_lines":[{"line_number":66,"context_line":"              \"timestamp\": 1618469147.743934,"},{"line_number":67,"context_line":"              \"total_combined_time\": 6.7653608322143555"},{"line_number":68,"context_line":"          }"},{"line_number":69,"context_line":"      },"},{"line_number":70,"context_line":"      \"start_time\": 1615426134.692052,"},{"line_number":71,"context_line":"      \"total_time\": 300.0,"},{"line_number":72,"context_line":"      \"stats\": {"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":25,"id":"7f6213ff_d8c16180","line":69,"updated":"2021-04-15 07:23:49.000000000","message":"Added a progress-1 and the per policy aggregation.","commit_id":"aad814e5163dbc8843adce04d120be6b558a0124"}],"etc/object-server.conf-sample":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"fe33b948377bd711287784a49b16567708dbff35","unresolved":true,"context_lines":[{"line_number":639,"context_line":"# different inodes to be relinked to the next partition power location."},{"line_number":640,"context_line":"# link_check_limit \u003d 2"},{"line_number":641,"context_line":"#"},{"line_number":642,"context_line":"# recon_interval \u003d 10.0"},{"line_number":643,"context_line":"# recon_cache_path \u003d /var/cache/swift"}],"source_content_type":"application/octet-stream","patch_set":30,"id":"7c932a2c_9310535a","line":642,"updated":"2021-04-26 21:26:37.000000000","message":"Feels like an aggressive default to me -- something like 300s seems more reasonable, and in line with\n\n* object-expirer\u0027s report_interval\n* object-updater\u0027s report_interval\n* object-replicator\u0027s stats_interval\n* object-reconstructor\u0027s stats_interval","commit_id":"cbed96294f376464021d3994bf8f17996434118b"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"f2944a5f2b55b5792f98eaac9efeab33e8e2dbd1","unresolved":false,"context_lines":[{"line_number":639,"context_line":"# different inodes to be relinked to the next partition power location."},{"line_number":640,"context_line":"# link_check_limit \u003d 2"},{"line_number":641,"context_line":"#"},{"line_number":642,"context_line":"# recon_interval \u003d 10.0"},{"line_number":643,"context_line":"# recon_cache_path \u003d /var/cache/swift"}],"source_content_type":"application/octet-stream","patch_set":30,"id":"68549070_656c5862","line":642,"in_reply_to":"7c932a2c_9310535a","updated":"2021-04-27 07:13:19.000000000","message":"Done","commit_id":"cbed96294f376464021d3994bf8f17996434118b"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"fe33b948377bd711287784a49b16567708dbff35","unresolved":true,"context_lines":[{"line_number":640,"context_line":"# link_check_limit \u003d 2"},{"line_number":641,"context_line":"#"},{"line_number":642,"context_line":"# recon_interval \u003d 10.0"},{"line_number":643,"context_line":"# recon_cache_path \u003d /var/cache/swift"}],"source_content_type":"application/octet-stream","patch_set":30,"id":"3afc4ed9_b116cdf1","line":643,"updated":"2021-04-26 21:26:37.000000000","message":"We should probably move this up to [DEFAULT] -- we use it all over the place! Proposed https://review.opendev.org/c/openstack/swift/+/788067","commit_id":"cbed96294f376464021d3994bf8f17996434118b"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"f2944a5f2b55b5792f98eaac9efeab33e8e2dbd1","unresolved":true,"context_lines":[{"line_number":640,"context_line":"# link_check_limit \u003d 2"},{"line_number":641,"context_line":"#"},{"line_number":642,"context_line":"# recon_interval \u003d 10.0"},{"line_number":643,"context_line":"# recon_cache_path \u003d /var/cache/swift"}],"source_content_type":"application/octet-stream","patch_set":30,"id":"5c200a27_4dc7b8e1","line":643,"in_reply_to":"3afc4ed9_b116cdf1","updated":"2021-04-27 07:13:19.000000000","message":"True, but I\u0027ll leave that for the follow up.","commit_id":"cbed96294f376464021d3994bf8f17996434118b"}],"swift/cli/relinker.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"87547941630594d9a3f7eb588fd4273177f849a3","unresolved":true,"context_lines":[{"line_number":41,"context_line":"EXIT_ERROR \u003d 1"},{"line_number":42,"context_line":"RECON_FILE \u003d \u0027relink.recon\u0027"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"DEFAULT_RECON_PROGRESS_STATS \u003d {"},{"line_number":45,"context_line":"    \u0027progress\u0027: [{\u0027device\u0027: \u0027\u0027,"},{"line_number":46,"context_line":"                  \u0027step\u0027: \u0027\u0027,"},{"line_number":47,"context_line":"                  \u0027parts_done\u0027: 0,"}],"source_content_type":"text/x-python","patch_set":4,"id":"9e75f85b_bad5f7d1","line":44,"updated":"2021-03-11 21:19:26.000000000","message":"Where\u0027s this used?","commit_id":"8de910bec02d907ddb8b5e432c0735a79d9c2669"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"87547941630594d9a3f7eb588fd4273177f849a3","unresolved":true,"context_lines":[{"line_number":227,"context_line":"    if not recon_cache.get(\u0027progress\u0027):"},{"line_number":228,"context_line":"        recon_cache[\u0027progress\u0027] \u003d {}"},{"line_number":229,"context_line":"    recon_cache[\u0027progress\u0027][device] \u003d device_progress"},{"line_number":230,"context_line":"    dump_recon_cache(recon_cache, conf[\u0027recon_cache\u0027], logger)"},{"line_number":231,"context_line":"    logger.info(\"Device: %s Step: %s Partitions: %d/%d\" % ("},{"line_number":232,"context_line":"        device, step, num_parts_done, num_total_parts))"},{"line_number":233,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"595f96b6_ac9e60bb","line":230,"updated":"2021-03-11 21:19:26.000000000","message":"What happens if we\u0027ve got concurrent writers? I guess one of them wins and updates their device, while the other one has to try again next time it finishes a partition?","commit_id":"8de910bec02d907ddb8b5e432c0735a79d9c2669"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5fd139138df992b6a798b496d4725387295cd36b","unresolved":true,"context_lines":[{"line_number":215,"context_line":"                       \u0027parts_done\u0027: num_parts_done,"},{"line_number":216,"context_line":"                       \u0027total_parts\u0027: num_total_parts,"},{"line_number":217,"context_line":"                       \u0027timestamp\u0027: Timestamp.now().timestamp}"},{"line_number":218,"context_line":"    recon_cache_dev \u003d {\u0027progress\u0027: {device: device_progress}}"},{"line_number":219,"context_line":"    dump_recon_cache(recon_cache_dev, conf[\u0027recon_cache\u0027], logger)"},{"line_number":220,"context_line":"    logger.info(\"Device: %s Step: %s Partitions: %d/%d\" % ("},{"line_number":221,"context_line":"        device, step, num_parts_done, num_total_parts))"}],"source_content_type":"text/x-python","patch_set":5,"id":"9ae235ed_c301d284","line":218,"range":{"start_line":218,"start_character":24,"end_line":218,"end_character":32},"updated":"2021-03-12 03:31:24.000000000","message":"Should probably be policy-specific. Maybe we have progress, progress-1, progress-2 keys?","commit_id":"9ca40858e0b271efe9f2da428ae2384de8bec151"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"8cb4f1b3dbbc6a4e5704ebab8600ed991ce8d54f","unresolved":true,"context_lines":[{"line_number":36,"context_line":"EXIT_SUCCESS \u003d 0"},{"line_number":37,"context_line":"EXIT_NO_APPLICABLE_POLICY \u003d 2"},{"line_number":38,"context_line":"EXIT_ERROR \u003d 1"},{"line_number":39,"context_line":"RECON_FILE \u003d \u0027relink.recon\u0027"},{"line_number":40,"context_line":""},{"line_number":41,"context_line":""},{"line_number":42,"context_line":"def non_negative_float(value):"}],"source_content_type":"text/x-python","patch_set":10,"id":"761422fb_8972366b","line":39,"range":{"start_line":39,"start_character":14,"end_line":39,"end_character":26},"updated":"2021-03-19 15:26:33.000000000","message":"I guess all the other files use \u0027relink\u0027, but there\u0027s some overlap between \u0027relink\u0027 the step vs \u0027cleanup\u0027 and \u0027relink\u0027 the entire process - the stats are reporting progress of the relinker, not just the relink step","commit_id":"8aa713f3208a1c333b15b1f999e1aac9cec5db58"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"4b15ab9cfec169c8580c83e6bc56b42b036ebde3","unresolved":false,"context_lines":[{"line_number":36,"context_line":"EXIT_SUCCESS \u003d 0"},{"line_number":37,"context_line":"EXIT_NO_APPLICABLE_POLICY \u003d 2"},{"line_number":38,"context_line":"EXIT_ERROR \u003d 1"},{"line_number":39,"context_line":"RECON_FILE \u003d \u0027relink.recon\u0027"},{"line_number":40,"context_line":""},{"line_number":41,"context_line":""},{"line_number":42,"context_line":"def non_negative_float(value):"}],"source_content_type":"text/x-python","patch_set":10,"id":"4052bd8b_ecd03090","line":39,"range":{"start_line":39,"start_character":14,"end_line":39,"end_character":26},"in_reply_to":"761422fb_8972366b","updated":"2021-03-21 23:03:20.000000000","message":"Good call, with change it to relinker.recon","commit_id":"8aa713f3208a1c333b15b1f999e1aac9cec5db58"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"8cb4f1b3dbbc6a4e5704ebab8600ed991ce8d54f","unresolved":true,"context_lines":[{"line_number":135,"context_line":""},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"# Save states when a partition is done"},{"line_number":138,"context_line":"def hook_post_partition(logger, conf, states, step, policy, diskfile_manager,"},{"line_number":139,"context_line":"                        partition_path):"},{"line_number":140,"context_line":"    datadir_path, part \u003d os.path.split(os.path.abspath(partition_path))"},{"line_number":141,"context_line":"    device_path, datadir_name \u003d os.path.split(datadir_path)"}],"source_content_type":"text/x-python","patch_set":10,"id":"dccbcb4a_2d2896b3","line":138,"updated":"2021-03-19 15:26:33.000000000","message":"Tim is going to rescue us from this perpetual proliferation of partial args https://review.opendev.org/c/openstack/swift/+/781576/1/swift/cli/relinker.py","commit_id":"8aa713f3208a1c333b15b1f999e1aac9cec5db58"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"4b15ab9cfec169c8580c83e6bc56b42b036ebde3","unresolved":true,"context_lines":[{"line_number":135,"context_line":""},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"# Save states when a partition is done"},{"line_number":138,"context_line":"def hook_post_partition(logger, conf, states, step, policy, diskfile_manager,"},{"line_number":139,"context_line":"                        partition_path):"},{"line_number":140,"context_line":"    datadir_path, part \u003d os.path.split(os.path.abspath(partition_path))"},{"line_number":141,"context_line":"    device_path, datadir_name \u003d os.path.split(datadir_path)"}],"source_content_type":"text/x-python","patch_set":10,"id":"232c381e_cf8363c2","line":138,"in_reply_to":"dccbcb4a_2d2896b3","updated":"2021-03-21 23:03:20.000000000","message":"oh awesome! That\u0027s a great improvement","commit_id":"8aa713f3208a1c333b15b1f999e1aac9cec5db58"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"8cb4f1b3dbbc6a4e5704ebab8600ed991ce8d54f","unresolved":true,"context_lines":[{"line_number":211,"context_line":"    device_progress \u003d {\u0027step\u0027: step,"},{"line_number":212,"context_line":"                       \u0027parts_done\u0027: num_parts_done,"},{"line_number":213,"context_line":"                       \u0027total_parts\u0027: num_total_parts,"},{"line_number":214,"context_line":"                       \u0027timestamp\u0027: Timestamp.now().timestamp}"},{"line_number":215,"context_line":"    recon_cache_dev \u003d {get_policy_string(\"progress\", policy): {"},{"line_number":216,"context_line":"        device: device_progress}}"},{"line_number":217,"context_line":"    dump_recon_cache(recon_cache_dev, conf[\u0027recon_cache\u0027], logger)"}],"source_content_type":"text/x-python","patch_set":10,"id":"25510067_9c318faf","line":214,"range":{"start_line":214,"start_character":52,"end_line":214,"end_character":61},"updated":"2021-03-19 15:26:33.000000000","message":"did you want .timestamp rather than .normal?","commit_id":"8aa713f3208a1c333b15b1f999e1aac9cec5db58"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"4b15ab9cfec169c8580c83e6bc56b42b036ebde3","unresolved":false,"context_lines":[{"line_number":211,"context_line":"    device_progress \u003d {\u0027step\u0027: step,"},{"line_number":212,"context_line":"                       \u0027parts_done\u0027: num_parts_done,"},{"line_number":213,"context_line":"                       \u0027total_parts\u0027: num_total_parts,"},{"line_number":214,"context_line":"                       \u0027timestamp\u0027: Timestamp.now().timestamp}"},{"line_number":215,"context_line":"    recon_cache_dev \u003d {get_policy_string(\"progress\", policy): {"},{"line_number":216,"context_line":"        device: device_progress}}"},{"line_number":217,"context_line":"    dump_recon_cache(recon_cache_dev, conf[\u0027recon_cache\u0027], logger)"}],"source_content_type":"text/x-python","patch_set":10,"id":"a4ca138e_571ebee9","line":214,"range":{"start_line":214,"start_character":52,"end_line":214,"end_character":61},"in_reply_to":"25510067_9c318faf","updated":"2021-03-21 23:03:20.000000000","message":"Sure, I guess it\u0027ll return the same thing basically.","commit_id":"8aa713f3208a1c333b15b1f999e1aac9cec5db58"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"8cb4f1b3dbbc6a4e5704ebab8600ed991ce8d54f","unresolved":true,"context_lines":[{"line_number":212,"context_line":"                       \u0027parts_done\u0027: num_parts_done,"},{"line_number":213,"context_line":"                       \u0027total_parts\u0027: num_total_parts,"},{"line_number":214,"context_line":"                       \u0027timestamp\u0027: Timestamp.now().timestamp}"},{"line_number":215,"context_line":"    recon_cache_dev \u003d {get_policy_string(\"progress\", policy): {"},{"line_number":216,"context_line":"        device: device_progress}}"},{"line_number":217,"context_line":"    dump_recon_cache(recon_cache_dev, conf[\u0027recon_cache\u0027], logger)"},{"line_number":218,"context_line":"    logger.info(\"Device: %s Step: %s Partitions: %d/%d\" % ("}],"source_content_type":"text/x-python","patch_set":10,"id":"71f032e2_0a200b8c","line":215,"range":{"start_line":215,"start_character":4,"end_line":215,"end_character":19},"updated":"2021-03-19 15:26:33.000000000","message":"this name threw me at first - its the dict to write, but it sounded like something to do with recon_cache_path","commit_id":"8aa713f3208a1c333b15b1f999e1aac9cec5db58"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"4b15ab9cfec169c8580c83e6bc56b42b036ebde3","unresolved":false,"context_lines":[{"line_number":212,"context_line":"                       \u0027parts_done\u0027: num_parts_done,"},{"line_number":213,"context_line":"                       \u0027total_parts\u0027: num_total_parts,"},{"line_number":214,"context_line":"                       \u0027timestamp\u0027: Timestamp.now().timestamp}"},{"line_number":215,"context_line":"    recon_cache_dev \u003d {get_policy_string(\"progress\", policy): {"},{"line_number":216,"context_line":"        device: device_progress}}"},{"line_number":217,"context_line":"    dump_recon_cache(recon_cache_dev, conf[\u0027recon_cache\u0027], logger)"},{"line_number":218,"context_line":"    logger.info(\"Device: %s Step: %s Partitions: %d/%d\" % ("}],"source_content_type":"text/x-python","patch_set":10,"id":"ad734022_8d98f12a","line":215,"range":{"start_line":215,"start_character":4,"end_line":215,"end_character":19},"in_reply_to":"71f032e2_0a200b8c","updated":"2021-03-21 23:03:20.000000000","message":"yup good call, I can see it\u0027s named a little confusingly.","commit_id":"8aa713f3208a1c333b15b1f999e1aac9cec5db58"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"8cb4f1b3dbbc6a4e5704ebab8600ed991ce8d54f","unresolved":true,"context_lines":[{"line_number":528,"context_line":"        \u0027files_per_second\u0027: ("},{"line_number":529,"context_line":"            args.files_per_second if args.files_per_second is not None"},{"line_number":530,"context_line":"            else non_negative_float(conf.get(\u0027files_per_second\u0027, \u00270\u0027))),"},{"line_number":531,"context_line":"        \u0027recon_cache_path\u0027: recon_cache_path,"},{"line_number":532,"context_line":"        \u0027recon_cache\u0027: os.path.join(recon_cache_path, RECON_FILE)"},{"line_number":533,"context_line":"    })"},{"line_number":534,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"91c6fd48_b186b9a5","line":531,"range":{"start_line":531,"start_character":9,"end_line":531,"end_character":45},"updated":"2021-03-19 15:26:33.000000000","message":"this isn\u0027t needed?","commit_id":"8aa713f3208a1c333b15b1f999e1aac9cec5db58"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"4b15ab9cfec169c8580c83e6bc56b42b036ebde3","unresolved":true,"context_lines":[{"line_number":528,"context_line":"        \u0027files_per_second\u0027: ("},{"line_number":529,"context_line":"            args.files_per_second if args.files_per_second is not None"},{"line_number":530,"context_line":"            else non_negative_float(conf.get(\u0027files_per_second\u0027, \u00270\u0027))),"},{"line_number":531,"context_line":"        \u0027recon_cache_path\u0027: recon_cache_path,"},{"line_number":532,"context_line":"        \u0027recon_cache\u0027: os.path.join(recon_cache_path, RECON_FILE)"},{"line_number":533,"context_line":"    })"},{"line_number":534,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"1d50b5d5_3991f749","line":531,"range":{"start_line":531,"start_character":9,"end_line":531,"end_character":45},"in_reply_to":"91c6fd48_b186b9a5","updated":"2021-03-21 23:03:20.000000000","message":"Yeah, this is a little weird but how we define it in other configs. We just use the path, but I also want to pass the full path because that\u0027s how we pass params (currently at least) in the relinker.\n\nSeeing as the file is a constant, I guess I can just do tha os.path.join when I need it and only use the above? So is it more obvous the way it is now.. as weird as it looks?","commit_id":"8aa713f3208a1c333b15b1f999e1aac9cec5db58"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"8cb4f1b3dbbc6a4e5704ebab8600ed991ce8d54f","unresolved":true,"context_lines":[{"line_number":529,"context_line":"            args.files_per_second if args.files_per_second is not None"},{"line_number":530,"context_line":"            else non_negative_float(conf.get(\u0027files_per_second\u0027, \u00270\u0027))),"},{"line_number":531,"context_line":"        \u0027recon_cache_path\u0027: recon_cache_path,"},{"line_number":532,"context_line":"        \u0027recon_cache\u0027: os.path.join(recon_cache_path, RECON_FILE)"},{"line_number":533,"context_line":"    })"},{"line_number":534,"context_line":""},{"line_number":535,"context_line":"    if args.action \u003d\u003d \u0027relink\u0027:"}],"source_content_type":"text/x-python","patch_set":10,"id":"891d2ab2_9bcd8507","line":532,"range":{"start_line":532,"start_character":9,"end_line":532,"end_character":20},"updated":"2021-03-19 15:26:33.000000000","message":"ok, this gets used","commit_id":"8aa713f3208a1c333b15b1f999e1aac9cec5db58"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"134275bf7fa2f5682b76444acd3fd4888c993305","unresolved":true,"context_lines":[{"line_number":248,"context_line":"        device_progress_recon \u003d {get_policy_string(\"progress\", self.policy): {"},{"line_number":249,"context_line":"            device: device_progress}}"},{"line_number":250,"context_line":"        recon_cache \u003d os.path.join(self.conf[\u0027recon_cache_path\u0027], RECON_FILE)"},{"line_number":251,"context_line":"        dump_recon_cache(device_progress_recon, recon_cache, self.logger)"},{"line_number":252,"context_line":"        self.logger.info(\"Device: %s Step: %s Partitions: %d/%d\" % ("},{"line_number":253,"context_line":"            device, STEP_CLEANUP if self.do_cleanup else STEP_RELINK,"},{"line_number":254,"context_line":"            num_parts_done, len(self.states[\"state\"])))"}],"source_content_type":"text/x-python","patch_set":12,"id":"a678422b_836f8848","line":251,"updated":"2021-03-22 11:30:09.000000000","message":"ok, so we have progress per device updated here.\n\nWhen relinker first starts, should it reset *all* devices? otherwise there\u0027s a start up period when the recon would show devices with all parts done when in fact no parts are done.\n\nThat would ideally means coupling the reset of recon with a reset of the state files, which the relinker doesn\u0027t yet do (but should).\n\nBut during start up the recon stats could be updated from the states file so that if the state file has been reset by another process then recon reflects that. In hook_pre_device maybe? Or maybe sooner - if the relinker process is running over more than one device then we\u0027d need all the devices to have their recon info reset early in the process. But only if it\u0027s a fresh start, not if the relinker is picking up from where it left off previous progress.\n\nBottom line is that when the relinker process starts it needs to make sure that current recon info reflects what is in the state file.\n\nHmmm, so could the two files be the same?","commit_id":"d09cb426f391cae6963186b0b4b5c04cdaf9700d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"134275bf7fa2f5682b76444acd3fd4888c993305","unresolved":true,"context_lines":[{"line_number":251,"context_line":"        dump_recon_cache(device_progress_recon, recon_cache, self.logger)"},{"line_number":252,"context_line":"        self.logger.info(\"Device: %s Step: %s Partitions: %d/%d\" % ("},{"line_number":253,"context_line":"            device, STEP_CLEANUP if self.do_cleanup else STEP_RELINK,"},{"line_number":254,"context_line":"            num_parts_done, len(self.states[\"state\"])))"},{"line_number":255,"context_line":""},{"line_number":256,"context_line":"    def hashes_filter(self, suff_path, hashes):"},{"line_number":257,"context_line":"        hashes \u003d list(hashes)"}],"source_content_type":"text/x-python","patch_set":12,"id":"56235703_127f4a6c","line":254,"range":{"start_line":254,"start_character":28,"end_line":254,"end_character":53},"updated":"2021-03-22 11:30:09.000000000","message":"nit: could be num_total_parts","commit_id":"d09cb426f391cae6963186b0b4b5c04cdaf9700d"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"15829e7d55eeedfd975452574f5905017df0089d","unresolved":true,"context_lines":[{"line_number":366,"context_line":"                1 for part in self.states[\"state\"].values()"},{"line_number":367,"context_line":"                if part)"},{"line_number":368,"context_line":"            num_total_parts \u003d len(self.states[\"state\"])"},{"line_number":369,"context_line":"            step \u003d STEP_CLEANUP if self.do_cleanup else STEP_RELINK"},{"line_number":370,"context_line":"            device_progress \u003d {\u0027step\u0027: step,"},{"line_number":371,"context_line":"                               \u0027parts_done\u0027: num_parts_done,"},{"line_number":372,"context_line":"                               \u0027total_parts\u0027: num_total_parts,"}],"source_content_type":"text/x-python","patch_set":15,"id":"fdc5b6c7_aa11a33c","line":369,"updated":"2021-03-30 20:07:39.000000000","message":"I wonder if it would be better to record part_power/next_part_power... I know I ran into trouble with that in the state files before.","commit_id":"368c931c4ebc833e76854e0b4335c9f7d43259f7"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"104b3be0e282cae70660feaf3d608a395aa226c9","unresolved":true,"context_lines":[{"line_number":376,"context_line":"                    device: device_progress}}"},{"line_number":377,"context_line":"        else:"},{"line_number":378,"context_line":"            device_progress_recon \u003d {"},{"line_number":379,"context_line":"                get_policy_string(\"progress\", self.policy): {}}"},{"line_number":380,"context_line":"        recon_cache \u003d os.path.join(self.conf[\u0027recon_cache_path\u0027], RECON_FILE)"},{"line_number":381,"context_line":"        dump_recon_cache(device_progress_recon, recon_cache, self.logger)"},{"line_number":382,"context_line":""}],"source_content_type":"text/x-python","patch_set":15,"id":"99b0e62c_283680c2","line":379,"updated":"2021-03-30 19:29:14.000000000","message":"so ALL this information is already presented/captured in LOGS - this change just starts to emit/update it in another place?","commit_id":"368c931c4ebc833e76854e0b4335c9f7d43259f7"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"3b3b10a4f832d7a2c818a8cb726dda2e1b78e5e6","unresolved":true,"context_lines":[{"line_number":376,"context_line":"                    device: device_progress}}"},{"line_number":377,"context_line":"        else:"},{"line_number":378,"context_line":"            device_progress_recon \u003d {"},{"line_number":379,"context_line":"                get_policy_string(\"progress\", self.policy): {}}"},{"line_number":380,"context_line":"        recon_cache \u003d os.path.join(self.conf[\u0027recon_cache_path\u0027], RECON_FILE)"},{"line_number":381,"context_line":"        dump_recon_cache(device_progress_recon, recon_cache, self.logger)"},{"line_number":382,"context_line":""}],"source_content_type":"text/x-python","patch_set":15,"id":"bbf5c90f_1ade7850","line":379,"in_reply_to":"17648736_7914024f","updated":"2021-03-30 23:30:19.000000000","message":"Love that idea! I need to play with swift-recon more...","commit_id":"368c931c4ebc833e76854e0b4335c9f7d43259f7"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"0eb4f2f8aa69031d82a1521b2332c248605c5829","unresolved":true,"context_lines":[{"line_number":376,"context_line":"                    device: device_progress}}"},{"line_number":377,"context_line":"        else:"},{"line_number":378,"context_line":"            device_progress_recon \u003d {"},{"line_number":379,"context_line":"                get_policy_string(\"progress\", self.policy): {}}"},{"line_number":380,"context_line":"        recon_cache \u003d os.path.join(self.conf[\u0027recon_cache_path\u0027], RECON_FILE)"},{"line_number":381,"context_line":"        dump_recon_cache(device_progress_recon, recon_cache, self.logger)"},{"line_number":382,"context_line":""}],"source_content_type":"text/x-python","patch_set":15,"id":"17648736_7914024f","line":379,"in_reply_to":"99b0e62c_283680c2","updated":"2021-03-30 23:01:34.000000000","message":"Yeah, that\u0027s true. The point was so we can watch the relinker live without having to wait and query the log tooling (pro stack). On the first part power increase people picked a different node and had a bash script to keep looking at progress of stat files.\n\nSo this became an endpoint we could monitor without crazy hacks.\n\nIe. jump on a node and hit the end point `curl http://localhost:\u003cany storage port\u003e/recon/relnker\n\nAnd also opens up the usecase for something like the controller to query the progress of the reliner.\n\nWhat might be a useful follow up would be to add to the recon tool (rather then just the middleware) to summerise the status of all nodes so with one command we can see if relinking is complete, like we can do for replicator cycles.","commit_id":"368c931c4ebc833e76854e0b4335c9f7d43259f7"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"15829e7d55eeedfd975452574f5905017df0089d","unresolved":true,"context_lines":[{"line_number":393,"context_line":"            \"next_part_power\": self.next_part_power,"},{"line_number":394,"context_line":"            \"state\": {},"},{"line_number":395,"context_line":"        }"},{"line_number":396,"context_line":"        self._update_recon()"},{"line_number":397,"context_line":""},{"line_number":398,"context_line":"        locations \u003d audit_location_generator("},{"line_number":399,"context_line":"            self.conf[\u0027devices\u0027],"}],"source_content_type":"text/x-python","patch_set":15,"id":"f5ea2cab_92417726","line":396,"updated":"2021-03-30 20:07:39.000000000","message":"So this resets the recon cache for all devices... what about targeted relinker runs, where the operator is just specifying one --device?","commit_id":"368c931c4ebc833e76854e0b4335c9f7d43259f7"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"3b3b10a4f832d7a2c818a8cb726dda2e1b78e5e6","unresolved":true,"context_lines":[{"line_number":393,"context_line":"            \"next_part_power\": self.next_part_power,"},{"line_number":394,"context_line":"            \"state\": {},"},{"line_number":395,"context_line":"        }"},{"line_number":396,"context_line":"        self._update_recon()"},{"line_number":397,"context_line":""},{"line_number":398,"context_line":"        locations \u003d audit_location_generator("},{"line_number":399,"context_line":"            self.conf[\u0027devices\u0027],"}],"source_content_type":"text/x-python","patch_set":15,"id":"cf9649a3_f80b3ce0","line":396,"in_reply_to":"7a642f0f_364001f3","updated":"2021-03-30 23:30:19.000000000","message":"It also gets hairy with some of the other targeting options we recently added like --policy and --partition :-/","commit_id":"368c931c4ebc833e76854e0b4335c9f7d43259f7"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"7eb6d7105063afca136774f4bef67d2eb7f6c95d","unresolved":true,"context_lines":[{"line_number":393,"context_line":"            \"next_part_power\": self.next_part_power,"},{"line_number":394,"context_line":"            \"state\": {},"},{"line_number":395,"context_line":"        }"},{"line_number":396,"context_line":"        self._update_recon()"},{"line_number":397,"context_line":""},{"line_number":398,"context_line":"        locations \u003d audit_location_generator("},{"line_number":399,"context_line":"            self.conf[\u0027devices\u0027],"}],"source_content_type":"text/x-python","patch_set":15,"id":"a6b84987_b62f0a96","line":396,"in_reply_to":"cf9649a3_f80b3ce0","updated":"2021-03-31 01:14:36.000000000","message":"ok.. got this working I think. About to send up a new version. I\u0027ve changed the recon layout, it\u0027s now:\n\n  { \u0027progress\u0027: {\n      \u0027\u003cpolicy idx\u003e\u0027: {\n       \u0027\u003cdevice\u003e\u0027: {\u003cstats\u003e}\n      }\n    }\n  }\n\nAnd if self.device is set then we only clear out that device.","commit_id":"368c931c4ebc833e76854e0b4335c9f7d43259f7"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"0eb4f2f8aa69031d82a1521b2332c248605c5829","unresolved":true,"context_lines":[{"line_number":393,"context_line":"            \"next_part_power\": self.next_part_power,"},{"line_number":394,"context_line":"            \"state\": {},"},{"line_number":395,"context_line":"        }"},{"line_number":396,"context_line":"        self._update_recon()"},{"line_number":397,"context_line":""},{"line_number":398,"context_line":"        locations \u003d audit_location_generator("},{"line_number":399,"context_line":"            self.conf[\u0027devices\u0027],"}],"source_content_type":"text/x-python","patch_set":15,"id":"7a642f0f_364001f3","line":396,"in_reply_to":"f5ea2cab_92417726","updated":"2021-03-30 23:01:34.000000000","message":"oh yeah, with the --device, that does change things a little. Good point. I\u0027ll have to change the patch.","commit_id":"368c931c4ebc833e76854e0b4335c9f7d43259f7"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"15829e7d55eeedfd975452574f5905017df0089d","unresolved":true,"context_lines":[{"line_number":512,"context_line":"    parser.add_argument(\u0027--debug\u0027, default\u003dFalse, action\u003d\u0027store_true\u0027,"},{"line_number":513,"context_line":"                        help\u003d\u0027Enable debug mode\u0027)"},{"line_number":514,"context_line":"    parser.add_argument(\"--recon-cache-path\", default\u003dNone,"},{"line_number":515,"context_line":"                        help\u003d\u0027Set the path to the recon cache\u0027)"},{"line_number":516,"context_line":""},{"line_number":517,"context_line":"    args \u003d parser.parse_args(args)"},{"line_number":518,"context_line":"    if args.conf_file:"}],"source_content_type":"text/x-python","patch_set":15,"id":"eb5ef8db_4d18b219","line":515,"range":{"start_line":515,"start_character":30,"end_line":515,"end_character":61},"updated":"2021-03-30 20:07:39.000000000","message":"Maybe better as\n\n\u003e Set the path to the recon cache directory\n\n? Since operators shouldn\u0027t be setting this to the actual file path.","commit_id":"368c931c4ebc833e76854e0b4335c9f7d43259f7"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"0eb4f2f8aa69031d82a1521b2332c248605c5829","unresolved":false,"context_lines":[{"line_number":512,"context_line":"    parser.add_argument(\u0027--debug\u0027, default\u003dFalse, action\u003d\u0027store_true\u0027,"},{"line_number":513,"context_line":"                        help\u003d\u0027Enable debug mode\u0027)"},{"line_number":514,"context_line":"    parser.add_argument(\"--recon-cache-path\", default\u003dNone,"},{"line_number":515,"context_line":"                        help\u003d\u0027Set the path to the recon cache\u0027)"},{"line_number":516,"context_line":""},{"line_number":517,"context_line":"    args \u003d parser.parse_args(args)"},{"line_number":518,"context_line":"    if args.conf_file:"}],"source_content_type":"text/x-python","patch_set":15,"id":"7516cb72_b91a6ab0","line":515,"range":{"start_line":515,"start_character":30,"end_line":515,"end_character":61},"in_reply_to":"eb5ef8db_4d18b219","updated":"2021-03-30 23:01:34.000000000","message":"Ack","commit_id":"368c931c4ebc833e76854e0b4335c9f7d43259f7"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"f4923405386c00290fe7cfe29742d88feca49707","unresolved":true,"context_lines":[{"line_number":113,"context_line":"                raise"},{"line_number":114,"context_line":"        # initialise the device in recon."},{"line_number":115,"context_line":"        device \u003d os.path.basename(device_path)"},{"line_number":116,"context_line":"        self._update_recon(device)"},{"line_number":117,"context_line":""},{"line_number":118,"context_line":"    def hook_post_device(self, _):"},{"line_number":119,"context_line":"        os.close(self.dev_lock)"}],"source_content_type":"text/x-python","patch_set":19,"id":"e4a46d70_94f181e6","line":116,"updated":"2021-04-06 10:05:26.000000000","message":"If there is nothing in the stat file with will make initialise which might be useful for tracking progress from 0 - 1 partitions done.","commit_id":"421022a103f5bf749dc4e545bfc9f2628d9e0f9d"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"f4923405386c00290fe7cfe29742d88feca49707","unresolved":true,"context_lines":[{"line_number":496,"context_line":"        self._zero_stats()"},{"line_number":497,"context_line":"        self.start_time \u003d time.time()"},{"line_number":498,"context_line":"        dump_recon_cache({\"start_time\": self.start_time},"},{"line_number":499,"context_line":"                         self.recon_cache, self.logger)"},{"line_number":500,"context_line":"        for policy in self.conf[\u0027policies\u0027]:"},{"line_number":501,"context_line":"            self.policy \u003d policy"},{"line_number":502,"context_line":"            policy.object_ring \u003d None  # Ensure it will be reloaded"}],"source_content_type":"text/x-python","patch_set":19,"id":"b2822d8b_d6c048e5","line":499,"updated":"2021-04-06 10:05:26.000000000","message":"The start_time, total_time and stats are reset and dropped on every relinker run. So doesns\u0027t play too well with --partition etc.","commit_id":"421022a103f5bf749dc4e545bfc9f2628d9e0f9d"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"f4923405386c00290fe7cfe29742d88feca49707","unresolved":true,"context_lines":[{"line_number":512,"context_line":"            self.process_policy(policy)"},{"line_number":513,"context_line":""},{"line_number":514,"context_line":"        # dump stats to recon"},{"line_number":515,"context_line":"        total_time \u003d (time.time() - self.start_time)"},{"line_number":516,"context_line":"        dump_recon_cache({\u0027stats\u0027: self.stats,"},{"line_number":517,"context_line":"                          \u0027total_time\u0027: total_time},"},{"line_number":518,"context_line":"                         self.recon_cache, self.logger)"}],"source_content_type":"text/x-python","patch_set":19,"id":"42544d82_aed19201","line":515,"updated":"2021-04-06 10:05:26.000000000","message":"db replicators just use a `time.time() - start_time`, whereas object replicators use `(time.time() - start_time) / 60`\n\nrelinking probably won\u0027t take as long, so didn\u0027t add the `/ 60`.","commit_id":"421022a103f5bf749dc4e545bfc9f2628d9e0f9d"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"f4923405386c00290fe7cfe29742d88feca49707","unresolved":true,"context_lines":[{"line_number":515,"context_line":"        total_time \u003d (time.time() - self.start_time)"},{"line_number":516,"context_line":"        dump_recon_cache({\u0027stats\u0027: self.stats,"},{"line_number":517,"context_line":"                          \u0027total_time\u0027: total_time},"},{"line_number":518,"context_line":"                         self.recon_cache, self.logger)"},{"line_number":519,"context_line":"        policies \u003d self.stats.pop(\u0027policies\u0027)"},{"line_number":520,"context_line":"        if not policies:"},{"line_number":521,"context_line":"            self.logger.warning("}],"source_content_type":"text/x-python","patch_set":19,"id":"128811e8_c2f4213e","line":518,"updated":"2021-04-06 10:05:26.000000000","message":"Thought I\u0027d throw the stats in too.","commit_id":"421022a103f5bf749dc4e545bfc9f2628d9e0f9d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"2ede9cc17d369e75f707dd114041b66bf0891193","unresolved":true,"context_lines":[{"line_number":114,"context_line":"                raise"},{"line_number":115,"context_line":"        # initialise the device in recon."},{"line_number":116,"context_line":"        device \u003d os.path.basename(device_path)"},{"line_number":117,"context_line":"        self._update_recon(device)"},{"line_number":118,"context_line":""},{"line_number":119,"context_line":"    def hook_post_device(self, _):"},{"line_number":120,"context_line":"        os.close(self.dev_lock)"}],"source_content_type":"text/x-python","patch_set":21,"id":"4220ad46_5f536cdc","line":117,"updated":"2021-04-12 14:05:10.000000000","message":"ok, so this is creating a device entry and setting all the device items to zero","commit_id":"b59449401ef30240b76f2549d4d1758fd19de10c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"2ede9cc17d369e75f707dd114041b66bf0891193","unresolved":true,"context_lines":[{"line_number":438,"context_line":"            device_progress \u003d {\u0027step\u0027: step,"},{"line_number":439,"context_line":"                               \u0027parts_done\u0027: num_parts_done,"},{"line_number":440,"context_line":"                               \u0027total_parts\u0027: num_total_parts,"},{"line_number":441,"context_line":"                               \u0027timestamp\u0027: Timestamp.now().normal}"},{"line_number":442,"context_line":"            device_progress_recon \u003d {"},{"line_number":443,"context_line":"                get_policy_string(\"progress\", self.policy): {"},{"line_number":444,"context_line":"                    device: device_progress}}"}],"source_content_type":"text/x-python","patch_set":21,"id":"dfd3d9d1_17fc8ba7","line":441,"updated":"2021-04-12 14:05:10.000000000","message":"do we want per-device start and elapsed times?","commit_id":"b59449401ef30240b76f2549d4d1758fd19de10c"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"d8082da3c12499c10f02ad356a23e51bbccc71f2","unresolved":true,"context_lines":[{"line_number":438,"context_line":"            device_progress \u003d {\u0027step\u0027: step,"},{"line_number":439,"context_line":"                               \u0027parts_done\u0027: num_parts_done,"},{"line_number":440,"context_line":"                               \u0027total_parts\u0027: num_total_parts,"},{"line_number":441,"context_line":"                               \u0027timestamp\u0027: Timestamp.now().normal}"},{"line_number":442,"context_line":"            device_progress_recon \u003d {"},{"line_number":443,"context_line":"                get_policy_string(\"progress\", self.policy): {"},{"line_number":444,"context_line":"                    device: device_progress}}"}],"source_content_type":"text/x-python","patch_set":21,"id":"d32ab5fe_714cae53","line":441,"in_reply_to":"dfd3d9d1_17fc8ba7","updated":"2021-04-13 03:40:41.000000000","message":"oh that could be hany info.","commit_id":"b59449401ef30240b76f2549d4d1758fd19de10c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"2ede9cc17d369e75f707dd114041b66bf0891193","unresolved":true,"context_lines":[{"line_number":442,"context_line":"            device_progress_recon \u003d {"},{"line_number":443,"context_line":"                get_policy_string(\"progress\", self.policy): {"},{"line_number":444,"context_line":"                    device: device_progress}}"},{"line_number":445,"context_line":"        elif self.device_list:"},{"line_number":446,"context_line":"            # only reset for the given devices we\u0027re working on"},{"line_number":447,"context_line":"            policy_data \u003d {d: {} for d in self.device_list}"},{"line_number":448,"context_line":"            policy_data[\u0027part_power\u0027] \u003d self.part_power"}],"source_content_type":"text/x-python","patch_set":21,"id":"ed775b52_f07b65c7","line":445,"updated":"2021-04-12 14:05:10.000000000","message":"nit: for clarity, this could be two methods - one that writes device data and one that clears it - there\u0027s only one common line after the if/elif/else","commit_id":"b59449401ef30240b76f2549d4d1758fd19de10c"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"d8082da3c12499c10f02ad356a23e51bbccc71f2","unresolved":true,"context_lines":[{"line_number":442,"context_line":"            device_progress_recon \u003d {"},{"line_number":443,"context_line":"                get_policy_string(\"progress\", self.policy): {"},{"line_number":444,"context_line":"                    device: device_progress}}"},{"line_number":445,"context_line":"        elif self.device_list:"},{"line_number":446,"context_line":"            # only reset for the given devices we\u0027re working on"},{"line_number":447,"context_line":"            policy_data \u003d {d: {} for d in self.device_list}"},{"line_number":448,"context_line":"            policy_data[\u0027part_power\u0027] \u003d self.part_power"}],"source_content_type":"text/x-python","patch_set":21,"id":"78c6ea42_0873ce6a","line":445,"in_reply_to":"ed775b52_f07b65c7","updated":"2021-04-13 03:40:41.000000000","message":"yeah this method started much simpler when we only emitted a few stats in one place. Now that we need to run dump_to_recon_cache in a bunch of places, might need to think about reworking it all.","commit_id":"b59449401ef30240b76f2549d4d1758fd19de10c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"2ede9cc17d369e75f707dd114041b66bf0891193","unresolved":true,"context_lines":[{"line_number":451,"context_line":"                get_policy_string(\"progress\", self.policy): policy_data}"},{"line_number":452,"context_line":"        else:"},{"line_number":453,"context_line":"            # reset all for devices for the policy"},{"line_number":454,"context_line":"            # setting the who progress to {} will clear it all."},{"line_number":455,"context_line":"            device_progress_recon \u003d {"},{"line_number":456,"context_line":"                get_policy_string(\"progress\", self.policy): {}}"},{"line_number":457,"context_line":"            dump_recon_cache(device_progress_recon, self.recon_cache,"}],"source_content_type":"text/x-python","patch_set":21,"id":"2f5e1bbb_904a832a","line":454,"range":{"start_line":454,"start_character":26,"end_line":454,"end_character":29},"updated":"2021-04-12 14:05:10.000000000","message":"typo: \u0027who\u0027 ?","commit_id":"b59449401ef30240b76f2549d4d1758fd19de10c"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"d8082da3c12499c10f02ad356a23e51bbccc71f2","unresolved":true,"context_lines":[{"line_number":451,"context_line":"                get_policy_string(\"progress\", self.policy): policy_data}"},{"line_number":452,"context_line":"        else:"},{"line_number":453,"context_line":"            # reset all for devices for the policy"},{"line_number":454,"context_line":"            # setting the who progress to {} will clear it all."},{"line_number":455,"context_line":"            device_progress_recon \u003d {"},{"line_number":456,"context_line":"                get_policy_string(\"progress\", self.policy): {}}"},{"line_number":457,"context_line":"            dump_recon_cache(device_progress_recon, self.recon_cache,"}],"source_content_type":"text/x-python","patch_set":21,"id":"1df40cc4_a051d432","line":454,"range":{"start_line":454,"start_character":26,"end_line":454,"end_character":29},"in_reply_to":"2f5e1bbb_904a832a","updated":"2021-04-13 03:40:41.000000000","message":"whole. will fix.","commit_id":"b59449401ef30240b76f2549d4d1758fd19de10c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"2ede9cc17d369e75f707dd114041b66bf0891193","unresolved":true,"context_lines":[{"line_number":476,"context_line":"            \"next_part_power\": self.next_part_power,"},{"line_number":477,"context_line":"            \"state\": {},"},{"line_number":478,"context_line":"        }"},{"line_number":479,"context_line":"        self._update_recon()"},{"line_number":480,"context_line":""},{"line_number":481,"context_line":"        locations \u003d audit_location_generator("},{"line_number":482,"context_line":"            self.conf[\u0027devices\u0027],"}],"source_content_type":"text/x-python","patch_set":21,"id":"ff2df455_9ec4b2fc","line":479,"updated":"2021-04-12 14:05:10.000000000","message":"see comment below - doesn\u0027t this risk leaving stale data for other policies in recon cache until this run gets to the other policies?","commit_id":"b59449401ef30240b76f2549d4d1758fd19de10c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"2ede9cc17d369e75f707dd114041b66bf0891193","unresolved":true,"context_lines":[{"line_number":520,"context_line":"            self.process_policy(policy)"},{"line_number":521,"context_line":""},{"line_number":522,"context_line":"        # dump stats to recon"},{"line_number":523,"context_line":"        dump_recon_cache({\u0027stats_{}\u0027.format(os.getpid()): self.stats},"},{"line_number":524,"context_line":"                         self.recon_cache, self.logger)"},{"line_number":525,"context_line":"        policies \u003d self.stats.pop(\u0027policies\u0027)"},{"line_number":526,"context_line":"        if not policies:"}],"source_content_type":"text/x-python","patch_set":21,"id":"53cdc7c5_af46fbb5","line":523,"updated":"2021-04-12 14:05:10.000000000","message":"might be easier to parse if we had \n\n  stats : {\n      pid1: { ... },\n      pid2: { ... },\n      aggregate : { ... }\n  }\n\nwith aggregate being the result of collate at the end","commit_id":"b59449401ef30240b76f2549d4d1758fd19de10c"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"d8082da3c12499c10f02ad356a23e51bbccc71f2","unresolved":true,"context_lines":[{"line_number":520,"context_line":"            self.process_policy(policy)"},{"line_number":521,"context_line":""},{"line_number":522,"context_line":"        # dump stats to recon"},{"line_number":523,"context_line":"        dump_recon_cache({\u0027stats_{}\u0027.format(os.getpid()): self.stats},"},{"line_number":524,"context_line":"                         self.recon_cache, self.logger)"},{"line_number":525,"context_line":"        policies \u003d self.stats.pop(\u0027policies\u0027)"},{"line_number":526,"context_line":"        if not policies:"}],"source_content_type":"text/x-python","patch_set":21,"id":"0d9be17b_7bf7569e","line":523,"in_reply_to":"53cdc7c5_af46fbb5","updated":"2021-04-13 03:40:41.000000000","message":"yeah, we could wrap them this way. I put them here so they don\u0027t appear in the recon middleware output until its been aggregated. But we want to provide the PID stats along with everything else sure, happy to change.","commit_id":"b59449401ef30240b76f2549d4d1758fd19de10c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"2ede9cc17d369e75f707dd114041b66bf0891193","unresolved":true,"context_lines":[{"line_number":568,"context_line":"    # dump the start time"},{"line_number":569,"context_line":"    recon_cache \u003d os.path.join(conf[\u0027recon_cache_path\u0027], RECON_FILE)"},{"line_number":570,"context_line":"    start_time \u003d time.time()"},{"line_number":571,"context_line":"    # inialise recon dump for collection"},{"line_number":572,"context_line":"    dump_recon_cache({\"start_time\": start_time, \"total_time\": None,"},{"line_number":573,"context_line":"                      \u0027stats\u0027: {}},"},{"line_number":574,"context_line":"                     recon_cache, logger)"}],"source_content_type":"text/x-python","patch_set":21,"id":"2184e8e9_a962f223","line":571,"updated":"2021-04-12 14:05:10.000000000","message":"nit: typo: initialise","commit_id":"b59449401ef30240b76f2549d4d1758fd19de10c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"2ede9cc17d369e75f707dd114041b66bf0891193","unresolved":true,"context_lines":[{"line_number":571,"context_line":"    # inialise recon dump for collection"},{"line_number":572,"context_line":"    dump_recon_cache({\"start_time\": start_time, \"total_time\": None,"},{"line_number":573,"context_line":"                      \u0027stats\u0027: {}},"},{"line_number":574,"context_line":"                     recon_cache, logger)"},{"line_number":575,"context_line":""},{"line_number":576,"context_line":"    device_list \u003d sorted(set(device_list or os.listdir(conf[\u0027devices\u0027])))"},{"line_number":577,"context_line":"    workers \u003d conf[\u0027workers\u0027]"}],"source_content_type":"text/x-python","patch_set":21,"id":"68a7994e_9b0edf76","line":574,"updated":"2021-04-12 14:05:10.000000000","message":"why not clear progress here for all device_list in all policies? otherwise, if we have stale progress data for a policy, and this run is for more than one policy, the state data could still be in recon cache until this run gets round to the policy?","commit_id":"b59449401ef30240b76f2549d4d1758fd19de10c"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"d8082da3c12499c10f02ad356a23e51bbccc71f2","unresolved":true,"context_lines":[{"line_number":571,"context_line":"    # inialise recon dump for collection"},{"line_number":572,"context_line":"    dump_recon_cache({\"start_time\": start_time, \"total_time\": None,"},{"line_number":573,"context_line":"                      \u0027stats\u0027: {}},"},{"line_number":574,"context_line":"                     recon_cache, logger)"},{"line_number":575,"context_line":""},{"line_number":576,"context_line":"    device_list \u003d sorted(set(device_list or os.listdir(conf[\u0027devices\u0027])))"},{"line_number":577,"context_line":"    workers \u003d conf[\u0027workers\u0027]"}],"source_content_type":"text/x-python","patch_set":21,"id":"b650babb_4d54af05","line":574,"in_reply_to":"68a7994e_9b0edf76","updated":"2021-04-13 03:40:41.000000000","message":"yeah clearing for all policies makes sense, thanks","commit_id":"b59449401ef30240b76f2549d4d1758fd19de10c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"2ede9cc17d369e75f707dd114041b66bf0891193","unresolved":true,"context_lines":[{"line_number":639,"context_line":""},{"line_number":640,"context_line":""},{"line_number":641,"context_line":"def cleanup_finalize_recon(recon_cache, start_time, logger):"},{"line_number":642,"context_line":"    # collate pid worker stats and remove them from recon at the same time."},{"line_number":643,"context_line":"    stats, empty_pid_stats \u003d collate_stats(recon_cache)"},{"line_number":644,"context_line":"    total_time \u003d (time.time() - start_time)"},{"line_number":645,"context_line":"    recon_data \u003d dict(total_time\u003dtotal_time, stats\u003dstats, **empty_pid_stats)"}],"source_content_type":"text/x-python","patch_set":21,"id":"03ef705f_52402686","line":642,"updated":"2021-04-12 14:05:10.000000000","message":"how does this work out if there are multiple relinker processes (multiple parents, each with workers)? or if a previous run did not clean up recon cache so there are stale stats_pid dicts in there?","commit_id":"b59449401ef30240b76f2549d4d1758fd19de10c"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"d8082da3c12499c10f02ad356a23e51bbccc71f2","unresolved":true,"context_lines":[{"line_number":639,"context_line":""},{"line_number":640,"context_line":""},{"line_number":641,"context_line":"def cleanup_finalize_recon(recon_cache, start_time, logger):"},{"line_number":642,"context_line":"    # collate pid worker stats and remove them from recon at the same time."},{"line_number":643,"context_line":"    stats, empty_pid_stats \u003d collate_stats(recon_cache)"},{"line_number":644,"context_line":"    total_time \u003d (time.time() - start_time)"},{"line_number":645,"context_line":"    recon_data \u003d dict(total_time\u003dtotal_time, stats\u003dstats, **empty_pid_stats)"}],"source_content_type":"text/x-python","patch_set":21,"id":"df3b005d_ed491202","line":642,"in_reply_to":"03ef705f_52402686","updated":"2021-04-13 03:40:41.000000000","message":"I guess I hope we only have the one process running it\u0027s own workers. Cleanup happens after they\u0027re all done... I hope. Because pids change I want to be able to clean them up.. this is a benefit of your stats -\u003e {pid, aggregated} change.","commit_id":"b59449401ef30240b76f2549d4d1758fd19de10c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"2ede9cc17d369e75f707dd114041b66bf0891193","unresolved":true,"context_lines":[{"line_number":654,"context_line":"        if not key.startswith(\u0027stats_\u0027):"},{"line_number":655,"context_line":"            continue"},{"line_number":656,"context_line":"        empty_pid_stats[key] \u003d {}"},{"line_number":657,"context_line":"        for stat, value in stats.items():"},{"line_number":658,"context_line":"            if stat \u003d\u003d \u0027policies\u0027:"},{"line_number":659,"context_line":"                if stat in collated_stats:"},{"line_number":660,"context_line":"                    collated_stats[stat] \u003d max(value, collated_stats[stat])"}],"source_content_type":"text/x-python","patch_set":21,"id":"9e821807_967a69c2","line":657,"updated":"2021-04-12 14:05:10.000000000","message":"I think we\u0027ll need to pass children pids into these functions and make the aggregation select only the current children\n\nso if we had a key in stats per child pid, something like:\n\n  for pid, value in recon_stats.get(\u0027stats\u0027, {}):\n     if pid not in children_pids:\n         etc...","commit_id":"b59449401ef30240b76f2549d4d1758fd19de10c"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"d8082da3c12499c10f02ad356a23e51bbccc71f2","unresolved":true,"context_lines":[{"line_number":654,"context_line":"        if not key.startswith(\u0027stats_\u0027):"},{"line_number":655,"context_line":"            continue"},{"line_number":656,"context_line":"        empty_pid_stats[key] \u003d {}"},{"line_number":657,"context_line":"        for stat, value in stats.items():"},{"line_number":658,"context_line":"            if stat \u003d\u003d \u0027policies\u0027:"},{"line_number":659,"context_line":"                if stat in collated_stats:"},{"line_number":660,"context_line":"                    collated_stats[stat] \u003d max(value, collated_stats[stat])"}],"source_content_type":"text/x-python","patch_set":21,"id":"3deaf779_ede02cea","line":657,"in_reply_to":"9e821807_967a69c2","updated":"2021-04-13 03:40:41.000000000","message":"good idea","commit_id":"b59449401ef30240b76f2549d4d1758fd19de10c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"2ede9cc17d369e75f707dd114041b66bf0891193","unresolved":true,"context_lines":[{"line_number":656,"context_line":"        empty_pid_stats[key] \u003d {}"},{"line_number":657,"context_line":"        for stat, value in stats.items():"},{"line_number":658,"context_line":"            if stat \u003d\u003d \u0027policies\u0027:"},{"line_number":659,"context_line":"                if stat in collated_stats:"},{"line_number":660,"context_line":"                    collated_stats[stat] \u003d max(value, collated_stats[stat])"},{"line_number":661,"context_line":"                else:"},{"line_number":662,"context_line":"                    collated_stats[stat] \u003d value"},{"line_number":663,"context_line":"            else:"},{"line_number":664,"context_line":"                collated_stats.setdefault(stat, 0)"},{"line_number":665,"context_line":"                collated_stats[stat] +\u003d value"},{"line_number":666,"context_line":"    return collated_stats, empty_pid_stats"}],"source_content_type":"text/x-python","patch_set":21,"id":"6b6b6a19_4bd116a5","line":663,"range":{"start_line":659,"start_character":0,"end_line":663,"end_character":2},"updated":"2021-04-12 14:05:10.000000000","message":"or\n\n  collated_stats[stat] \u003d max(value, collated_stats.get(stat, 0)","commit_id":"b59449401ef30240b76f2549d4d1758fd19de10c"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"11a6e0129499176e513575ea5e1cdea6d15c690f","unresolved":true,"context_lines":[{"line_number":656,"context_line":"        empty_pid_stats[key] \u003d {}"},{"line_number":657,"context_line":"        for stat, value in stats.items():"},{"line_number":658,"context_line":"            if stat \u003d\u003d \u0027policies\u0027:"},{"line_number":659,"context_line":"                if stat in collated_stats:"},{"line_number":660,"context_line":"                    collated_stats[stat] \u003d max(value, collated_stats[stat])"},{"line_number":661,"context_line":"                else:"},{"line_number":662,"context_line":"                    collated_stats[stat] \u003d value"},{"line_number":663,"context_line":"            else:"},{"line_number":664,"context_line":"                collated_stats.setdefault(stat, 0)"},{"line_number":665,"context_line":"                collated_stats[stat] +\u003d value"},{"line_number":666,"context_line":"    return collated_stats, empty_pid_stats"}],"source_content_type":"text/x-python","patch_set":21,"id":"359e54b5_8a7a3e56","line":663,"range":{"start_line":659,"start_character":0,"end_line":663,"end_character":2},"in_reply_to":"1c27e090_70666e99","updated":"2021-04-13 07:27:57.000000000","message":"oh yeah, this is much better.","commit_id":"b59449401ef30240b76f2549d4d1758fd19de10c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"dd5851baecf6f69ab7c7c026ca192545cd401233","unresolved":true,"context_lines":[{"line_number":656,"context_line":"        empty_pid_stats[key] \u003d {}"},{"line_number":657,"context_line":"        for stat, value in stats.items():"},{"line_number":658,"context_line":"            if stat \u003d\u003d \u0027policies\u0027:"},{"line_number":659,"context_line":"                if stat in collated_stats:"},{"line_number":660,"context_line":"                    collated_stats[stat] \u003d max(value, collated_stats[stat])"},{"line_number":661,"context_line":"                else:"},{"line_number":662,"context_line":"                    collated_stats[stat] \u003d value"},{"line_number":663,"context_line":"            else:"},{"line_number":664,"context_line":"                collated_stats.setdefault(stat, 0)"},{"line_number":665,"context_line":"                collated_stats[stat] +\u003d value"},{"line_number":666,"context_line":"    return collated_stats, empty_pid_stats"}],"source_content_type":"text/x-python","patch_set":21,"id":"6d672b71_850b30c3","line":663,"range":{"start_line":659,"start_character":0,"end_line":663,"end_character":2},"in_reply_to":"6b6b6a19_4bd116a5","updated":"2021-04-12 16:38:37.000000000","message":"also, this isn\u0027t covered by unit tests","commit_id":"b59449401ef30240b76f2549d4d1758fd19de10c"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"d8082da3c12499c10f02ad356a23e51bbccc71f2","unresolved":true,"context_lines":[{"line_number":656,"context_line":"        empty_pid_stats[key] \u003d {}"},{"line_number":657,"context_line":"        for stat, value in stats.items():"},{"line_number":658,"context_line":"            if stat \u003d\u003d \u0027policies\u0027:"},{"line_number":659,"context_line":"                if stat in collated_stats:"},{"line_number":660,"context_line":"                    collated_stats[stat] \u003d max(value, collated_stats[stat])"},{"line_number":661,"context_line":"                else:"},{"line_number":662,"context_line":"                    collated_stats[stat] \u003d value"},{"line_number":663,"context_line":"            else:"},{"line_number":664,"context_line":"                collated_stats.setdefault(stat, 0)"},{"line_number":665,"context_line":"                collated_stats[stat] +\u003d value"},{"line_number":666,"context_line":"    return collated_stats, empty_pid_stats"}],"source_content_type":"text/x-python","patch_set":21,"id":"1c27e090_70666e99","line":663,"range":{"start_line":659,"start_character":0,"end_line":663,"end_character":2},"in_reply_to":"6d672b71_850b30c3","updated":"2021-04-13 03:40:41.000000000","message":"yeah sorry, this is new... though that isn\u0027t a good reason 😊\n\nwe want some stats to sum and things like policies to max.","commit_id":"b59449401ef30240b76f2549d4d1758fd19de10c"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"b7f0e3b8e061e83404a86140b60364d63a058c0e","unresolved":true,"context_lines":[{"line_number":268,"context_line":"        num_total_parts \u003d len(self.states[\"state\"])"},{"line_number":269,"context_line":"        self.logger.info(\"Step: %s Device: %s Policy: %s Partitions: %d/%d\" % ("},{"line_number":270,"context_line":"            step, device, self.policy.name, num_parts_done, num_total_parts))"},{"line_number":271,"context_line":"        self._update_recon(device, self.device_stats)"},{"line_number":272,"context_line":""},{"line_number":273,"context_line":"    def hashes_filter(self, suff_path, hashes):"},{"line_number":274,"context_line":"        hashes \u003d list(hashes)"}],"source_content_type":"text/x-python","patch_set":24,"id":"5e0484a2_b77e78ae","line":271,"updated":"2021-04-14 18:21:26.000000000","message":"updating every partition is quite frequent... I think an internal last_update time and configurable interval (default 10-30s) would be a big improvement.","commit_id":"5b355b34ab8c457b2f09734e3a5a6a17330932c9"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"7bdcdb4b282a182ee34e3255b184530551f59485","unresolved":false,"context_lines":[{"line_number":268,"context_line":"        num_total_parts \u003d len(self.states[\"state\"])"},{"line_number":269,"context_line":"        self.logger.info(\"Step: %s Device: %s Policy: %s Partitions: %d/%d\" % ("},{"line_number":270,"context_line":"            step, device, self.policy.name, num_parts_done, num_total_parts))"},{"line_number":271,"context_line":"        self._update_recon(device, self.device_stats)"},{"line_number":272,"context_line":""},{"line_number":273,"context_line":"    def hashes_filter(self, suff_path, hashes):"},{"line_number":274,"context_line":"        hashes \u003d list(hashes)"}],"source_content_type":"text/x-python","patch_set":24,"id":"0490ef11_b65aabb2","line":271,"in_reply_to":"0dd261f6_05401df3","updated":"2021-04-15 07:15:32.000000000","message":"Done","commit_id":"5b355b34ab8c457b2f09734e3a5a6a17330932c9"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"ca40c1e251085b6cad9625dfa1d6017000161e69","unresolved":true,"context_lines":[{"line_number":268,"context_line":"        num_total_parts \u003d len(self.states[\"state\"])"},{"line_number":269,"context_line":"        self.logger.info(\"Step: %s Device: %s Policy: %s Partitions: %d/%d\" % ("},{"line_number":270,"context_line":"            step, device, self.policy.name, num_parts_done, num_total_parts))"},{"line_number":271,"context_line":"        self._update_recon(device, self.device_stats)"},{"line_number":272,"context_line":""},{"line_number":273,"context_line":"    def hashes_filter(self, suff_path, hashes):"},{"line_number":274,"context_line":"        hashes \u003d list(hashes)"}],"source_content_type":"text/x-python","patch_set":24,"id":"0dd261f6_05401df3","line":271,"in_reply_to":"5e0484a2_b77e78ae","updated":"2021-04-14 23:36:21.000000000","message":"+1 thanks for the follow up, I\u0027ll suqash it in. Thanks!","commit_id":"5b355b34ab8c457b2f09734e3a5a6a17330932c9"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"b7f0e3b8e061e83404a86140b60364d63a058c0e","unresolved":true,"context_lines":[{"line_number":564,"context_line":"        ring \u003d pol.object_ring"},{"line_number":565,"context_line":""},{"line_number":566,"context_line":"        if device_list:"},{"line_number":567,"context_line":"            # only reset for the given devices we\u0027re working on"},{"line_number":568,"context_line":"            policy_data \u003d {d: {} for d in device_list}"},{"line_number":569,"context_line":"            policy_data[\u0027part_power\u0027] \u003d ring.part_power"},{"line_number":570,"context_line":"            policy_data[\u0027next_part_power\u0027] \u003d ring.next_part_power"}],"source_content_type":"text/x-python","patch_set":24,"id":"cec5388b_b0aa261e","line":567,"updated":"2021-04-14 18:21:26.000000000","message":"if a device gets removed from the ring (or formatted and relabled) - will the last stats it generated be left in the recon file forever?","commit_id":"5b355b34ab8c457b2f09734e3a5a6a17330932c9"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"ca40c1e251085b6cad9625dfa1d6017000161e69","unresolved":true,"context_lines":[{"line_number":564,"context_line":"        ring \u003d pol.object_ring"},{"line_number":565,"context_line":""},{"line_number":566,"context_line":"        if device_list:"},{"line_number":567,"context_line":"            # only reset for the given devices we\u0027re working on"},{"line_number":568,"context_line":"            policy_data \u003d {d: {} for d in device_list}"},{"line_number":569,"context_line":"            policy_data[\u0027part_power\u0027] \u003d ring.part_power"},{"line_number":570,"context_line":"            policy_data[\u0027next_part_power\u0027] \u003d ring.next_part_power"}],"source_content_type":"text/x-python","patch_set":24,"id":"5a68bea5_29e4c374","line":567,"in_reply_to":"cec5388b_b0aa261e","updated":"2021-04-14 23:36:21.000000000","message":"oh, that\u0027s a great question. With the ability to just pick a single device I didn\u0027t want to nuke old stats because maybe your re-running it on a single device. But yeah, I guess the flip side to this is what you say.\nThey\u0027d at least have old timestamps in them. So options are:\n\n  - We expect to nuke the old run (or move it) each time. That\u0027s simpler code; or\n  - add some kind of recliam here and clean up old timestamped data based of age?","commit_id":"5b355b34ab8c457b2f09734e3a5a6a17330932c9"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"b7f0e3b8e061e83404a86140b60364d63a058c0e","unresolved":true,"context_lines":[{"line_number":571,"context_line":"            device_progress_recon[progress_str] \u003d policy_data"},{"line_number":572,"context_line":"        else:"},{"line_number":573,"context_line":"            # reset all for devices for the policy"},{"line_number":574,"context_line":"            # setting the whole progress to {} will clear it all."},{"line_number":575,"context_line":"            clr_progress_recon \u003d {"},{"line_number":576,"context_line":"                progress_str: {}}"},{"line_number":577,"context_line":"            dump_recon_cache(clr_progress_recon, recon_cache, logger)"}],"source_content_type":"text/x-python","patch_set":24,"id":"1348031e_cb9b2402","line":574,"updated":"2021-04-14 18:21:26.000000000","message":"AFAIK _reset_recon is only called at the start of a new run\n\nI think we should always clear the dump from the last \"cycle\" (or move it under a different \"relinker_previous_run\" key)","commit_id":"5b355b34ab8c457b2f09734e3a5a6a17330932c9"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"ca40c1e251085b6cad9625dfa1d6017000161e69","unresolved":true,"context_lines":[{"line_number":571,"context_line":"            device_progress_recon[progress_str] \u003d policy_data"},{"line_number":572,"context_line":"        else:"},{"line_number":573,"context_line":"            # reset all for devices for the policy"},{"line_number":574,"context_line":"            # setting the whole progress to {} will clear it all."},{"line_number":575,"context_line":"            clr_progress_recon \u003d {"},{"line_number":576,"context_line":"                progress_str: {}}"},{"line_number":577,"context_line":"            dump_recon_cache(clr_progress_recon, recon_cache, logger)"}],"source_content_type":"text/x-python","patch_set":24,"id":"06b92980_3995959f","line":574,"in_reply_to":"1348031e_cb9b2402","updated":"2021-04-14 23:36:21.000000000","message":"oh I see, but we have to be careful how deep that gets.. though on the otherhand we\u0027re never going to be indivdually be updating it, so deepness isn\u0027t really an issue. So maybe have a:\n\n {\n     \u0027progress\u0027:{...},\n     \u0027progress-1\u0027: {...},\n     \u0027stats\u0027: {...},\n      ...\n     \u0027previous_run\u0027: { \u003cold recon data (minus it\u0027s previous run)\u003e }\n }\n\nThat seems simpler to code and you\u0027d still have access to the last run. I guess the question is, I\u0027m I thinking too hard about the last run at all, do we need it?","commit_id":"5b355b34ab8c457b2f09734e3a5a6a17330932c9"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"b7f0e3b8e061e83404a86140b60364d63a058c0e","unresolved":true,"context_lines":[{"line_number":578,"context_line":"            # new just set to part_power/next_part_power"},{"line_number":579,"context_line":"            device_progress_recon[progress_str] \u003d {"},{"line_number":580,"context_line":"                \u0027part_power\u0027: ring.part_power,"},{"line_number":581,"context_line":"                \u0027next_part_power\u0027: ring.next_part_power}"},{"line_number":582,"context_line":"    dump_recon_cache(device_progress_recon, recon_cache, logger)"},{"line_number":583,"context_line":""},{"line_number":584,"context_line":""}],"source_content_type":"text/x-python","patch_set":24,"id":"a39d462e_5fb10539","line":581,"updated":"2021-04-14 18:21:26.000000000","message":"i found this little bit super helpful to keep track of what was going on","commit_id":"5b355b34ab8c457b2f09734e3a5a6a17330932c9"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"b7f0e3b8e061e83404a86140b60364d63a058c0e","unresolved":true,"context_lines":[{"line_number":614,"context_line":""},{"line_number":615,"context_line":"    # start collate stat process, if you start it with workers is 0 then we"},{"line_number":616,"context_line":"    # wont run the collate_pid. It makes it easier to debug."},{"line_number":617,"context_line":"    collate_pid \u003d os.fork()"},{"line_number":618,"context_line":"    if collate_pid \u003d\u003d 0:"},{"line_number":619,"context_line":"        os._exit(collate_stats_proc(recon_cache))"},{"line_number":620,"context_line":""}],"source_content_type":"text/x-python","patch_set":24,"id":"62f21e12_4b6ef719","line":617,"updated":"2021-04-14 18:21:26.000000000","message":"I\u0027m fine with this\n\nstarting up a whole process to collate stats seems heavy-weight - but better than trying to fork after kicking up some greenthreads and getting the hub started then trying to \"green\" the calls to os.wait()","commit_id":"5b355b34ab8c457b2f09734e3a5a6a17330932c9"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"ca40c1e251085b6cad9625dfa1d6017000161e69","unresolved":true,"context_lines":[{"line_number":614,"context_line":""},{"line_number":615,"context_line":"    # start collate stat process, if you start it with workers is 0 then we"},{"line_number":616,"context_line":"    # wont run the collate_pid. It makes it easier to debug."},{"line_number":617,"context_line":"    collate_pid \u003d os.fork()"},{"line_number":618,"context_line":"    if collate_pid \u003d\u003d 0:"},{"line_number":619,"context_line":"        os._exit(collate_stats_proc(recon_cache))"},{"line_number":620,"context_line":""}],"source_content_type":"text/x-python","patch_set":24,"id":"0e8cf55b_fc6b636f","line":617,"in_reply_to":"62f21e12_4b6ef719","updated":"2021-04-14 23:36:21.000000000","message":"yeah, Tim seemed to go out of his way to avoid green threads and instead when down the fork route. I didn\u0027t want to mix the threading/mutli-processing methodology that was being used.","commit_id":"5b355b34ab8c457b2f09734e3a5a6a17330932c9"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"b7f0e3b8e061e83404a86140b60364d63a058c0e","unresolved":true,"context_lines":[{"line_number":693,"context_line":"            else:"},{"line_number":694,"context_line":"                collated_stats.setdefault(stat, 0)"},{"line_number":695,"context_line":"                collated_stats[stat] +\u003d value"},{"line_number":696,"context_line":"    return collated_stats"},{"line_number":697,"context_line":""},{"line_number":698,"context_line":""},{"line_number":699,"context_line":"def main(args):"}],"source_content_type":"text/x-python","patch_set":24,"id":"b06b794f_77f94562","line":696,"updated":"2021-04-14 18:21:26.000000000","message":"please consider re-organizing the text in this file so these function defintions appear BEFORE the call sites.","commit_id":"5b355b34ab8c457b2f09734e3a5a6a17330932c9"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"ca40c1e251085b6cad9625dfa1d6017000161e69","unresolved":true,"context_lines":[{"line_number":693,"context_line":"            else:"},{"line_number":694,"context_line":"                collated_stats.setdefault(stat, 0)"},{"line_number":695,"context_line":"                collated_stats[stat] +\u003d value"},{"line_number":696,"context_line":"    return collated_stats"},{"line_number":697,"context_line":""},{"line_number":698,"context_line":""},{"line_number":699,"context_line":"def main(args):"}],"source_content_type":"text/x-python","patch_set":24,"id":"70e5cef0_6dfdb2be","line":696,"in_reply_to":"b06b794f_77f94562","updated":"2021-04-14 23:36:21.000000000","message":"oh yeah good call.","commit_id":"5b355b34ab8c457b2f09734e3a5a6a17330932c9"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"b7f0e3b8e061e83404a86140b60364d63a058c0e","unresolved":true,"context_lines":[{"line_number":741,"context_line":"                             \u0027inode in the next partition power location \u0027"},{"line_number":742,"context_line":"                             \u0027(default: 2).\u0027)"},{"line_number":743,"context_line":"    parser.add_argument(\"--recon-cache-path\", default\u003dNone,"},{"line_number":744,"context_line":"                        help\u003d\u0027Set the path to the recon cache directory\u0027)"},{"line_number":745,"context_line":""},{"line_number":746,"context_line":"    args \u003d parser.parse_args(args)"},{"line_number":747,"context_line":"    if args.conf_file:"}],"source_content_type":"text/x-python","patch_set":24,"id":"8ffb01bc_d2e88b3d","line":744,"updated":"2021-04-14 18:21:26.000000000","message":"can we NOT expose this option on the command line?","commit_id":"5b355b34ab8c457b2f09734e3a5a6a17330932c9"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"ca40c1e251085b6cad9625dfa1d6017000161e69","unresolved":true,"context_lines":[{"line_number":741,"context_line":"                             \u0027inode in the next partition power location \u0027"},{"line_number":742,"context_line":"                             \u0027(default: 2).\u0027)"},{"line_number":743,"context_line":"    parser.add_argument(\"--recon-cache-path\", default\u003dNone,"},{"line_number":744,"context_line":"                        help\u003d\u0027Set the path to the recon cache directory\u0027)"},{"line_number":745,"context_line":""},{"line_number":746,"context_line":"    args \u003d parser.parse_args(args)"},{"line_number":747,"context_line":"    if args.conf_file:"}],"source_content_type":"text/x-python","patch_set":24,"id":"0ae66fb7_4a676dd0","line":744,"in_reply_to":"8ffb01bc_d2e88b3d","updated":"2021-04-14 23:36:21.000000000","message":"Fair enough, I\u0027ve been using it my saio testing.. but I guess I could just as easy start using the config for each node which should point correctly to the right place as its not the default path.","commit_id":"5b355b34ab8c457b2f09734e3a5a6a17330932c9"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"b7f0e3b8e061e83404a86140b60364d63a058c0e","unresolved":true,"context_lines":[{"line_number":752,"context_line":"        if user:"},{"line_number":753,"context_line":"            drop_privileges(user)"},{"line_number":754,"context_line":"        logger \u003d get_logger(conf)"},{"line_number":755,"context_line":"    else:"},{"line_number":756,"context_line":"        conf \u003d {\u0027log_level\u0027: \u0027DEBUG\u0027 if args.debug else \u0027INFO\u0027}"},{"line_number":757,"context_line":"        if args.user:"},{"line_number":758,"context_line":"            # Drop privs before creating log file"}],"source_content_type":"text/x-python","patch_set":24,"id":"e5574603_79b52eab","line":755,"updated":"2021-04-14 18:21:26.000000000","message":"maybe explicitly set recon_cache_path to False and disable it unless you\u0027re using a config","commit_id":"5b355b34ab8c457b2f09734e3a5a6a17330932c9"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"b7f0e3b8e061e83404a86140b60364d63a058c0e","unresolved":true,"context_lines":[{"line_number":765,"context_line":"        logger \u003d logging.getLogger()"},{"line_number":766,"context_line":""},{"line_number":767,"context_line":"    recon_cache_path \u003d (args.recon_cache_path or"},{"line_number":768,"context_line":"                        conf.get(\u0027recon_cache_path\u0027, \u0027/var/cache/swift\u0027))"},{"line_number":769,"context_line":""},{"line_number":770,"context_line":"    conf.update({"},{"line_number":771,"context_line":"        \u0027swift_dir\u0027: args.swift_dir or conf.get(\u0027swift_dir\u0027, \u0027/etc/swift\u0027),"}],"source_content_type":"text/x-python","patch_set":24,"id":"4536cecc_329054d2","line":768,"updated":"2021-04-14 18:21:26.000000000","message":"we need to add this option to the relinker section of the sample config","commit_id":"5b355b34ab8c457b2f09734e3a5a6a17330932c9"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"66c41dfad6399d1bdbebbad80b02487aa14062a0","unresolved":true,"context_lines":[{"line_number":436,"context_line":"                self.logger.warning("},{"line_number":437,"context_line":"                    \u0027Error invalidating suffix for %s: %r\u0027,"},{"line_number":438,"context_line":"                    hash_path, exc)"},{"line_number":439,"context_line":"        # dump stats to recon"},{"line_number":440,"context_line":"        stats \u003d dict(timestamp\u003dtime.time(), **self.stats)"},{"line_number":441,"context_line":"        dump_recon_cache({\u0027stats\u0027: {"},{"line_number":442,"context_line":"            \u0027stats_{}\u0027.format(os.getpid()): stats}},"},{"line_number":443,"context_line":"            self.recon_cache, self.logger)"},{"line_number":444,"context_line":""},{"line_number":445,"context_line":"    def _update_recon(self, device, extra_stats, force_dump\u003dFalse):"},{"line_number":446,"context_line":"        if not force_dump and self._last_recon_update + self.recon_interval \\"},{"line_number":447,"context_line":"                \u003e time.time():"}],"source_content_type":"text/x-python","patch_set":25,"id":"5a7978fd_5d2dd0e2","line":444,"range":{"start_line":439,"start_character":1,"end_line":444,"end_character":0},"updated":"2021-04-16 18:31:32.000000000","message":"this is being written after every object is linked/cleaned up? shouldn\u0027t it be part of _update_recon and written less frequently?","commit_id":"aad814e5163dbc8843adce04d120be6b558a0124"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"d1a256b8635bd3c4f575aaaa6e009bb0d47c1eab","unresolved":true,"context_lines":[{"line_number":436,"context_line":"                self.logger.warning("},{"line_number":437,"context_line":"                    \u0027Error invalidating suffix for %s: %r\u0027,"},{"line_number":438,"context_line":"                    hash_path, exc)"},{"line_number":439,"context_line":"        # dump stats to recon"},{"line_number":440,"context_line":"        stats \u003d dict(timestamp\u003dtime.time(), **self.stats)"},{"line_number":441,"context_line":"        dump_recon_cache({\u0027stats\u0027: {"},{"line_number":442,"context_line":"            \u0027stats_{}\u0027.format(os.getpid()): stats}},"},{"line_number":443,"context_line":"            self.recon_cache, self.logger)"},{"line_number":444,"context_line":""},{"line_number":445,"context_line":"    def _update_recon(self, device, extra_stats, force_dump\u003dFalse):"},{"line_number":446,"context_line":"        if not force_dump and self._last_recon_update + self.recon_interval \\"},{"line_number":447,"context_line":"                \u003e time.time():"}],"source_content_type":"text/x-python","patch_set":25,"id":"7b9b0406_099971b9","line":444,"range":{"start_line":439,"start_character":1,"end_line":444,"end_character":0},"in_reply_to":"5a7978fd_5d2dd0e2","updated":"2021-04-19 03:01:24.000000000","message":"yeah good idea!\n\nDone","commit_id":"aad814e5163dbc8843adce04d120be6b558a0124"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"66c41dfad6399d1bdbebbad80b02487aa14062a0","unresolved":true,"context_lines":[{"line_number":442,"context_line":"            \u0027stats_{}\u0027.format(os.getpid()): stats}},"},{"line_number":443,"context_line":"            self.recon_cache, self.logger)"},{"line_number":444,"context_line":""},{"line_number":445,"context_line":"    def _update_recon(self, device, extra_stats, force_dump\u003dFalse):"},{"line_number":446,"context_line":"        if not force_dump and self._last_recon_update + self.recon_interval \\"},{"line_number":447,"context_line":"                \u003e time.time():"},{"line_number":448,"context_line":"            # not time yet!"}],"source_content_type":"text/x-python","patch_set":25,"id":"1a3503f9_2ccd2440","line":445,"updated":"2021-04-16 18:31:32.000000000","message":"pls move this method above call sites in the file","commit_id":"aad814e5163dbc8843adce04d120be6b558a0124"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"d1a256b8635bd3c4f575aaaa6e009bb0d47c1eab","unresolved":false,"context_lines":[{"line_number":442,"context_line":"            \u0027stats_{}\u0027.format(os.getpid()): stats}},"},{"line_number":443,"context_line":"            self.recon_cache, self.logger)"},{"line_number":444,"context_line":""},{"line_number":445,"context_line":"    def _update_recon(self, device, extra_stats, force_dump\u003dFalse):"},{"line_number":446,"context_line":"        if not force_dump and self._last_recon_update + self.recon_interval \\"},{"line_number":447,"context_line":"                \u003e time.time():"},{"line_number":448,"context_line":"            # not time yet!"}],"source_content_type":"text/x-python","patch_set":25,"id":"8a8a8744_efc63873","line":445,"in_reply_to":"1a3503f9_2ccd2440","updated":"2021-04-19 03:01:24.000000000","message":"Done","commit_id":"aad814e5163dbc8843adce04d120be6b558a0124"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"66c41dfad6399d1bdbebbad80b02487aa14062a0","unresolved":true,"context_lines":[{"line_number":586,"context_line":"            clr_progress_recon \u003d {"},{"line_number":587,"context_line":"                progress_str: {}}"},{"line_number":588,"context_line":"            dump_recon_cache(clr_progress_recon, recon_cache, logger)"},{"line_number":589,"context_line":"            # new just set to part_power/next_part_power"},{"line_number":590,"context_line":"            device_progress_recon[progress_str] \u003d {"},{"line_number":591,"context_line":"                \u0027part_power\u0027: ring.part_power,"},{"line_number":592,"context_line":"                \u0027next_part_power\u0027: ring.next_part_power}"}],"source_content_type":"text/x-python","patch_set":25,"id":"48734377_84f753dd","line":589,"range":{"start_line":589,"start_character":14,"end_line":589,"end_character":17},"updated":"2021-04-16 18:31:32.000000000","message":"nit: s/new/now/ ?","commit_id":"aad814e5163dbc8843adce04d120be6b558a0124"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"d1a256b8635bd3c4f575aaaa6e009bb0d47c1eab","unresolved":false,"context_lines":[{"line_number":586,"context_line":"            clr_progress_recon \u003d {"},{"line_number":587,"context_line":"                progress_str: {}}"},{"line_number":588,"context_line":"            dump_recon_cache(clr_progress_recon, recon_cache, logger)"},{"line_number":589,"context_line":"            # new just set to part_power/next_part_power"},{"line_number":590,"context_line":"            device_progress_recon[progress_str] \u003d {"},{"line_number":591,"context_line":"                \u0027part_power\u0027: ring.part_power,"},{"line_number":592,"context_line":"                \u0027next_part_power\u0027: ring.next_part_power}"}],"source_content_type":"text/x-python","patch_set":25,"id":"188add7f_0aa20989","line":589,"range":{"start_line":589,"start_character":14,"end_line":589,"end_character":17},"in_reply_to":"48734377_84f753dd","updated":"2021-04-19 03:01:24.000000000","message":"Done","commit_id":"aad814e5163dbc8843adce04d120be6b558a0124"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"72285f28b456a777ac294144368935a51eed88ce","unresolved":true,"context_lines":[{"line_number":590,"context_line":"            device_progress_recon[progress_str] \u003d {"},{"line_number":591,"context_line":"                \u0027part_power\u0027: ring.part_power,"},{"line_number":592,"context_line":"                \u0027next_part_power\u0027: ring.next_part_power}"},{"line_number":593,"context_line":"    dump_recon_cache(device_progress_recon, recon_cache, logger)"},{"line_number":594,"context_line":""},{"line_number":595,"context_line":""},{"line_number":596,"context_line":"def _collate_stats(recon_stats):"}],"source_content_type":"text/x-python","patch_set":25,"id":"b783470f_51fee887","line":593,"updated":"2021-04-15 07:23:49.000000000","message":"Still haven\u0027t decided what to do here, look at the discussion in the earlier patchset. Maybe I\u0027m trying to hard to keep older data. In this patchet I\u0027m just truggering the else statement (that is clear all data).","commit_id":"aad814e5163dbc8843adce04d120be6b558a0124"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"66c41dfad6399d1bdbebbad80b02487aa14062a0","unresolved":true,"context_lines":[{"line_number":593,"context_line":"    dump_recon_cache(device_progress_recon, recon_cache, logger)"},{"line_number":594,"context_line":""},{"line_number":595,"context_line":""},{"line_number":596,"context_line":"def _collate_stats(recon_stats):"},{"line_number":597,"context_line":"    collated_stats \u003d {}"},{"line_number":598,"context_line":"    for key, stats in recon_stats.items():"},{"line_number":599,"context_line":"        if not key.startswith(\u0027stats_\u0027):"}],"source_content_type":"text/x-python","patch_set":25,"id":"fd429016_0a87a545","line":596,"range":{"start_line":596,"start_character":4,"end_line":596,"end_character":18},"updated":"2021-04-16 18:31:32.000000000","message":"nit: could this be _collate_per_worker_stats","commit_id":"aad814e5163dbc8843adce04d120be6b558a0124"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"d1a256b8635bd3c4f575aaaa6e009bb0d47c1eab","unresolved":false,"context_lines":[{"line_number":593,"context_line":"    dump_recon_cache(device_progress_recon, recon_cache, logger)"},{"line_number":594,"context_line":""},{"line_number":595,"context_line":""},{"line_number":596,"context_line":"def _collate_stats(recon_stats):"},{"line_number":597,"context_line":"    collated_stats \u003d {}"},{"line_number":598,"context_line":"    for key, stats in recon_stats.items():"},{"line_number":599,"context_line":"        if not key.startswith(\u0027stats_\u0027):"}],"source_content_type":"text/x-python","patch_set":25,"id":"432d4eb2_44c8d290","line":596,"range":{"start_line":596,"start_character":4,"end_line":596,"end_character":18},"in_reply_to":"fd429016_0a87a545","updated":"2021-04-19 03:01:24.000000000","message":"Done","commit_id":"aad814e5163dbc8843adce04d120be6b558a0124"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"66c41dfad6399d1bdbebbad80b02487aa14062a0","unresolved":true,"context_lines":[{"line_number":607,"context_line":"    return collated_stats"},{"line_number":608,"context_line":""},{"line_number":609,"context_line":""},{"line_number":610,"context_line":"def _collate_device_stats(recon_stats):"},{"line_number":611,"context_line":"    collated_stats \u003d {}"},{"line_number":612,"context_line":"    DEV_STAT_MAP \u003d {\u0027timestamp\u0027: \u0027timestamp\u0027,"},{"line_number":613,"context_line":"                    \u0027total_parts\u0027: \u0027discovered_parts\u0027,"}],"source_content_type":"text/x-python","patch_set":25,"id":"ea751acd_182bf504","line":610,"range":{"start_line":610,"start_character":4,"end_line":610,"end_character":25},"updated":"2021-04-16 18:31:32.000000000","message":"nit: ...and could this be _collate_per_policy_stats","commit_id":"aad814e5163dbc8843adce04d120be6b558a0124"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"d1a256b8635bd3c4f575aaaa6e009bb0d47c1eab","unresolved":false,"context_lines":[{"line_number":607,"context_line":"    return collated_stats"},{"line_number":608,"context_line":""},{"line_number":609,"context_line":""},{"line_number":610,"context_line":"def _collate_device_stats(recon_stats):"},{"line_number":611,"context_line":"    collated_stats \u003d {}"},{"line_number":612,"context_line":"    DEV_STAT_MAP \u003d {\u0027timestamp\u0027: \u0027timestamp\u0027,"},{"line_number":613,"context_line":"                    \u0027total_parts\u0027: \u0027discovered_parts\u0027,"}],"source_content_type":"text/x-python","patch_set":25,"id":"85b0aa2b_14c20f79","line":610,"range":{"start_line":610,"start_character":4,"end_line":610,"end_character":25},"in_reply_to":"ea751acd_182bf504","updated":"2021-04-19 03:01:24.000000000","message":"Done","commit_id":"aad814e5163dbc8843adce04d120be6b558a0124"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"72285f28b456a777ac294144368935a51eed88ce","unresolved":true,"context_lines":[{"line_number":612,"context_line":"    DEV_STAT_MAP \u003d {\u0027timestamp\u0027: \u0027timestamp\u0027,"},{"line_number":613,"context_line":"                    \u0027total_parts\u0027: \u0027discovered_parts\u0027,"},{"line_number":614,"context_line":"                    \u0027parts_done\u0027: \u0027parts_done\u0027,"},{"line_number":615,"context_line":"                    \u0027total_time\u0027: \u0027total_combined_time\u0027}"},{"line_number":616,"context_line":"    for key, stats in recon_stats.items():"},{"line_number":617,"context_line":"        if not isinstance(stats, dict) or key \u003d\u003d \u0027aggregate\u0027:"},{"line_number":618,"context_line":"            continue"}],"source_content_type":"text/x-python","patch_set":25,"id":"aa5497c7_dd377e76","line":615,"updated":"2021-04-15 07:23:49.000000000","message":"Thought that so long as we are aggregating device stats it might be interesting to know the total_combined_time. That is how much time it took (if it wasn\u0027t done in parallel).","commit_id":"aad814e5163dbc8843adce04d120be6b558a0124"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"66c41dfad6399d1bdbebbad80b02487aa14062a0","unresolved":true,"context_lines":[{"line_number":612,"context_line":"    DEV_STAT_MAP \u003d {\u0027timestamp\u0027: \u0027timestamp\u0027,"},{"line_number":613,"context_line":"                    \u0027total_parts\u0027: \u0027discovered_parts\u0027,"},{"line_number":614,"context_line":"                    \u0027parts_done\u0027: \u0027parts_done\u0027,"},{"line_number":615,"context_line":"                    \u0027total_time\u0027: \u0027total_combined_time\u0027}"},{"line_number":616,"context_line":"    for key, stats in recon_stats.items():"},{"line_number":617,"context_line":"        if not isinstance(stats, dict) or key \u003d\u003d \u0027aggregate\u0027:"},{"line_number":618,"context_line":"            continue"}],"source_content_type":"text/x-python","patch_set":25,"id":"ac052fec_40710e80","line":615,"in_reply_to":"aa5497c7_dd377e76","updated":"2021-04-16 18:31:32.000000000","message":"see my comment in test_relinker: I\u0027d prefer it without the key renaming","commit_id":"aad814e5163dbc8843adce04d120be6b558a0124"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"66c41dfad6399d1bdbebbad80b02487aa14062a0","unresolved":true,"context_lines":[{"line_number":614,"context_line":"                    \u0027parts_done\u0027: \u0027parts_done\u0027,"},{"line_number":615,"context_line":"                    \u0027total_time\u0027: \u0027total_combined_time\u0027}"},{"line_number":616,"context_line":"    for key, stats in recon_stats.items():"},{"line_number":617,"context_line":"        if not isinstance(stats, dict) or key \u003d\u003d \u0027aggregate\u0027:"},{"line_number":618,"context_line":"            continue"},{"line_number":619,"context_line":""},{"line_number":620,"context_line":"        for d_stat, d_value in stats.items():"}],"source_content_type":"text/x-python","patch_set":25,"id":"428899ea_6597cd93","line":617,"range":{"start_line":617,"start_character":8,"end_line":617,"end_character":61},"updated":"2021-04-16 18:31:32.000000000","message":"somewhere we must have a device_list against which we could check keys?? or maybe not if we run relinker with default all devices? :/\n\njust seems a shame to prohibit any other dict ever being added under the policy\n\nwe could add a \u0027device\u0027: \u0027sda1\u0027 item to the per-device dict so that here you can query \n\n  if not \u0027device\u0027 in stats:\n      continue","commit_id":"aad814e5163dbc8843adce04d120be6b558a0124"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"d1a256b8635bd3c4f575aaaa6e009bb0d47c1eab","unresolved":true,"context_lines":[{"line_number":614,"context_line":"                    \u0027parts_done\u0027: \u0027parts_done\u0027,"},{"line_number":615,"context_line":"                    \u0027total_time\u0027: \u0027total_combined_time\u0027}"},{"line_number":616,"context_line":"    for key, stats in recon_stats.items():"},{"line_number":617,"context_line":"        if not isinstance(stats, dict) or key \u003d\u003d \u0027aggregate\u0027:"},{"line_number":618,"context_line":"            continue"},{"line_number":619,"context_line":""},{"line_number":620,"context_line":"        for d_stat, d_value in stats.items():"}],"source_content_type":"text/x-python","patch_set":25,"id":"5499333a_3b8600d4","line":617,"range":{"start_line":617,"start_character":8,"end_line":617,"end_character":61},"in_reply_to":"428899ea_6597cd93","updated":"2021-04-19 03:01:24.000000000","message":"interesting idea. Maybe this can be a part of the structure/naming recon dissussion at the PTG this week 😊","commit_id":"aad814e5163dbc8843adce04d120be6b558a0124"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"66c41dfad6399d1bdbebbad80b02487aa14062a0","unresolved":true,"context_lines":[{"line_number":648,"context_line":""},{"line_number":649,"context_line":"def collate_stats_proc(recon_cache, logger, interval):"},{"line_number":650,"context_line":"    while True:"},{"line_number":651,"context_line":"        time.sleep(interval)"},{"line_number":652,"context_line":"        stats \u003d collate_stats(recon_cache)"},{"line_number":653,"context_line":"        dump_recon_cache(stats, recon_cache, logger)"},{"line_number":654,"context_line":""}],"source_content_type":"text/x-python","patch_set":25,"id":"31d73842_27837bd8","line":651,"range":{"start_line":651,"start_character":19,"end_line":651,"end_character":27},"updated":"2021-04-16 18:31:32.000000000","message":"need to validate that interval is non-negative","commit_id":"aad814e5163dbc8843adce04d120be6b558a0124"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"d1a256b8635bd3c4f575aaaa6e009bb0d47c1eab","unresolved":false,"context_lines":[{"line_number":648,"context_line":""},{"line_number":649,"context_line":"def collate_stats_proc(recon_cache, logger, interval):"},{"line_number":650,"context_line":"    while True:"},{"line_number":651,"context_line":"        time.sleep(interval)"},{"line_number":652,"context_line":"        stats \u003d collate_stats(recon_cache)"},{"line_number":653,"context_line":"        dump_recon_cache(stats, recon_cache, logger)"},{"line_number":654,"context_line":""}],"source_content_type":"text/x-python","patch_set":25,"id":"49b256e3_f9a2315e","line":651,"range":{"start_line":651,"start_character":19,"end_line":651,"end_character":27},"in_reply_to":"31d73842_27837bd8","updated":"2021-04-19 03:01:24.000000000","message":"Done","commit_id":"aad814e5163dbc8843adce04d120be6b558a0124"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"72285f28b456a777ac294144368935a51eed88ce","unresolved":true,"context_lines":[{"line_number":662,"context_line":"    # inialise recon dump for collection"},{"line_number":663,"context_line":"    # Lets start by always deleting last run\u0027s stats"},{"line_number":664,"context_line":"    _reset_recon(conf, None, recon_cache, logger)"},{"line_number":665,"context_line":"    #_reset_recon(conf, device_list, recon_cache, logger)"},{"line_number":666,"context_line":"    dump_recon_cache({\"start_time\": start_time, \"total_time\": None,"},{"line_number":667,"context_line":"                      \u0027stats\u0027: {}},"},{"line_number":668,"context_line":"                     recon_cache, logger)"}],"source_content_type":"text/x-python","patch_set":25,"id":"ce5b6a6a_1a0b918f","line":665,"updated":"2021-04-15 07:23:49.000000000","message":"See just sending None to clean it all up. If we decide just to clean up from last run the _reset_recon could become much simpler.","commit_id":"aad814e5163dbc8843adce04d120be6b558a0124"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"66c41dfad6399d1bdbebbad80b02487aa14062a0","unresolved":true,"context_lines":[{"line_number":684,"context_line":"    collate_pid \u003d os.fork()"},{"line_number":685,"context_line":"    if collate_pid \u003d\u003d 0:"},{"line_number":686,"context_line":"        os._exit(collate_stats_proc(recon_cache, logger,"},{"line_number":687,"context_line":"                                    float(conf.get(\u0027recon_interval\u0027))))"},{"line_number":688,"context_line":""},{"line_number":689,"context_line":"    children \u003d {}"},{"line_number":690,"context_line":"    for worker_devs in distribute_evenly(device_list, workers):"}],"source_content_type":"text/x-python","patch_set":25,"id":"395f0797_a745aa85","line":687,"range":{"start_line":687,"start_character":36,"end_line":687,"end_character":41},"updated":"2021-04-16 18:31:32.000000000","message":"nit: it\u0027s already been cast to float","commit_id":"aad814e5163dbc8843adce04d120be6b558a0124"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"d1a256b8635bd3c4f575aaaa6e009bb0d47c1eab","unresolved":false,"context_lines":[{"line_number":684,"context_line":"    collate_pid \u003d os.fork()"},{"line_number":685,"context_line":"    if collate_pid \u003d\u003d 0:"},{"line_number":686,"context_line":"        os._exit(collate_stats_proc(recon_cache, logger,"},{"line_number":687,"context_line":"                                    float(conf.get(\u0027recon_interval\u0027))))"},{"line_number":688,"context_line":""},{"line_number":689,"context_line":"    children \u003d {}"},{"line_number":690,"context_line":"    for worker_devs in distribute_evenly(device_list, workers):"}],"source_content_type":"text/x-python","patch_set":25,"id":"7182cd33_8367f754","line":687,"range":{"start_line":687,"start_character":36,"end_line":687,"end_character":41},"in_reply_to":"395f0797_a745aa85","updated":"2021-04-19 03:01:24.000000000","message":"Done","commit_id":"aad814e5163dbc8843adce04d120be6b558a0124"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"66c41dfad6399d1bdbebbad80b02487aa14062a0","unresolved":true,"context_lines":[{"line_number":824,"context_line":"            args.link_check_limit if args.link_check_limit is not None"},{"line_number":825,"context_line":"            else non_negative_int(conf.get(\u0027link_check_limit\u0027, 2))),"},{"line_number":826,"context_line":"        \u0027recon_cache_path\u0027: conf.get(\u0027recon_cache_path\u0027, \u0027/var/cache/swift\u0027),"},{"line_number":827,"context_line":"        \u0027recon_interval\u0027: float(conf.get(\u0027recon_interval\u0027, 10.0)),"},{"line_number":828,"context_line":"    })"},{"line_number":829,"context_line":"    return parallel_process("},{"line_number":830,"context_line":"        args.action \u003d\u003d \u0027cleanup\u0027, conf, logger, args.device_list)"}],"source_content_type":"text/x-python","patch_set":25,"id":"84a5249d_185325ef","line":827,"range":{"start_line":827,"start_character":26,"end_line":827,"end_character":31},"updated":"2021-04-16 18:31:32.000000000","message":"can use utils.config_float_value or non_negative_float to add some validation","commit_id":"aad814e5163dbc8843adce04d120be6b558a0124"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"d1a256b8635bd3c4f575aaaa6e009bb0d47c1eab","unresolved":false,"context_lines":[{"line_number":824,"context_line":"            args.link_check_limit if args.link_check_limit is not None"},{"line_number":825,"context_line":"            else non_negative_int(conf.get(\u0027link_check_limit\u0027, 2))),"},{"line_number":826,"context_line":"        \u0027recon_cache_path\u0027: conf.get(\u0027recon_cache_path\u0027, \u0027/var/cache/swift\u0027),"},{"line_number":827,"context_line":"        \u0027recon_interval\u0027: float(conf.get(\u0027recon_interval\u0027, 10.0)),"},{"line_number":828,"context_line":"    })"},{"line_number":829,"context_line":"    return parallel_process("},{"line_number":830,"context_line":"        args.action \u003d\u003d \u0027cleanup\u0027, conf, logger, args.device_list)"}],"source_content_type":"text/x-python","patch_set":25,"id":"54550b0a_91fa6834","line":827,"range":{"start_line":827,"start_character":26,"end_line":827,"end_character":31},"in_reply_to":"84a5249d_185325ef","updated":"2021-04-19 03:01:24.000000000","message":"Done","commit_id":"aad814e5163dbc8843adce04d120be6b558a0124"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"fe33b948377bd711287784a49b16567708dbff35","unresolved":true,"context_lines":[{"line_number":148,"context_line":"        recon_data \u003d {\u0027devices\u0027: self.recon_data}"},{"line_number":149,"context_line":""},{"line_number":150,"context_line":"        self.logger.debug(\"Updating recon for %s: %s\" % ("},{"line_number":151,"context_line":"            device, recon_data))"},{"line_number":152,"context_line":"        self._last_recon_update \u003d time.time()"},{"line_number":153,"context_line":"        dump_recon_cache(recon_data, self.recon_cache, self.logger)"},{"line_number":154,"context_line":""}],"source_content_type":"text/x-python","patch_set":30,"id":"eae62337_23ac30c8","line":151,"updated":"2021-04-26 21:26:37.000000000","message":"This feels a bit noisy, especially given how we just stuffed it all into recon anyway. OTOH, it\u0027s down at debug... *shrug*\n\nDefinitely reads a little weird when device\u003dNone, though.","commit_id":"cbed96294f376464021d3994bf8f17996434118b"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"f2944a5f2b55b5792f98eaac9efeab33e8e2dbd1","unresolved":true,"context_lines":[{"line_number":148,"context_line":"        recon_data \u003d {\u0027devices\u0027: self.recon_data}"},{"line_number":149,"context_line":""},{"line_number":150,"context_line":"        self.logger.debug(\"Updating recon for %s: %s\" % ("},{"line_number":151,"context_line":"            device, recon_data))"},{"line_number":152,"context_line":"        self._last_recon_update \u003d time.time()"},{"line_number":153,"context_line":"        dump_recon_cache(recon_data, self.recon_cache, self.logger)"},{"line_number":154,"context_line":""}],"source_content_type":"text/x-python","patch_set":30,"id":"c78c1b11_40c233ac","line":151,"in_reply_to":"eae62337_23ac30c8","updated":"2021-04-27 07:13:19.000000000","message":"yeah, the device comes in when we finish a partition and it\u0027s for updating. But it\u0027s also called to just agregate elsewhere without device.\n\nI guess we could rework it :shrug:","commit_id":"cbed96294f376464021d3994bf8f17996434118b"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"fe33b948377bd711287784a49b16567708dbff35","unresolved":true,"context_lines":[{"line_number":681,"context_line":""},{"line_number":682,"context_line":"    collated_stats[\u0027stats\u0027][\u0027policies\u0027] \u003d len(policies)"},{"line_number":683,"context_line":"    collated_stats[\u0027policies\u0027] \u003d policies"},{"line_number":684,"context_line":"    return {\u0027aggregate\u0027: collated_stats}"},{"line_number":685,"context_line":""},{"line_number":686,"context_line":""},{"line_number":687,"context_line":"def cleanup_finalize_recon(recon_cache, logger):"}],"source_content_type":"text/x-python","patch_set":30,"id":"a5d68418_0787d324","line":684,"updated":"2021-04-26 21:26:37.000000000","message":"I\u0027ve got this feeling like we ought to kick the collation out to a separate patch, or just push consumers to handle it themselves. That seems to be the direction the ALL audit takes, FWIW.","commit_id":"cbed96294f376464021d3994bf8f17996434118b"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"f2944a5f2b55b5792f98eaac9efeab33e8e2dbd1","unresolved":true,"context_lines":[{"line_number":681,"context_line":""},{"line_number":682,"context_line":"    collated_stats[\u0027stats\u0027][\u0027policies\u0027] \u003d len(policies)"},{"line_number":683,"context_line":"    collated_stats[\u0027policies\u0027] \u003d policies"},{"line_number":684,"context_line":"    return {\u0027aggregate\u0027: collated_stats}"},{"line_number":685,"context_line":""},{"line_number":686,"context_line":""},{"line_number":687,"context_line":"def cleanup_finalize_recon(recon_cache, logger):"}],"source_content_type":"text/x-python","patch_set":30,"id":"e57d6748_e3bfeec5","line":684,"in_reply_to":"a5d68418_0787d324","updated":"2021-04-27 07:13:19.000000000","message":"pushed to a seperate patch, we can discuss it there :)","commit_id":"cbed96294f376464021d3994bf8f17996434118b"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"fe33b948377bd711287784a49b16567708dbff35","unresolved":true,"context_lines":[{"line_number":706,"context_line":"    start_time \u003d time.time()"},{"line_number":707,"context_line":"    # inialise recon dump for collection"},{"line_number":708,"context_line":"    # Lets start by always deleting last run\u0027s stats"},{"line_number":709,"context_line":"    _reset_recon(recon_cache, logger)"},{"line_number":710,"context_line":""},{"line_number":711,"context_line":"    device_list \u003d sorted(set(device_list or os.listdir(conf[\u0027devices\u0027])))"},{"line_number":712,"context_line":"    workers \u003d conf[\u0027workers\u0027]"}],"source_content_type":"text/x-python","patch_set":30,"id":"02ef1dc5_f9bc04de","line":709,"updated":"2021-04-26 21:26:37.000000000","message":"It makes me a little nervous how we go blindly resetting recon -- in particular, targeted runs for a single device (or a handful of devices) seem to warrant some special consideration, given how that was previously the *only* way to get good parallelization.","commit_id":"cbed96294f376464021d3994bf8f17996434118b"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"f2944a5f2b55b5792f98eaac9efeab33e8e2dbd1","unresolved":true,"context_lines":[{"line_number":706,"context_line":"    start_time \u003d time.time()"},{"line_number":707,"context_line":"    # inialise recon dump for collection"},{"line_number":708,"context_line":"    # Lets start by always deleting last run\u0027s stats"},{"line_number":709,"context_line":"    _reset_recon(recon_cache, logger)"},{"line_number":710,"context_line":""},{"line_number":711,"context_line":"    device_list \u003d sorted(set(device_list or os.listdir(conf[\u0027devices\u0027])))"},{"line_number":712,"context_line":"    workers \u003d conf[\u0027workers\u0027]"}],"source_content_type":"text/x-python","patch_set":30,"id":"ce69ea88_b66057ff","line":709,"in_reply_to":"02ef1dc5_f9bc04de","updated":"2021-04-27 07:13:19.000000000","message":"yeah, I used have a bunch of code for only resetting certain devices etc. But made things like worker cleanup hard. So decided to start with the simple option. Recon will only display the results of the last/current run. If you pick only a subset, you\u0027ll only see that same subset.","commit_id":"cbed96294f376464021d3994bf8f17996434118b"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"fe33b948377bd711287784a49b16567708dbff35","unresolved":true,"context_lines":[{"line_number":725,"context_line":"    collate_pid \u003d os.fork()"},{"line_number":726,"context_line":"    if collate_pid \u003d\u003d 0:"},{"line_number":727,"context_line":"        os._exit(collate_stats_proc(recon_cache, logger,"},{"line_number":728,"context_line":"                                    conf.get(\u0027recon_interval\u0027)))"},{"line_number":729,"context_line":""},{"line_number":730,"context_line":"    children \u003d {}"},{"line_number":731,"context_line":"    for worker_devs in distribute_evenly(device_list, workers):"}],"source_content_type":"text/x-python","patch_set":30,"id":"2ccdf0a8_875fdafb","line":728,"updated":"2021-04-26 21:26:37.000000000","message":"Should we stuff something into children so we recognize this guy if it\u0027s returned by os.wait()? Though that makes the `while children` more complicated...","commit_id":"cbed96294f376464021d3994bf8f17996434118b"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"f2944a5f2b55b5792f98eaac9efeab33e8e2dbd1","unresolved":true,"context_lines":[{"line_number":725,"context_line":"    collate_pid \u003d os.fork()"},{"line_number":726,"context_line":"    if collate_pid \u003d\u003d 0:"},{"line_number":727,"context_line":"        os._exit(collate_stats_proc(recon_cache, logger,"},{"line_number":728,"context_line":"                                    conf.get(\u0027recon_interval\u0027)))"},{"line_number":729,"context_line":""},{"line_number":730,"context_line":"    children \u003d {}"},{"line_number":731,"context_line":"    for worker_devs in distribute_evenly(device_list, workers):"}],"source_content_type":"text/x-python","patch_set":30,"id":"6449072a_fcef965f","line":728,"in_reply_to":"2ccdf0a8_875fdafb","updated":"2021-04-27 07:13:19.000000000","message":"hmm, maybe.. or maybe we could thread this guy rather then use os.fork? Or as you mentioned elsewhere use recon-cron (if we\u0027re happy with the aggregates potentually being x minutes behined even post relinker is complete.","commit_id":"cbed96294f376464021d3994bf8f17996434118b"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"fe33b948377bd711287784a49b16567708dbff35","unresolved":true,"context_lines":[{"line_number":752,"context_line":"            final_status \u003d EXIT_ERROR"},{"line_number":753,"context_line":"            final_messages.append("},{"line_number":754,"context_line":"                \u0027Worker %s exited in %.1fs after receiving signal: %s\u0027"},{"line_number":755,"context_line":"                % (worker_desc, time_delta, sig))"},{"line_number":756,"context_line":"            continue"},{"line_number":757,"context_line":""},{"line_number":758,"context_line":"        if status \u003d\u003d EXIT_SUCCESS:"}],"source_content_type":"text/x-python","patch_set":30,"id":"bbf01b62_7d2e153f","line":755,"updated":"2021-04-26 21:26:37.000000000","message":"Huh. So during probe tests, I saw\n\n Apr 26 18:32:20 saio object-6020: Worker (pid\u003d334798, devs\u003dunknown device) exited in 0.0s after receiving signal: 15\n\nwhich I\u0027ve gotta assume is the collator ...but... that doesn\u0027t really make sense -- we\u0027re supposed to signal that guy *after* this loop 😕\n\nAnyway, that caused the overall status to flip to error, bombing out the probe test 😞","commit_id":"cbed96294f376464021d3994bf8f17996434118b"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"f2944a5f2b55b5792f98eaac9efeab33e8e2dbd1","unresolved":true,"context_lines":[{"line_number":752,"context_line":"            final_status \u003d EXIT_ERROR"},{"line_number":753,"context_line":"            final_messages.append("},{"line_number":754,"context_line":"                \u0027Worker %s exited in %.1fs after receiving signal: %s\u0027"},{"line_number":755,"context_line":"                % (worker_desc, time_delta, sig))"},{"line_number":756,"context_line":"            continue"},{"line_number":757,"context_line":""},{"line_number":758,"context_line":"        if status \u003d\u003d EXIT_SUCCESS:"}],"source_content_type":"text/x-python","patch_set":30,"id":"1e689747_b18bd7dd","line":755,"in_reply_to":"bbf01b62_7d2e153f","updated":"2021-04-27 07:13:19.000000000","message":"hmm, that\u0027s problematic, not sure how that\u0027ll even work. Like mentioned above maybe we need to use a different threading for the collator? Again let\u0027s discuss this in the seperated patch now 😊","commit_id":"cbed96294f376464021d3994bf8f17996434118b"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"18d221075af567269b914cc713e3f45f98271418","unresolved":true,"context_lines":[{"line_number":89,"context_line":"        \u0027stats\u0027: _zero_stats()}"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"def _worker_stats():"},{"line_number":93,"context_line":"    return {"},{"line_number":94,"context_line":"        \"return_code\": None,"},{"line_number":95,"context_line":"        \"drives\": [],"}],"source_content_type":"text/x-python","patch_set":31,"id":"b7cca3ec_86e3e430","line":92,"updated":"2021-04-27 18:00:02.000000000","message":"this is also \u0027zero-ing\u0027 I think? could it be called _zero_worker_stats?","commit_id":"b70819635d5c9ce0a29d9a9b0bb82197cbab86ab"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"9223916d7813173c0e658b1183097f54d5baea8a","unresolved":true,"context_lines":[{"line_number":89,"context_line":"        \u0027stats\u0027: _zero_stats()}"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"def _worker_stats():"},{"line_number":93,"context_line":"    return {"},{"line_number":94,"context_line":"        \"return_code\": None,"},{"line_number":95,"context_line":"        \"drives\": [],"}],"source_content_type":"text/x-python","patch_set":31,"id":"41374247_c917e892","line":92,"in_reply_to":"1c69716f_81023059","updated":"2021-04-28 07:31:23.000000000","message":"also we don\u0027t use it anymore so will remove the method.","commit_id":"b70819635d5c9ce0a29d9a9b0bb82197cbab86ab"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"c8225a146c318f8798950ade4fdfe4736be2b276","unresolved":true,"context_lines":[{"line_number":89,"context_line":"        \u0027stats\u0027: _zero_stats()}"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"def _worker_stats():"},{"line_number":93,"context_line":"    return {"},{"line_number":94,"context_line":"        \"return_code\": None,"},{"line_number":95,"context_line":"        \"drives\": [],"}],"source_content_type":"text/x-python","patch_set":31,"id":"1c69716f_81023059","line":92,"in_reply_to":"b7cca3ec_86e3e430","updated":"2021-04-28 00:17:15.000000000","message":"yup, good call","commit_id":"b70819635d5c9ce0a29d9a9b0bb82197cbab86ab"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"18d221075af567269b914cc713e3f45f98271418","unresolved":true,"context_lines":[{"line_number":92,"context_line":"def _worker_stats():"},{"line_number":93,"context_line":"    return {"},{"line_number":94,"context_line":"        \"return_code\": None,"},{"line_number":95,"context_line":"        \"drives\": [],"},{"line_number":96,"context_line":"        \"timestamp\": 0,"},{"line_number":97,"context_line":"    }"},{"line_number":98,"context_line":""}],"source_content_type":"text/x-python","patch_set":31,"id":"cae18903_f835e012","line":95,"range":{"start_line":95,"start_character":9,"end_line":95,"end_character":16},"updated":"2021-04-27 18:00:02.000000000","message":"this should be devices to be consistent","commit_id":"b70819635d5c9ce0a29d9a9b0bb82197cbab86ab"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"c8225a146c318f8798950ade4fdfe4736be2b276","unresolved":true,"context_lines":[{"line_number":92,"context_line":"def _worker_stats():"},{"line_number":93,"context_line":"    return {"},{"line_number":94,"context_line":"        \"return_code\": None,"},{"line_number":95,"context_line":"        \"drives\": [],"},{"line_number":96,"context_line":"        \"timestamp\": 0,"},{"line_number":97,"context_line":"    }"},{"line_number":98,"context_line":""}],"source_content_type":"text/x-python","patch_set":31,"id":"ebfdbdb8_73272d67","line":95,"range":{"start_line":95,"start_character":9,"end_line":95,"end_character":16},"in_reply_to":"cae18903_f835e012","updated":"2021-04-28 00:17:15.000000000","message":"yes it probably should, thanks 😊","commit_id":"b70819635d5c9ce0a29d9a9b0bb82197cbab86ab"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"18d221075af567269b914cc713e3f45f98271418","unresolved":true,"context_lines":[{"line_number":112,"context_line":"        self.diskfile_mgr \u003d None"},{"line_number":113,"context_line":"        self.dev_lock \u003d None"},{"line_number":114,"context_line":"        self._last_recon_update \u003d 0"},{"line_number":115,"context_line":"        self.recon_interval \u003d float(conf.get(\u0027recon_interval\u0027, 300.0))"},{"line_number":116,"context_line":"        self.diskfile_router \u003d diskfile.DiskFileRouter(self.conf, self.logger)"},{"line_number":117,"context_line":"        self.stats \u003d _zero_stats()"},{"line_number":118,"context_line":"        self.recon_data \u003d {}"}],"source_content_type":"text/x-python","patch_set":31,"id":"fc4cb4cc_7aa5d41c","line":115,"updated":"2021-04-27 18:00:02.000000000","message":"in replicator and reconstructor we call this stats_interval and it must be an int","commit_id":"b70819635d5c9ce0a29d9a9b0bb82197cbab86ab"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"c8225a146c318f8798950ade4fdfe4736be2b276","unresolved":true,"context_lines":[{"line_number":112,"context_line":"        self.diskfile_mgr \u003d None"},{"line_number":113,"context_line":"        self.dev_lock \u003d None"},{"line_number":114,"context_line":"        self._last_recon_update \u003d 0"},{"line_number":115,"context_line":"        self.recon_interval \u003d float(conf.get(\u0027recon_interval\u0027, 300.0))"},{"line_number":116,"context_line":"        self.diskfile_router \u003d diskfile.DiskFileRouter(self.conf, self.logger)"},{"line_number":117,"context_line":"        self.stats \u003d _zero_stats()"},{"line_number":118,"context_line":"        self.recon_data \u003d {}"}],"source_content_type":"text/x-python","patch_set":31,"id":"cb30e355_4f02455b","line":115,"in_reply_to":"fc4cb4cc_7aa5d41c","updated":"2021-04-28 00:17:15.000000000","message":"I guess being able to do fraction of seconds aren\u0027t going to make a big difference. Happy to make it the same.","commit_id":"b70819635d5c9ce0a29d9a9b0bb82197cbab86ab"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"18d221075af567269b914cc713e3f45f98271418","unresolved":true,"context_lines":[{"line_number":115,"context_line":"        self.recon_interval \u003d float(conf.get(\u0027recon_interval\u0027, 300.0))"},{"line_number":116,"context_line":"        self.diskfile_router \u003d diskfile.DiskFileRouter(self.conf, self.logger)"},{"line_number":117,"context_line":"        self.stats \u003d _zero_stats()"},{"line_number":118,"context_line":"        self.recon_data \u003d {}"},{"line_number":119,"context_line":"        self.worker_stats \u003d {}"},{"line_number":120,"context_line":"        self.policy_count \u003d 0"},{"line_number":121,"context_line":"        self.pid \u003d os.getpid()"}],"source_content_type":"text/x-python","patch_set":31,"id":"4ca863d3_01ad20b3","line":118,"range":{"start_line":118,"start_character":8,"end_line":118,"end_character":23},"updated":"2021-04-27 18:00:02.000000000","message":"I found it a little confusing that recon_data is in fact the sub-dict of per device data, rather than the top level dict of all recon data","commit_id":"b70819635d5c9ce0a29d9a9b0bb82197cbab86ab"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"c8225a146c318f8798950ade4fdfe4736be2b276","unresolved":true,"context_lines":[{"line_number":115,"context_line":"        self.recon_interval \u003d float(conf.get(\u0027recon_interval\u0027, 300.0))"},{"line_number":116,"context_line":"        self.diskfile_router \u003d diskfile.DiskFileRouter(self.conf, self.logger)"},{"line_number":117,"context_line":"        self.stats \u003d _zero_stats()"},{"line_number":118,"context_line":"        self.recon_data \u003d {}"},{"line_number":119,"context_line":"        self.worker_stats \u003d {}"},{"line_number":120,"context_line":"        self.policy_count \u003d 0"},{"line_number":121,"context_line":"        self.pid \u003d os.getpid()"}],"source_content_type":"text/x-python","patch_set":31,"id":"17c3398b_7273d3fc","line":118,"range":{"start_line":118,"start_character":8,"end_line":118,"end_character":23},"in_reply_to":"4ca863d3_01ad20b3","updated":"2021-04-28 00:17:15.000000000","message":"Good point. It just started to get a bit unweildy in size and was only storing device data. I could either combine the recon_data and worker_stats or maybe rename recon_data to device_stats or something.","commit_id":"b70819635d5c9ce0a29d9a9b0bb82197cbab86ab"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"18d221075af567269b914cc713e3f45f98271418","unresolved":true,"context_lines":[{"line_number":128,"context_line":"        if device:"},{"line_number":129,"context_line":"            # dump recon stats for the device"},{"line_number":130,"context_line":"            num_parts_done \u003d sum("},{"line_number":131,"context_line":"                1 for part in self.states[\"state\"].values()"},{"line_number":132,"context_line":"                if part)"},{"line_number":133,"context_line":"            num_total_parts \u003d len(self.states[\"state\"])"},{"line_number":134,"context_line":"            step \u003d STEP_CLEANUP if self.do_cleanup else STEP_RELINK"}],"source_content_type":"text/x-python","patch_set":31,"id":"a26c37d5_93de3c6e","line":131,"range":{"start_line":131,"start_character":30,"end_line":131,"end_character":41},"updated":"2021-04-27 18:00:02.000000000","message":"ok, so self.states[\u0027state\u0027] is per-device","commit_id":"b70819635d5c9ce0a29d9a9b0bb82197cbab86ab"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"18d221075af567269b914cc713e3f45f98271418","unresolved":true,"context_lines":[{"line_number":144,"context_line":"            self.recon_data[dev].update(_zero_collated_stats())"},{"line_number":145,"context_line":"            for policy_data in self.recon_data[dev].get("},{"line_number":146,"context_line":"                    \u0027policies\u0027, {}).values():"},{"line_number":147,"context_line":"                self.recon_data[dev].update("},{"line_number":148,"context_line":"                    _aggregate_recon_stats(self.recon_data[dev], policy_data))"},{"line_number":149,"context_line":""},{"line_number":150,"context_line":"        # We want to periodically update the worker recon timestamp so we know"}],"source_content_type":"text/x-python","patch_set":31,"id":"43b10b79_be899db5","line":147,"range":{"start_line":147,"start_character":16,"end_line":147,"end_character":43},"updated":"2021-04-27 18:00:02.000000000","message":"this update isn\u0027t necessary: self.recon_data[dev] is updated by _aggregate_recon_stats","commit_id":"b70819635d5c9ce0a29d9a9b0bb82197cbab86ab"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"c8225a146c318f8798950ade4fdfe4736be2b276","unresolved":true,"context_lines":[{"line_number":144,"context_line":"            self.recon_data[dev].update(_zero_collated_stats())"},{"line_number":145,"context_line":"            for policy_data in self.recon_data[dev].get("},{"line_number":146,"context_line":"                    \u0027policies\u0027, {}).values():"},{"line_number":147,"context_line":"                self.recon_data[dev].update("},{"line_number":148,"context_line":"                    _aggregate_recon_stats(self.recon_data[dev], policy_data))"},{"line_number":149,"context_line":""},{"line_number":150,"context_line":"        # We want to periodically update the worker recon timestamp so we know"}],"source_content_type":"text/x-python","patch_set":31,"id":"60a04479_1324bdb6","line":147,"range":{"start_line":147,"start_character":16,"end_line":147,"end_character":43},"in_reply_to":"43b10b79_be899db5","updated":"2021-04-28 00:17:15.000000000","message":"that\u0027s true, unless there is some stat in there that isn\u0027t in _aggregate_recon_stats.. but there shouldn\u0027t be. So OK 😊","commit_id":"b70819635d5c9ce0a29d9a9b0bb82197cbab86ab"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"18d221075af567269b914cc713e3f45f98271418","unresolved":true,"context_lines":[{"line_number":198,"context_line":"        device \u003d os.path.basename(device_path)"},{"line_number":199,"context_line":"        self.recon_data.setdefault(device, {})"},{"line_number":200,"context_line":"        self.recon_data[device].setdefault(\u0027policies\u0027, {})"},{"line_number":201,"context_line":"        self.recon_data[device][\u0027policies\u0027].setdefault("},{"line_number":202,"context_line":"            self.policy.idx, {})"},{"line_number":203,"context_line":"        self.recon_data[device][\u0027policies\u0027][self.policy.idx] \u003d {"},{"line_number":204,"context_line":"            \u0027start_time\u0027: time.time(), \u0027stats\u0027: self.stats,"},{"line_number":205,"context_line":"            \u0027part_power\u0027: self.states[\"part_power\"],"}],"source_content_type":"text/x-python","patch_set":31,"id":"bee7ba14_5784c23f","line":202,"range":{"start_line":201,"start_character":8,"end_line":202,"end_character":32},"updated":"2021-04-27 18:00:02.000000000","message":"this is always replaced by the next line - was the setdefault not needed or should the next line be an update? Since we\u0027re initialising I guess the setdefault wasn\u0027t needed.","commit_id":"b70819635d5c9ce0a29d9a9b0bb82197cbab86ab"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"c8225a146c318f8798950ade4fdfe4736be2b276","unresolved":true,"context_lines":[{"line_number":198,"context_line":"        device \u003d os.path.basename(device_path)"},{"line_number":199,"context_line":"        self.recon_data.setdefault(device, {})"},{"line_number":200,"context_line":"        self.recon_data[device].setdefault(\u0027policies\u0027, {})"},{"line_number":201,"context_line":"        self.recon_data[device][\u0027policies\u0027].setdefault("},{"line_number":202,"context_line":"            self.policy.idx, {})"},{"line_number":203,"context_line":"        self.recon_data[device][\u0027policies\u0027][self.policy.idx] \u003d {"},{"line_number":204,"context_line":"            \u0027start_time\u0027: time.time(), \u0027stats\u0027: self.stats,"},{"line_number":205,"context_line":"            \u0027part_power\u0027: self.states[\"part_power\"],"}],"source_content_type":"text/x-python","patch_set":31,"id":"ff83720d_b1c13c57","line":202,"range":{"start_line":201,"start_character":8,"end_line":202,"end_character":32},"in_reply_to":"bee7ba14_5784c23f","updated":"2021-04-28 00:17:15.000000000","message":"yeah, I think I must\u0027ve changed something here and the set default must\u0027ve stuck around.","commit_id":"b70819635d5c9ce0a29d9a9b0bb82197cbab86ab"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"18d221075af567269b914cc713e3f45f98271418","unresolved":true,"context_lines":[{"line_number":212,"context_line":"        device \u003d os.path.basename(device_path)"},{"line_number":213,"context_line":"        pol_stats \u003d self.recon_data[device][\u0027policies\u0027][self.policy.idx]"},{"line_number":214,"context_line":"        total_time \u003d time.time() - pol_stats[\u0027start_time\u0027]"},{"line_number":215,"context_line":"        self.recon_data[device][\u0027policies\u0027][self.policy.idx].update("},{"line_number":216,"context_line":"            {\u0027total_time\u0027: total_time, \u0027stats\u0027: self.stats})"},{"line_number":217,"context_line":"        self._update_recon(device, force_dump\u003dTrue)"},{"line_number":218,"context_line":""}],"source_content_type":"text/x-python","patch_set":31,"id":"5f0d693a_b297a710","line":215,"range":{"start_line":215,"start_character":8,"end_line":215,"end_character":60},"updated":"2021-04-27 18:00:02.000000000","message":"this is pol_stats","commit_id":"b70819635d5c9ce0a29d9a9b0bb82197cbab86ab"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"c8225a146c318f8798950ade4fdfe4736be2b276","unresolved":false,"context_lines":[{"line_number":212,"context_line":"        device \u003d os.path.basename(device_path)"},{"line_number":213,"context_line":"        pol_stats \u003d self.recon_data[device][\u0027policies\u0027][self.policy.idx]"},{"line_number":214,"context_line":"        total_time \u003d time.time() - pol_stats[\u0027start_time\u0027]"},{"line_number":215,"context_line":"        self.recon_data[device][\u0027policies\u0027][self.policy.idx].update("},{"line_number":216,"context_line":"            {\u0027total_time\u0027: total_time, \u0027stats\u0027: self.stats})"},{"line_number":217,"context_line":"        self._update_recon(device, force_dump\u003dTrue)"},{"line_number":218,"context_line":""}],"source_content_type":"text/x-python","patch_set":31,"id":"a82c479c_e8aedbfa","line":215,"range":{"start_line":215,"start_character":8,"end_line":215,"end_character":60},"in_reply_to":"5f0d693a_b297a710","updated":"2021-04-28 00:17:15.000000000","message":"Ack","commit_id":"b70819635d5c9ce0a29d9a9b0bb82197cbab86ab"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"18d221075af567269b914cc713e3f45f98271418","unresolved":true,"context_lines":[{"line_number":527,"context_line":"        self.recon_data.setdefault(dev, {})"},{"line_number":528,"context_line":"        self.recon_data[dev].setdefault(\u0027policies\u0027, {})"},{"line_number":529,"context_line":"        self.recon_data[dev][\u0027policies\u0027].setdefault(policy.idx, {})"},{"line_number":530,"context_line":"        self.recon_data[dev][\u0027policies\u0027][policy.idx].setdefault(\"stats\", {})"},{"line_number":531,"context_line":"        stats \u003d self.recon_data[dev][\u0027policies\u0027][policy.idx][\u0027stats\u0027]"},{"line_number":532,"context_line":""},{"line_number":533,"context_line":"        if not stats:"},{"line_number":534,"context_line":"            stats \u003d _zero_stats()"},{"line_number":535,"context_line":"        if stat in stats:"},{"line_number":536,"context_line":"            stats[stat] +\u003d value"},{"line_number":537,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":31,"id":"45825281_ed5e35d5","line":534,"range":{"start_line":530,"start_character":8,"end_line":534,"end_character":33},"updated":"2021-04-27 18:00:02.000000000","message":"I think this simplifies to \n\n  stats \u003d self.recon_data[dev][\u0027policies\u0027][policy.idx].setdefault(\"stats\", _zero_stats())","commit_id":"b70819635d5c9ce0a29d9a9b0bb82197cbab86ab"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"c8225a146c318f8798950ade4fdfe4736be2b276","unresolved":true,"context_lines":[{"line_number":527,"context_line":"        self.recon_data.setdefault(dev, {})"},{"line_number":528,"context_line":"        self.recon_data[dev].setdefault(\u0027policies\u0027, {})"},{"line_number":529,"context_line":"        self.recon_data[dev][\u0027policies\u0027].setdefault(policy.idx, {})"},{"line_number":530,"context_line":"        self.recon_data[dev][\u0027policies\u0027][policy.idx].setdefault(\"stats\", {})"},{"line_number":531,"context_line":"        stats \u003d self.recon_data[dev][\u0027policies\u0027][policy.idx][\u0027stats\u0027]"},{"line_number":532,"context_line":""},{"line_number":533,"context_line":"        if not stats:"},{"line_number":534,"context_line":"            stats \u003d _zero_stats()"},{"line_number":535,"context_line":"        if stat in stats:"},{"line_number":536,"context_line":"            stats[stat] +\u003d value"},{"line_number":537,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":31,"id":"f03fbe4a_3c6725d2","line":534,"range":{"start_line":530,"start_character":8,"end_line":534,"end_character":33},"in_reply_to":"45825281_ed5e35d5","updated":"2021-04-28 00:17:15.000000000","message":"Thanks! yes that\u0027s much better.","commit_id":"b70819635d5c9ce0a29d9a9b0bb82197cbab86ab"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"18d221075af567269b914cc713e3f45f98271418","unresolved":true,"context_lines":[{"line_number":536,"context_line":"            stats[stat] +\u003d value"},{"line_number":537,"context_line":"        else:"},{"line_number":538,"context_line":"            stats[stat] \u003d value"},{"line_number":539,"context_line":"        self.recon_data[dev][\u0027policies\u0027][policy.idx][\u0027stats\u0027].update(stats)"},{"line_number":540,"context_line":""},{"line_number":541,"context_line":"    def process_policy(self, policy):"},{"line_number":542,"context_line":"        self.logger.info("}],"source_content_type":"text/x-python","patch_set":31,"id":"49e199e3_08799fd9","line":539,"updated":"2021-04-27 18:00:02.000000000","message":"with the change suggested above this line is no longer needed: the leaf dict is being mutated directly","commit_id":"b70819635d5c9ce0a29d9a9b0bb82197cbab86ab"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"18d221075af567269b914cc713e3f45f98271418","unresolved":true,"context_lines":[{"line_number":590,"context_line":"            device \u003d os.path.basename(device_path)"},{"line_number":591,"context_line":"            self.place_policy_stat(device, policy, \u0027unlistable_partitions\u0027, 1)"},{"line_number":592,"context_line":""},{"line_number":593,"context_line":"    def _update_worker_stats(self, recon_dump\u003dTrue):"},{"line_number":594,"context_line":"        self.worker_stats[\u0027timestamp\u0027] \u003d time.time()"},{"line_number":595,"context_line":"        worker_data \u003d {\"workers\": {str(self.pid): self.worker_stats}}"},{"line_number":596,"context_line":"        if recon_dump:"}],"source_content_type":"text/x-python","patch_set":31,"id":"e7d8887b_a9a3dd59","line":593,"updated":"2021-04-27 18:00:02.000000000","message":"nit: could just init self.worker_stats here:\n\n  if not self.worker_stats:\n      self.worker_stats \u003d _worker_stats()\n\nin fact, we could just build the worker stats dict every time in this method and not have self.worker_stats - pass in an optional return code and the other items are self.device_list and time.time","commit_id":"b70819635d5c9ce0a29d9a9b0bb82197cbab86ab"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"c8225a146c318f8798950ade4fdfe4736be2b276","unresolved":true,"context_lines":[{"line_number":590,"context_line":"            device \u003d os.path.basename(device_path)"},{"line_number":591,"context_line":"            self.place_policy_stat(device, policy, \u0027unlistable_partitions\u0027, 1)"},{"line_number":592,"context_line":""},{"line_number":593,"context_line":"    def _update_worker_stats(self, recon_dump\u003dTrue):"},{"line_number":594,"context_line":"        self.worker_stats[\u0027timestamp\u0027] \u003d time.time()"},{"line_number":595,"context_line":"        worker_data \u003d {\"workers\": {str(self.pid): self.worker_stats}}"},{"line_number":596,"context_line":"        if recon_dump:"}],"source_content_type":"text/x-python","patch_set":31,"id":"40a0f74d_d0a5159d","line":593,"in_reply_to":"e7d8887b_a9a3dd59","updated":"2021-04-28 00:17:15.000000000","message":"oh nice suggestion!","commit_id":"b70819635d5c9ce0a29d9a9b0bb82197cbab86ab"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"18d221075af567269b914cc713e3f45f98271418","unresolved":true,"context_lines":[{"line_number":600,"context_line":"    def run(self):"},{"line_number":601,"context_line":"        num_policies \u003d 0"},{"line_number":602,"context_line":"        self.worker_stats \u003d _worker_stats()"},{"line_number":603,"context_line":"        self.worker_stats[\u0027drives\u0027] \u003d self.device_list"},{"line_number":604,"context_line":"        self._update_worker_stats()"},{"line_number":605,"context_line":"        for policy in self.conf[\u0027policies\u0027]:"},{"line_number":606,"context_line":"            self.policy \u003d policy"}],"source_content_type":"text/x-python","patch_set":31,"id":"d771371e_53bc6105","line":603,"range":{"start_line":603,"start_character":8,"end_line":603,"end_character":54},"updated":"2021-04-27 18:00:02.000000000","message":"this could be set in update_worker_stats","commit_id":"b70819635d5c9ce0a29d9a9b0bb82197cbab86ab"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"c8225a146c318f8798950ade4fdfe4736be2b276","unresolved":false,"context_lines":[{"line_number":600,"context_line":"    def run(self):"},{"line_number":601,"context_line":"        num_policies \u003d 0"},{"line_number":602,"context_line":"        self.worker_stats \u003d _worker_stats()"},{"line_number":603,"context_line":"        self.worker_stats[\u0027drives\u0027] \u003d self.device_list"},{"line_number":604,"context_line":"        self._update_worker_stats()"},{"line_number":605,"context_line":"        for policy in self.conf[\u0027policies\u0027]:"},{"line_number":606,"context_line":"            self.policy \u003d policy"}],"source_content_type":"text/x-python","patch_set":31,"id":"e8f79ac1_223d28fb","line":603,"range":{"start_line":603,"start_character":8,"end_line":603,"end_character":54},"in_reply_to":"d771371e_53bc6105","updated":"2021-04-28 00:17:15.000000000","message":"Ack","commit_id":"b70819635d5c9ce0a29d9a9b0bb82197cbab86ab"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"18d221075af567269b914cc713e3f45f98271418","unresolved":true,"context_lines":[{"line_number":622,"context_line":"        if not num_policies:"},{"line_number":623,"context_line":"            self.logger.warning("},{"line_number":624,"context_line":"                \"No policy found to increase the partition power.\")"},{"line_number":625,"context_line":"            self.worker_stats[\u0027return_code\u0027] \u003d EXIT_NO_APPLICABLE_POLICY"},{"line_number":626,"context_line":"            self._update_worker_stats()"},{"line_number":627,"context_line":"            return EXIT_NO_APPLICABLE_POLICY"},{"line_number":628,"context_line":""}],"source_content_type":"text/x-python","patch_set":31,"id":"d4e7cf3a_fe7fc5b9","line":625,"updated":"2021-04-27 18:00:02.000000000","message":"maybe pass return code as an optional arg to update_worker_stats\n\n  self._update_worker_stats(return_code\u003dEXIT_NO_APPLICABLE_POLICY)","commit_id":"b70819635d5c9ce0a29d9a9b0bb82197cbab86ab"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"18d221075af567269b914cc713e3f45f98271418","unresolved":true,"context_lines":[{"line_number":628,"context_line":""},{"line_number":629,"context_line":"        stats \u003d _zero_stats()"},{"line_number":630,"context_line":"        for dev_stats in self.recon_data.values():"},{"line_number":631,"context_line":"            stats \u003d _aggregate_stats(stats, dev_stats.get(\u0027stats\u0027, {}))"},{"line_number":632,"context_line":"        hash_dirs \u003d stats.pop(\u0027hash_dirs\u0027)"},{"line_number":633,"context_line":"        files \u003d stats.pop(\u0027files\u0027)"},{"line_number":634,"context_line":"        linked \u003d stats.pop(\u0027linked\u0027)"}],"source_content_type":"text/x-python","patch_set":31,"id":"52a3dd7a_db9f7edc","line":631,"updated":"2021-04-27 18:00:02.000000000","message":"ok, so this sums all the per device stats up ready for the final logging for this worker. But the summed stats are not dumped to recon, correct?","commit_id":"b70819635d5c9ce0a29d9a9b0bb82197cbab86ab"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"c8225a146c318f8798950ade4fdfe4736be2b276","unresolved":true,"context_lines":[{"line_number":628,"context_line":""},{"line_number":629,"context_line":"        stats \u003d _zero_stats()"},{"line_number":630,"context_line":"        for dev_stats in self.recon_data.values():"},{"line_number":631,"context_line":"            stats \u003d _aggregate_stats(stats, dev_stats.get(\u0027stats\u0027, {}))"},{"line_number":632,"context_line":"        hash_dirs \u003d stats.pop(\u0027hash_dirs\u0027)"},{"line_number":633,"context_line":"        files \u003d stats.pop(\u0027files\u0027)"},{"line_number":634,"context_line":"        linked \u003d stats.pop(\u0027linked\u0027)"}],"source_content_type":"text/x-python","patch_set":31,"id":"ec567994_6857d392","line":631,"in_reply_to":"52a3dd7a_db9f7edc","updated":"2021-04-28 00:17:15.000000000","message":"nope, not at the moment. Where do we put them? An aggregation like this wont fit in \u0027devices\u0027. Is pretty much what\u0027s in \u0027aggregate\u0027 in the next patch. \n\nit\u0027s mostly here so I don\u0027t change the final logging and generating of the return_code.","commit_id":"b70819635d5c9ce0a29d9a9b0bb82197cbab86ab"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"18d221075af567269b914cc713e3f45f98271418","unresolved":true,"context_lines":[{"line_number":660,"context_line":"            \u0027%d hash dirs processed (cleanup\u003d%s) (%d files, %d linked, \u0027"},{"line_number":661,"context_line":"            \u0027%d removed, %d errors)\u0027, hash_dirs, self.do_cleanup, files,"},{"line_number":662,"context_line":"            linked, removed, action_errors + listdir_errors)"},{"line_number":663,"context_line":"        self.worker_stats[\u0027return_code\u0027] \u003d status"},{"line_number":664,"context_line":"        self._update_worker_stats()"},{"line_number":665,"context_line":"        return status"},{"line_number":666,"context_line":""}],"source_content_type":"text/x-python","patch_set":31,"id":"fc67e465_ce2bb841","line":663,"updated":"2021-04-27 18:00:02.000000000","message":"maybe self._update_worker_stats(return_code\u003dstatus)","commit_id":"b70819635d5c9ce0a29d9a9b0bb82197cbab86ab"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"18d221075af567269b914cc713e3f45f98271418","unresolved":true,"context_lines":[{"line_number":665,"context_line":"        return status"},{"line_number":666,"context_line":""},{"line_number":667,"context_line":""},{"line_number":668,"context_line":"def _reset_recon(recon_cache, logger):"},{"line_number":669,"context_line":"    device_progress_recon \u003d {\u0027devices\u0027: {}, \u0027aggregate\u0027: {}, \u0027workers\u0027: {}}"},{"line_number":670,"context_line":"    dump_recon_cache(device_progress_recon, recon_cache, logger)"},{"line_number":671,"context_line":""}],"source_content_type":"text/x-python","patch_set":31,"id":"5ee2dfc1_13d92106","line":668,"updated":"2021-04-27 18:00:02.000000000","message":"nit: this doesn\u0027t do much as a separate function except it does self-document. I wonder if it might belong up top with the other recon-related module level functions?","commit_id":"b70819635d5c9ce0a29d9a9b0bb82197cbab86ab"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"c8225a146c318f8798950ade4fdfe4736be2b276","unresolved":true,"context_lines":[{"line_number":665,"context_line":"        return status"},{"line_number":666,"context_line":""},{"line_number":667,"context_line":""},{"line_number":668,"context_line":"def _reset_recon(recon_cache, logger):"},{"line_number":669,"context_line":"    device_progress_recon \u003d {\u0027devices\u0027: {}, \u0027aggregate\u0027: {}, \u0027workers\u0027: {}}"},{"line_number":670,"context_line":"    dump_recon_cache(device_progress_recon, recon_cache, logger)"},{"line_number":671,"context_line":""}],"source_content_type":"text/x-python","patch_set":31,"id":"4b272df0_6e705cd6","line":668,"in_reply_to":"5ee2dfc1_13d92106","updated":"2021-04-28 00:17:15.000000000","message":"yeah, it used to do much more.. and now it does very little :P","commit_id":"b70819635d5c9ce0a29d9a9b0bb82197cbab86ab"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"18d221075af567269b914cc713e3f45f98271418","unresolved":true,"context_lines":[{"line_number":666,"context_line":""},{"line_number":667,"context_line":""},{"line_number":668,"context_line":"def _reset_recon(recon_cache, logger):"},{"line_number":669,"context_line":"    device_progress_recon \u003d {\u0027devices\u0027: {}, \u0027aggregate\u0027: {}, \u0027workers\u0027: {}}"},{"line_number":670,"context_line":"    dump_recon_cache(device_progress_recon, recon_cache, logger)"},{"line_number":671,"context_line":""},{"line_number":672,"context_line":""}],"source_content_type":"text/x-python","patch_set":31,"id":"5b9a2f1a_b818232b","line":669,"range":{"start_line":669,"start_character":44,"end_line":669,"end_character":55},"updated":"2021-04-27 18:00:02.000000000","message":"is aggregate used in this patch?","commit_id":"b70819635d5c9ce0a29d9a9b0bb82197cbab86ab"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"c8225a146c318f8798950ade4fdfe4736be2b276","unresolved":true,"context_lines":[{"line_number":666,"context_line":""},{"line_number":667,"context_line":""},{"line_number":668,"context_line":"def _reset_recon(recon_cache, logger):"},{"line_number":669,"context_line":"    device_progress_recon \u003d {\u0027devices\u0027: {}, \u0027aggregate\u0027: {}, \u0027workers\u0027: {}}"},{"line_number":670,"context_line":"    dump_recon_cache(device_progress_recon, recon_cache, logger)"},{"line_number":671,"context_line":""},{"line_number":672,"context_line":""}],"source_content_type":"text/x-python","patch_set":31,"id":"9889314f_0873c10d","line":669,"range":{"start_line":669,"start_character":44,"end_line":669,"end_character":55},"in_reply_to":"5b9a2f1a_b818232b","updated":"2021-04-28 00:17:15.000000000","message":"ops, missed this in the split 😊","commit_id":"b70819635d5c9ce0a29d9a9b0bb82197cbab86ab"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"18d221075af567269b914cc713e3f45f98271418","unresolved":true,"context_lines":[{"line_number":675,"context_line":""},{"line_number":676,"context_line":"    # dump the start time"},{"line_number":677,"context_line":"    recon_cache \u003d os.path.join(conf[\u0027recon_cache_path\u0027], RECON_FILE)"},{"line_number":678,"context_line":"    start_time \u003d time.time()"},{"line_number":679,"context_line":"    # inialise recon dump for collection"},{"line_number":680,"context_line":"    # Lets start by always deleting last run\u0027s stats"},{"line_number":681,"context_line":"    _reset_recon(recon_cache, logger)"}],"source_content_type":"text/x-python","patch_set":31,"id":"c0c9bb27_931d1cc3","line":678,"range":{"start_line":678,"start_character":4,"end_line":678,"end_character":15},"updated":"2021-04-27 18:00:02.000000000","message":"this seems to duplicate start at line 690, probably crept in with other recon logging patch - I think we only need one start time","commit_id":"b70819635d5c9ce0a29d9a9b0bb82197cbab86ab"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"c8225a146c318f8798950ade4fdfe4736be2b276","unresolved":true,"context_lines":[{"line_number":675,"context_line":""},{"line_number":676,"context_line":"    # dump the start time"},{"line_number":677,"context_line":"    recon_cache \u003d os.path.join(conf[\u0027recon_cache_path\u0027], RECON_FILE)"},{"line_number":678,"context_line":"    start_time \u003d time.time()"},{"line_number":679,"context_line":"    # inialise recon dump for collection"},{"line_number":680,"context_line":"    # Lets start by always deleting last run\u0027s stats"},{"line_number":681,"context_line":"    _reset_recon(recon_cache, logger)"}],"source_content_type":"text/x-python","patch_set":31,"id":"a5925ff9_fa93d5f7","line":678,"range":{"start_line":678,"start_character":4,"end_line":678,"end_character":15},"in_reply_to":"c0c9bb27_931d1cc3","updated":"2021-04-28 00:17:15.000000000","message":"What only one!.. this one is surely more accurate :P","commit_id":"b70819635d5c9ce0a29d9a9b0bb82197cbab86ab"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"18d221075af567269b914cc713e3f45f98271418","unresolved":true,"context_lines":[{"line_number":676,"context_line":"    # dump the start time"},{"line_number":677,"context_line":"    recon_cache \u003d os.path.join(conf[\u0027recon_cache_path\u0027], RECON_FILE)"},{"line_number":678,"context_line":"    start_time \u003d time.time()"},{"line_number":679,"context_line":"    # inialise recon dump for collection"},{"line_number":680,"context_line":"    # Lets start by always deleting last run\u0027s stats"},{"line_number":681,"context_line":"    _reset_recon(recon_cache, logger)"},{"line_number":682,"context_line":""}],"source_content_type":"text/x-python","patch_set":31,"id":"c2b32087_148d0ca0","line":679,"range":{"start_line":679,"start_character":6,"end_line":679,"end_character":14},"updated":"2021-04-27 18:00:02.000000000","message":"typo: initialise","commit_id":"b70819635d5c9ce0a29d9a9b0bb82197cbab86ab"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"c8225a146c318f8798950ade4fdfe4736be2b276","unresolved":false,"context_lines":[{"line_number":676,"context_line":"    # dump the start time"},{"line_number":677,"context_line":"    recon_cache \u003d os.path.join(conf[\u0027recon_cache_path\u0027], RECON_FILE)"},{"line_number":678,"context_line":"    start_time \u003d time.time()"},{"line_number":679,"context_line":"    # inialise recon dump for collection"},{"line_number":680,"context_line":"    # Lets start by always deleting last run\u0027s stats"},{"line_number":681,"context_line":"    _reset_recon(recon_cache, logger)"},{"line_number":682,"context_line":""}],"source_content_type":"text/x-python","patch_set":31,"id":"7fc9868b_d2088cb0","line":679,"range":{"start_line":679,"start_character":6,"end_line":679,"end_character":14},"in_reply_to":"c2b32087_148d0ca0","updated":"2021-04-28 00:17:15.000000000","message":"Ack","commit_id":"b70819635d5c9ce0a29d9a9b0bb82197cbab86ab"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"7ee3333df864288030238500ccdf72fbceb4d555","unresolved":true,"context_lines":[{"line_number":105,"context_line":"        self.diskfile_mgr \u003d None"},{"line_number":106,"context_line":"        self.dev_lock \u003d None"},{"line_number":107,"context_line":"        self._last_recon_update \u003d 0"},{"line_number":108,"context_line":"        self.recon_interval \u003d float(conf.get(\u0027recon_interval\u0027, 300.0))"},{"line_number":109,"context_line":"        self.diskfile_router \u003d diskfile.DiskFileRouter(self.conf, self.logger)"},{"line_number":110,"context_line":"        self.stats \u003d _zero_stats()"},{"line_number":111,"context_line":"        self.devices_data \u003d {}"}],"source_content_type":"text/x-python","patch_set":33,"id":"c996d52e_befa4a76","line":108,"range":{"start_line":108,"start_character":8,"end_line":108,"end_character":27},"updated":"2021-04-28 16:04:15.000000000","message":"still needs changing to stats_interval","commit_id":"00de6d5191f78fe694b26205868894b0f52b299a"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7a0500eb3b3152b939255184b9bcb9514b66c589","unresolved":true,"context_lines":[{"line_number":104,"context_line":"        self.part_power \u003d self.next_part_power \u003d None"},{"line_number":105,"context_line":"        self.diskfile_mgr \u003d None"},{"line_number":106,"context_line":"        self.dev_lock \u003d None"},{"line_number":107,"context_line":"        self._last_recon_update \u003d 0"},{"line_number":108,"context_line":"        self.stats_interval \u003d float(conf.get(\u0027stats_interval\u0027, 300.0))"},{"line_number":109,"context_line":"        self.diskfile_router \u003d diskfile.DiskFileRouter(self.conf, self.logger)"},{"line_number":110,"context_line":"        self.stats \u003d _zero_stats()"}],"source_content_type":"text/x-python","patch_set":35,"id":"9f72b725_d5ed1d44","line":107,"updated":"2021-04-29 20:02:46.000000000","message":"Better as zero, or now?","commit_id":"0e91c39cc002e93bbd5fe41ebf079431c960614a"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"3de413559ee4837cce29ef3b30b0d14d392828ba","unresolved":false,"context_lines":[{"line_number":104,"context_line":"        self.part_power \u003d self.next_part_power \u003d None"},{"line_number":105,"context_line":"        self.diskfile_mgr \u003d None"},{"line_number":106,"context_line":"        self.dev_lock \u003d None"},{"line_number":107,"context_line":"        self._last_recon_update \u003d 0"},{"line_number":108,"context_line":"        self.stats_interval \u003d float(conf.get(\u0027stats_interval\u0027, 300.0))"},{"line_number":109,"context_line":"        self.diskfile_router \u003d diskfile.DiskFileRouter(self.conf, self.logger)"},{"line_number":110,"context_line":"        self.stats \u003d _zero_stats()"}],"source_content_type":"text/x-python","patch_set":35,"id":"9c527c35_8fa595c0","line":107,"in_reply_to":"9f72b725_d5ed1d44","updated":"2021-04-30 07:18:09.000000000","message":"Done","commit_id":"0e91c39cc002e93bbd5fe41ebf079431c960614a"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7a0500eb3b3152b939255184b9bcb9514b66c589","unresolved":true,"context_lines":[{"line_number":109,"context_line":"        self.diskfile_router \u003d diskfile.DiskFileRouter(self.conf, self.logger)"},{"line_number":110,"context_line":"        self.stats \u003d _zero_stats()"},{"line_number":111,"context_line":"        self.devices_data \u003d {}"},{"line_number":112,"context_line":"        self.policy_count \u003d 0"},{"line_number":113,"context_line":"        self.pid \u003d os.getpid()"},{"line_number":114,"context_line":""},{"line_number":115,"context_line":"    def _update_recon(self, device\u003dNone, force_dump\u003dFalse):"}],"source_content_type":"text/x-python","patch_set":35,"id":"17fda440_16f8d886","line":112,"updated":"2021-04-29 20:02:46.000000000","message":"+1, I like getting this out of the stats dict -- we\u0027re using this key very differently from the rest of it.","commit_id":"0e91c39cc002e93bbd5fe41ebf079431c960614a"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7a0500eb3b3152b939255184b9bcb9514b66c589","unresolved":true,"context_lines":[{"line_number":120,"context_line":"        if device:"},{"line_number":121,"context_line":"            # dump recon stats for the device"},{"line_number":122,"context_line":"            num_parts_done \u003d sum("},{"line_number":123,"context_line":"                1 for part in self.states[\"state\"].values()"},{"line_number":124,"context_line":"                if part)"},{"line_number":125,"context_line":"            num_total_parts \u003d len(self.states[\"state\"])"},{"line_number":126,"context_line":"            step \u003d STEP_CLEANUP if self.do_cleanup else STEP_RELINK"}],"source_content_type":"text/x-python","patch_set":35,"id":"44f5ff8e_a00a6563","line":123,"range":{"start_line":123,"start_character":22,"end_line":123,"end_character":26},"updated":"2021-04-29 20:02:46.000000000","message":"nit: better named to part_done?","commit_id":"0e91c39cc002e93bbd5fe41ebf079431c960614a"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"3de413559ee4837cce29ef3b30b0d14d392828ba","unresolved":false,"context_lines":[{"line_number":120,"context_line":"        if device:"},{"line_number":121,"context_line":"            # dump recon stats for the device"},{"line_number":122,"context_line":"            num_parts_done \u003d sum("},{"line_number":123,"context_line":"                1 for part in self.states[\"state\"].values()"},{"line_number":124,"context_line":"                if part)"},{"line_number":125,"context_line":"            num_total_parts \u003d len(self.states[\"state\"])"},{"line_number":126,"context_line":"            step \u003d STEP_CLEANUP if self.do_cleanup else STEP_RELINK"}],"source_content_type":"text/x-python","patch_set":35,"id":"ac70854e_9982c3c0","line":123,"range":{"start_line":123,"start_character":22,"end_line":123,"end_character":26},"in_reply_to":"44f5ff8e_a00a6563","updated":"2021-04-30 07:18:09.000000000","message":"Done","commit_id":"0e91c39cc002e93bbd5fe41ebf079431c960614a"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7a0500eb3b3152b939255184b9bcb9514b66c589","unresolved":true,"context_lines":[{"line_number":143,"context_line":"        recon_data \u003d self._update_worker_stats(recon_dump\u003dFalse)"},{"line_number":144,"context_line":""},{"line_number":145,"context_line":"        recon_data.update({\u0027devices\u0027: self.devices_data})"},{"line_number":146,"context_line":"        self.logger.debug(\"Updating recon for %s: %s\" % (device, recon_data))"},{"line_number":147,"context_line":"        self._last_recon_update \u003d time.time()"},{"line_number":148,"context_line":"        dump_recon_cache(recon_data, self.recon_cache, self.logger)"},{"line_number":149,"context_line":""}],"source_content_type":"text/x-python","patch_set":35,"id":"8dad6a93_4a270257","line":146,"updated":"2021-04-29 20:02:46.000000000","message":"This still feels a noisy, especially given how big these recon dicts are getting. Should we just drop this logging?","commit_id":"0e91c39cc002e93bbd5fe41ebf079431c960614a"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"3de413559ee4837cce29ef3b30b0d14d392828ba","unresolved":true,"context_lines":[{"line_number":143,"context_line":"        recon_data \u003d self._update_worker_stats(recon_dump\u003dFalse)"},{"line_number":144,"context_line":""},{"line_number":145,"context_line":"        recon_data.update({\u0027devices\u0027: self.devices_data})"},{"line_number":146,"context_line":"        self.logger.debug(\"Updating recon for %s: %s\" % (device, recon_data))"},{"line_number":147,"context_line":"        self._last_recon_update \u003d time.time()"},{"line_number":148,"context_line":"        dump_recon_cache(recon_data, self.recon_cache, self.logger)"},{"line_number":149,"context_line":""}],"source_content_type":"text/x-python","patch_set":35,"id":"715f0daf_9d52d7fb","line":146,"in_reply_to":"8dad6a93_4a270257","updated":"2021-04-30 07:18:09.000000000","message":"Simplified it to: \n  self.logger.debug(\"Updating recon for %s\" % device)","commit_id":"0e91c39cc002e93bbd5fe41ebf079431c960614a"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7a0500eb3b3152b939255184b9bcb9514b66c589","unresolved":true,"context_lines":[{"line_number":651,"context_line":"def parallel_process(do_cleanup, conf, logger\u003dNone, device_list\u003dNone):"},{"line_number":652,"context_line":"    logger \u003d logger or logging.getLogger()"},{"line_number":653,"context_line":""},{"line_number":654,"context_line":"    # inialise recon dump for collection"},{"line_number":655,"context_line":"    # Lets start by always deleting last run\u0027s stats"},{"line_number":656,"context_line":"    recon_cache \u003d os.path.join(conf[\u0027recon_cache_path\u0027], RECON_FILE)"},{"line_number":657,"context_line":"    _reset_recon(recon_cache, logger)"}],"source_content_type":"text/x-python","patch_set":35,"id":"fad1c41b_dfb6e9d7","line":654,"range":{"start_line":654,"start_character":6,"end_line":654,"end_character":14},"updated":"2021-04-29 20:02:46.000000000","message":"initialise (though if I\u0027m the one fixing it, it\u0027ll probably come out initialize ;-)","commit_id":"0e91c39cc002e93bbd5fe41ebf079431c960614a"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"3de413559ee4837cce29ef3b30b0d14d392828ba","unresolved":false,"context_lines":[{"line_number":651,"context_line":"def parallel_process(do_cleanup, conf, logger\u003dNone, device_list\u003dNone):"},{"line_number":652,"context_line":"    logger \u003d logger or logging.getLogger()"},{"line_number":653,"context_line":""},{"line_number":654,"context_line":"    # inialise recon dump for collection"},{"line_number":655,"context_line":"    # Lets start by always deleting last run\u0027s stats"},{"line_number":656,"context_line":"    recon_cache \u003d os.path.join(conf[\u0027recon_cache_path\u0027], RECON_FILE)"},{"line_number":657,"context_line":"    _reset_recon(recon_cache, logger)"}],"source_content_type":"text/x-python","patch_set":35,"id":"66323823_a85c22cc","line":654,"range":{"start_line":654,"start_character":6,"end_line":654,"end_character":14},"in_reply_to":"fad1c41b_dfb6e9d7","updated":"2021-04-30 07:18:09.000000000","message":"Done","commit_id":"0e91c39cc002e93bbd5fe41ebf079431c960614a"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7a0500eb3b3152b939255184b9bcb9514b66c589","unresolved":true,"context_lines":[{"line_number":654,"context_line":"    # inialise recon dump for collection"},{"line_number":655,"context_line":"    # Lets start by always deleting last run\u0027s stats"},{"line_number":656,"context_line":"    recon_cache \u003d os.path.join(conf[\u0027recon_cache_path\u0027], RECON_FILE)"},{"line_number":657,"context_line":"    _reset_recon(recon_cache, logger)"},{"line_number":658,"context_line":""},{"line_number":659,"context_line":"    device_list \u003d sorted(set(device_list or os.listdir(conf[\u0027devices\u0027])))"},{"line_number":660,"context_line":"    workers \u003d conf[\u0027workers\u0027]"}],"source_content_type":"text/x-python","patch_set":35,"id":"7aa21893_3de40c9d","line":657,"updated":"2021-04-29 20:02:46.000000000","message":"Yeah, I think I\u0027m fine with this -- if you want useful recon, you gotta move away from manually managing your own workers.","commit_id":"0e91c39cc002e93bbd5fe41ebf079431c960614a"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"a441c3c4b62ddfd64e4533b2cdce02d700d271f5","unresolved":true,"context_lines":[{"line_number":105,"context_line":"        self.diskfile_mgr \u003d None"},{"line_number":106,"context_line":"        self.dev_lock \u003d None"},{"line_number":107,"context_line":"        self._last_recon_update \u003d time.time()"},{"line_number":108,"context_line":"        self.stats_interval \u003d float(conf.get(\u0027stats_interval\u0027, 300.0))"},{"line_number":109,"context_line":"        self.diskfile_router \u003d diskfile.DiskFileRouter(self.conf, self.logger)"},{"line_number":110,"context_line":"        self.stats \u003d _zero_stats()"},{"line_number":111,"context_line":"        self.devices_data \u003d {}"}],"source_content_type":"text/x-python","patch_set":37,"id":"08720611_24dccf14","line":108,"range":{"start_line":108,"start_character":30,"end_line":108,"end_character":35},"updated":"2021-04-30 12:00:48.000000000","message":"in main this has to be non-negative float, but as commented there, it should be int anyway for consistency","commit_id":"2fad8e44627d07829aa7bb369d7641c4ce3dce16"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"722ce98aa872ff2e46abef53ec70d92506587096","unresolved":true,"context_lines":[{"line_number":105,"context_line":"        self.diskfile_mgr \u003d None"},{"line_number":106,"context_line":"        self.dev_lock \u003d None"},{"line_number":107,"context_line":"        self._last_recon_update \u003d time.time()"},{"line_number":108,"context_line":"        self.stats_interval \u003d float(conf.get(\u0027stats_interval\u0027, 300.0))"},{"line_number":109,"context_line":"        self.diskfile_router \u003d diskfile.DiskFileRouter(self.conf, self.logger)"},{"line_number":110,"context_line":"        self.stats \u003d _zero_stats()"},{"line_number":111,"context_line":"        self.devices_data \u003d {}"}],"source_content_type":"text/x-python","patch_set":37,"id":"ff5f8640_ad1316b2","line":108,"range":{"start_line":108,"start_character":30,"end_line":108,"end_character":35},"in_reply_to":"08720611_24dccf14","updated":"2021-04-30 17:42:11.000000000","message":"or .. make the int in replicator be a float - Clay likes floats","commit_id":"2fad8e44627d07829aa7bb369d7641c4ce3dce16"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"a441c3c4b62ddfd64e4533b2cdce02d700d271f5","unresolved":true,"context_lines":[{"line_number":107,"context_line":"        self._last_recon_update \u003d time.time()"},{"line_number":108,"context_line":"        self.stats_interval \u003d float(conf.get(\u0027stats_interval\u0027, 300.0))"},{"line_number":109,"context_line":"        self.diskfile_router \u003d diskfile.DiskFileRouter(self.conf, self.logger)"},{"line_number":110,"context_line":"        self.stats \u003d _zero_stats()"},{"line_number":111,"context_line":"        self.devices_data \u003d {}"},{"line_number":112,"context_line":"        self.policy_count \u003d 0"},{"line_number":113,"context_line":"        self.pid \u003d os.getpid()"}],"source_content_type":"text/x-python","patch_set":37,"id":"b8e85717_0132810b","line":110,"updated":"2021-04-30 12:00:48.000000000","message":"ok, so self.stats has changed from being stats for whole life of this Relinker instance to per-device-per-policy stats that is reset for each device\n\nnit: maybe rename to indicate that e.g. self.current_device_stats\n\nall the stats and nested dicts makes my head spin :)","commit_id":"2fad8e44627d07829aa7bb369d7641c4ce3dce16"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"a441c3c4b62ddfd64e4533b2cdce02d700d271f5","unresolved":true,"context_lines":[{"line_number":108,"context_line":"        self.stats_interval \u003d float(conf.get(\u0027stats_interval\u0027, 300.0))"},{"line_number":109,"context_line":"        self.diskfile_router \u003d diskfile.DiskFileRouter(self.conf, self.logger)"},{"line_number":110,"context_line":"        self.stats \u003d _zero_stats()"},{"line_number":111,"context_line":"        self.devices_data \u003d {}"},{"line_number":112,"context_line":"        self.policy_count \u003d 0"},{"line_number":113,"context_line":"        self.pid \u003d os.getpid()"},{"line_number":114,"context_line":""}],"source_content_type":"text/x-python","patch_set":37,"id":"0813de97_d00e7fcb","line":111,"updated":"2021-04-30 12:00:48.000000000","message":"nit: a comment wouldn\u0027t hurt to remind us what this data structure collects:\n\n  # stats for each device are added to this dict as devices are visited","commit_id":"2fad8e44627d07829aa7bb369d7641c4ce3dce16"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"a441c3c4b62ddfd64e4533b2cdce02d700d271f5","unresolved":true,"context_lines":[{"line_number":112,"context_line":"        self.policy_count \u003d 0"},{"line_number":113,"context_line":"        self.pid \u003d os.getpid()"},{"line_number":114,"context_line":""},{"line_number":115,"context_line":"    def _aggregate_dev_policy_stats_to_drive(self):"},{"line_number":116,"context_line":"        for dev in self.devices_data.keys():"},{"line_number":117,"context_line":"            self.devices_data[dev].update(_zero_collated_stats())"},{"line_number":118,"context_line":"            for policy_data in self.devices_data[dev].get("}],"source_content_type":"text/x-python","patch_set":37,"id":"2f468074_5ddabd74","line":115,"range":{"start_line":115,"start_character":39,"end_line":115,"end_character":44},"updated":"2021-04-30 12:00:48.000000000","message":"nit: pls use device rather than drive for consistency, or just \u0027_aggregate_dev_policy_stats\u0027","commit_id":"2fad8e44627d07829aa7bb369d7641c4ce3dce16"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"a441c3c4b62ddfd64e4533b2cdce02d700d271f5","unresolved":true,"context_lines":[{"line_number":113,"context_line":"        self.pid \u003d os.getpid()"},{"line_number":114,"context_line":""},{"line_number":115,"context_line":"    def _aggregate_dev_policy_stats_to_drive(self):"},{"line_number":116,"context_line":"        for dev in self.devices_data.keys():"},{"line_number":117,"context_line":"            self.devices_data[dev].update(_zero_collated_stats())"},{"line_number":118,"context_line":"            for policy_data in self.devices_data[dev].get("},{"line_number":119,"context_line":"                    \u0027policies\u0027, {}).values():"}],"source_content_type":"text/x-python","patch_set":37,"id":"1f4d94a6_fa216538","line":116,"range":{"start_line":116,"start_character":8,"end_line":116,"end_character":43},"updated":"2021-04-30 12:00:48.000000000","message":"simpler with\n\n  for dev_data in self.devices_data.values():","commit_id":"2fad8e44627d07829aa7bb369d7641c4ce3dce16"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"a441c3c4b62ddfd64e4533b2cdce02d700d271f5","unresolved":true,"context_lines":[{"line_number":131,"context_line":"                if part_done)"},{"line_number":132,"context_line":"            num_total_parts \u003d len(self.states[\"state\"])"},{"line_number":133,"context_line":"            step \u003d STEP_CLEANUP if self.do_cleanup else STEP_RELINK"},{"line_number":134,"context_line":"            policy_dev_progress \u003d {\u0027step\u0027: step,"},{"line_number":135,"context_line":"                                   \u0027parts_done\u0027: num_parts_done,"},{"line_number":136,"context_line":"                                   \u0027total_parts\u0027: num_total_parts,"},{"line_number":137,"context_line":"                                   \u0027timestamp\u0027: time.time()}"}],"source_content_type":"text/x-python","patch_set":37,"id":"34063938_697a9104","line":134,"range":{"start_line":134,"start_character":35,"end_line":134,"end_character":47},"updated":"2021-04-30 12:00:48.000000000","message":"step is going to be the same for all policies and devices, and since the recon file is wiped at start of process then it will only be one step per recon file.\n\nif we ever did somehow have different steps per policy than the aggregation would get confusing\n\nso maybe step could move to \u0027workers\u0027 where we also have the device list or even a new top level key?","commit_id":"2fad8e44627d07829aa7bb369d7641c4ce3dce16"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"a441c3c4b62ddfd64e4533b2cdce02d700d271f5","unresolved":true,"context_lines":[{"line_number":146,"context_line":"        recon_data \u003d self._update_worker_stats(recon_dump\u003dFalse)"},{"line_number":147,"context_line":""},{"line_number":148,"context_line":"        recon_data.update({\u0027devices\u0027: self.devices_data})"},{"line_number":149,"context_line":"        self.logger.debug(\"Updating recon for %s\" % device)"},{"line_number":150,"context_line":"        self._last_recon_update \u003d time.time()"},{"line_number":151,"context_line":"        dump_recon_cache(recon_data, self.recon_cache, self.logger)"},{"line_number":152,"context_line":""}],"source_content_type":"text/x-python","patch_set":37,"id":"390af25c_6a6de9f7","line":149,"updated":"2021-04-30 12:00:48.000000000","message":"I see:\n\n  Apr 30 10:59:35 saio object-6010[1590]: [pid\u003d1590, devs\u003dsdb1] Updating recon for sdb1\nApr 30 10:59:35 saio object-6010[1590]: [pid\u003d1590, devs\u003dsdb1] Updating recon for None\nA\n\nthe \u0027None\u0027 is disconcerting IMHO.\n\nGiven the aggregating etc is the update strictly confined to one device, or might the log be better in the \u0027if device\u0027 clause? or modify the log message when device is None","commit_id":"2fad8e44627d07829aa7bb369d7641c4ce3dce16"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"a441c3c4b62ddfd64e4533b2cdce02d700d271f5","unresolved":true,"context_lines":[{"line_number":214,"context_line":"        device \u003d os.path.basename(device_path)"},{"line_number":215,"context_line":"        pol_stats \u003d self.devices_data[device][\u0027policies\u0027][self.policy.idx]"},{"line_number":216,"context_line":"        total_time \u003d time.time() - pol_stats[\u0027start_time\u0027]"},{"line_number":217,"context_line":"        pol_stats.update({\u0027total_time\u0027: total_time, \u0027stats\u0027: self.stats})"},{"line_number":218,"context_line":"        self._update_recon(device, force_dump\u003dTrue)"},{"line_number":219,"context_line":""},{"line_number":220,"context_line":"    def partitions_filter(self, datadir_path, partitions):"}],"source_content_type":"text/x-python","patch_set":37,"id":"5c625c87_359970a1","line":217,"updated":"2021-04-30 12:00:48.000000000","message":"so I think this is the only time self.stats is added to the device data? should/could it be updated periodically?\n\nis the presence of total_time and stats what tells us that the device has been completed?","commit_id":"2fad8e44627d07829aa7bb369d7641c4ce3dce16"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"a441c3c4b62ddfd64e4533b2cdce02d700d271f5","unresolved":true,"context_lines":[{"line_number":563,"context_line":"            hook_post_partition\u003dself.hook_post_partition,"},{"line_number":564,"context_line":"            hashes_filter\u003dself.hashes_filter,"},{"line_number":565,"context_line":"            logger\u003dself.logger,"},{"line_number":566,"context_line":"            error_counter\u003daudit_stats,"},{"line_number":567,"context_line":"            yield_hash_dirs\u003dTrue"},{"line_number":568,"context_line":"        )"},{"line_number":569,"context_line":"        if self.conf[\u0027files_per_second\u0027] \u003e 0:"}],"source_content_type":"text/x-python","patch_set":37,"id":"189c38ea_63e1549e","line":566,"updated":"2021-04-30 12:00:48.000000000","message":"+1 self.stats is now per-device so this is better being a separate dict","commit_id":"2fad8e44627d07829aa7bb369d7641c4ce3dce16"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"a441c3c4b62ddfd64e4533b2cdce02d700d271f5","unresolved":true,"context_lines":[{"line_number":589,"context_line":"            device \u003d os.path.basename(device_path)"},{"line_number":590,"context_line":"            self.place_policy_stat(device, policy, \u0027unlistable_partitions\u0027, 1)"},{"line_number":591,"context_line":""},{"line_number":592,"context_line":"    def _update_worker_stats(self, recon_dump\u003dTrue, return_code\u003dNone):"},{"line_number":593,"context_line":"        worker_stats \u003d {\u0027devices\u0027: self.device_list,"},{"line_number":594,"context_line":"                        \u0027timestamp\u0027: time.time(),"},{"line_number":595,"context_line":"                        \u0027return_code\u0027: return_code}"}],"source_content_type":"text/x-python","patch_set":37,"id":"8617c0dc_a40221b9","line":592,"updated":"2021-04-30 12:00:48.000000000","message":"nit: this is called earlier in the file could be relocated to above the first call site","commit_id":"2fad8e44627d07829aa7bb369d7641c4ce3dce16"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"a441c3c4b62ddfd64e4533b2cdce02d700d271f5","unresolved":true,"context_lines":[{"line_number":600,"context_line":""},{"line_number":601,"context_line":"    def run(self):"},{"line_number":602,"context_line":"        num_policies \u003d 0"},{"line_number":603,"context_line":"        self._update_worker_stats()"},{"line_number":604,"context_line":"        for policy in self.conf[\u0027policies\u0027]:"},{"line_number":605,"context_line":"            self.policy \u003d policy"},{"line_number":606,"context_line":"            policy.object_ring \u003d None  # Ensure it will be reloaded"}],"source_content_type":"text/x-python","patch_set":37,"id":"6fe55c2e_c7341c2c","line":603,"updated":"2021-04-30 12:00:48.000000000","message":"ok, this is like hello, I\u0027m running","commit_id":"2fad8e44627d07829aa7bb369d7641c4ce3dce16"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"a441c3c4b62ddfd64e4533b2cdce02d700d271f5","unresolved":true,"context_lines":[{"line_number":615,"context_line":"            num_policies +\u003d 1"},{"line_number":616,"context_line":"            self.process_policy(policy)"},{"line_number":617,"context_line":""},{"line_number":618,"context_line":"        # Some stat collation happens during _update_recon and we want to force"},{"line_number":619,"context_line":"        # this to happen at the end of the run"},{"line_number":620,"context_line":"        self._update_recon(force_dump\u003dTrue)"},{"line_number":621,"context_line":"        if not num_policies:"},{"line_number":622,"context_line":"            self.logger.warning("},{"line_number":623,"context_line":"                \"No policy found to increase the partition power.\")"},{"line_number":624,"context_line":"            self._update_worker_stats(return_code\u003dEXIT_NO_APPLICABLE_POLICY)"}],"source_content_type":"text/x-python","patch_set":37,"id":"2c639b8e_a533d604","line":621,"range":{"start_line":618,"start_character":0,"end_line":621,"end_character":0},"updated":"2021-04-30 12:00:48.000000000","message":"I think this is to make sure that any audit_errors get dumped to recon? should we be doing this at the end of each policy (so the unmounted errors get reported sooner)","commit_id":"2fad8e44627d07829aa7bb369d7641c4ce3dce16"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"a441c3c4b62ddfd64e4533b2cdce02d700d271f5","unresolved":true,"context_lines":[{"line_number":641,"context_line":"        linked \u003d stats.pop(\u0027linked\u0027)"},{"line_number":642,"context_line":"        removed \u003d stats.pop(\u0027removed\u0027)"},{"line_number":643,"context_line":"        action_errors \u003d stats.pop(\u0027errors\u0027)"},{"line_number":644,"context_line":"        unmounted \u003d stats.pop(\u0027unmounted\u0027, 0)"},{"line_number":645,"context_line":"        if unmounted:"},{"line_number":646,"context_line":"            self.logger.warning(\u0027%d disks were unmounted\u0027, unmounted)"},{"line_number":647,"context_line":"        listdir_errors \u003d stats.pop(\u0027unlistable_partitions\u0027, 0)"}],"source_content_type":"text/x-python","patch_set":37,"id":"35e70a46_5f6ad2ec","line":644,"updated":"2021-04-30 12:00:48.000000000","message":"ok, so place_policy_stats put these into \n\n  devices/dev/policies/policy_index/stats\n\nthen update_recon calls _aggregate_dev_policy_stats() which aggregates all\n\n  devices/dev/policies/*/stats\n\ninto\n\n devices/dev/stats\n\nand then aggregate_stats aggregates\n\n devices/dev/stats\n\ninto \u0027stats\u0027","commit_id":"2fad8e44627d07829aa7bb369d7641c4ce3dce16"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"a441c3c4b62ddfd64e4533b2cdce02d700d271f5","unresolved":true,"context_lines":[{"line_number":833,"context_line":"            else non_negative_int(conf.get(\u0027link_check_limit\u0027, 2))),"},{"line_number":834,"context_line":"        \u0027recon_cache_path\u0027: conf.get(\u0027recon_cache_path\u0027,"},{"line_number":835,"context_line":"                                     DEFAULT_RECON_CACHE_PATH),"},{"line_number":836,"context_line":"        \u0027stats_interval\u0027: non_negative_float(conf.get(\u0027stats_interval\u0027,"},{"line_number":837,"context_line":"                                                      300.0)),"},{"line_number":838,"context_line":"    })"},{"line_number":839,"context_line":"    return parallel_process("}],"source_content_type":"text/x-python","patch_set":37,"id":"54bd24b2_4044b60a","line":836,"range":{"start_line":836,"start_character":26,"end_line":836,"end_character":45},"updated":"2021-04-30 12:00:48.000000000","message":"it has to be an int in replicator and reconstructor, so makes sense for that to be the same here for consistency","commit_id":"2fad8e44627d07829aa7bb369d7641c4ce3dce16"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"722ce98aa872ff2e46abef53ec70d92506587096","unresolved":true,"context_lines":[{"line_number":833,"context_line":"            else non_negative_int(conf.get(\u0027link_check_limit\u0027, 2))),"},{"line_number":834,"context_line":"        \u0027recon_cache_path\u0027: conf.get(\u0027recon_cache_path\u0027,"},{"line_number":835,"context_line":"                                     DEFAULT_RECON_CACHE_PATH),"},{"line_number":836,"context_line":"        \u0027stats_interval\u0027: non_negative_float(conf.get(\u0027stats_interval\u0027,"},{"line_number":837,"context_line":"                                                      300.0)),"},{"line_number":838,"context_line":"    })"},{"line_number":839,"context_line":"    return parallel_process("}],"source_content_type":"text/x-python","patch_set":37,"id":"03b5647f_a1562ee5","line":836,"range":{"start_line":836,"start_character":26,"end_line":836,"end_character":45},"in_reply_to":"54bd24b2_4044b60a","updated":"2021-04-30 17:42:11.000000000","message":"Clay says go the other way - change replicator option to allow float","commit_id":"2fad8e44627d07829aa7bb369d7641c4ce3dce16"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"33842612f19a4cb329e72479ed5923fe82a397f7","unresolved":true,"context_lines":[{"line_number":834,"context_line":"        \u0027recon_cache_path\u0027: conf.get(\u0027recon_cache_path\u0027,"},{"line_number":835,"context_line":"                                     DEFAULT_RECON_CACHE_PATH),"},{"line_number":836,"context_line":"        \u0027stats_interval\u0027: non_negative_float(conf.get(\u0027stats_interval\u0027,"},{"line_number":837,"context_line":"                                                      300.0)),"},{"line_number":838,"context_line":"    })"},{"line_number":839,"context_line":"    return parallel_process("},{"line_number":840,"context_line":"        args.action \u003d\u003d \u0027cleanup\u0027, conf, logger, args.device_list)"}],"source_content_type":"text/x-python","patch_set":37,"id":"9416a109_77ae0c05","line":837,"updated":"2021-05-04 22:37:28.000000000","message":"Might want to allow this to be overridden from the CLI.","commit_id":"2fad8e44627d07829aa7bb369d7641c4ce3dce16"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"33842612f19a4cb329e72479ed5923fe82a397f7","unresolved":true,"context_lines":[{"line_number":150,"context_line":"        recon_data \u003d self._update_worker_stats(recon_dump\u003dFalse)"},{"line_number":151,"context_line":""},{"line_number":152,"context_line":"        recon_data.update({\u0027devices\u0027: self.devices_data})"},{"line_number":153,"context_line":"        self.logger.debug(\"Updating recon for %s\" % device)"},{"line_number":154,"context_line":"        self._last_recon_update \u003d time.time()"},{"line_number":155,"context_line":"        dump_recon_cache(recon_data, self.recon_cache, self.logger)"},{"line_number":156,"context_line":""}],"source_content_type":"text/x-python","patch_set":38,"id":"f825f140_c7127d97","line":153,"updated":"2021-05-04 22:37:28.000000000","message":"Looks a little funky when device is None. I know Al noticed it, too.","commit_id":"3b71653c272e6a900271be573f76e3e4a3740405"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"bc5a12d981bbaefe60325868876bbf611e0800b5","unresolved":true,"context_lines":[{"line_number":60,"context_line":"def _aggregate_stats(base_stats, update_stats):"},{"line_number":61,"context_line":"    for key, value in update_stats.items():"},{"line_number":62,"context_line":"        base_stats.setdefault(key, 0)"},{"line_number":63,"context_line":"        base_stats[key] +\u003d value"},{"line_number":64,"context_line":""},{"line_number":65,"context_line":"    return base_stats"},{"line_number":66,"context_line":""}],"source_content_type":"text/x-python","patch_set":39,"id":"58801430_55e6973c","line":63,"updated":"2021-05-07 04:20:34.000000000","message":"FWIW, this all reminds me of swift.obj.replicator.Stats... I\u0027m not sure what to *do* with that similarity yet, but wanted to mention it...","commit_id":"be16528597a9f5b0a51e4e9d56df2e07f275e7c2"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"bc5a12d981bbaefe60325868876bbf611e0800b5","unresolved":true,"context_lines":[{"line_number":93,"context_line":"        \u0027parts_done\u0027: 0,"},{"line_number":94,"context_line":"        \u0027total_parts\u0027: 0,"},{"line_number":95,"context_line":"        \u0027total_time\u0027: 0,"},{"line_number":96,"context_line":"        \u0027stats\u0027: _zero_stats()}"},{"line_number":97,"context_line":""},{"line_number":98,"context_line":""},{"line_number":99,"context_line":"class Relinker(object):"}],"source_content_type":"text/x-python","patch_set":39,"id":"7b3f0bfc_417e0919","line":96,"updated":"2021-05-07 04:20:34.000000000","message":"Right, so start_time and timestamp aren\u0027t included at init; they only come across as disks finish.","commit_id":"be16528597a9f5b0a51e4e9d56df2e07f275e7c2"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"bc5a12d981bbaefe60325868876bbf611e0800b5","unresolved":true,"context_lines":[{"line_number":110,"context_line":"        self.part_power \u003d self.next_part_power \u003d None"},{"line_number":111,"context_line":"        self.diskfile_mgr \u003d None"},{"line_number":112,"context_line":"        self.dev_lock \u003d None"},{"line_number":113,"context_line":"        self._last_recon_update \u003d time.time()"},{"line_number":114,"context_line":"        self.stats_interval \u003d float(conf.get("},{"line_number":115,"context_line":"            \u0027stats_interval\u0027, DEFAULT_STATS_INTERVAL))"},{"line_number":116,"context_line":"        self.diskfile_router \u003d diskfile.DiskFileRouter(self.conf, self.logger)"}],"source_content_type":"text/x-python","patch_set":39,"id":"cf5f8a82_ce4cd82e","line":113,"updated":"2021-05-07 04:20:34.000000000","message":"FWIW, I wasn\u0027t actually sure about whether 0 or time.time() was better, but I was leaning towards this way ;-)","commit_id":"be16528597a9f5b0a51e4e9d56df2e07f275e7c2"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"bc5a12d981bbaefe60325868876bbf611e0800b5","unresolved":true,"context_lines":[{"line_number":114,"context_line":"        self.stats_interval \u003d float(conf.get("},{"line_number":115,"context_line":"            \u0027stats_interval\u0027, DEFAULT_STATS_INTERVAL))"},{"line_number":116,"context_line":"        self.diskfile_router \u003d diskfile.DiskFileRouter(self.conf, self.logger)"},{"line_number":117,"context_line":"        self.stats \u003d _zero_stats()"},{"line_number":118,"context_line":"        self.devices_data \u003d recursive_defaultdict()"},{"line_number":119,"context_line":"        self.policy_count \u003d 0"},{"line_number":120,"context_line":"        self.pid \u003d os.getpid()"}],"source_content_type":"text/x-python","patch_set":39,"id":"1c2cf6a5_0a351340","line":117,"updated":"2021-05-07 04:20:34.000000000","message":"If we\u0027re setting this in the pre-device hook, we no longer need it here, yeah? Actually, I wonder if we still need self.stats *at all*... something like http://paste.openstack.org/show/805019/ gets me pretty darn close to still having tests passing...","commit_id":"be16528597a9f5b0a51e4e9d56df2e07f275e7c2"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"bc5a12d981bbaefe60325868876bbf611e0800b5","unresolved":true,"context_lines":[{"line_number":165,"context_line":"        # level"},{"line_number":166,"context_line":"        self._aggregate_dev_policy_stats()"},{"line_number":167,"context_line":"        return sum([sum(["},{"line_number":168,"context_line":"            dev.get(\u0027stats\u0027, {}).get(\u0027errors\u0027, 0),"},{"line_number":169,"context_line":"            dev.get(\u0027stats\u0027, {}).get(\u0027unmounted\u0027, 0),"},{"line_number":170,"context_line":"            dev.get(\u0027stats\u0027, {}).get(\u0027unlistable_partitions\u0027, 0)])"},{"line_number":171,"context_line":"            for dev in self.devices_data.values()])"}],"source_content_type":"text/x-python","patch_set":39,"id":"3a623656_2afaa203","line":168,"range":{"start_line":168,"start_character":12,"end_line":168,"end_character":32},"updated":"2021-05-07 04:20:34.000000000","message":"Would we ever have a dev without a stats key? I feel like that\u0027s part of the appeal of _zero_collated_stats()...","commit_id":"be16528597a9f5b0a51e4e9d56df2e07f275e7c2"}],"swift/common/middleware/recon.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"8cb4f1b3dbbc6a4e5704ebab8600ed991ce8d54f","unresolved":true,"context_lines":[{"line_number":47,"context_line":"        swift_dir \u003d conf.get(\u0027swift_dir\u0027, \u0027/etc/swift\u0027)"},{"line_number":48,"context_line":"        self.logger \u003d get_logger(conf, log_route\u003d\u0027recon\u0027)"},{"line_number":49,"context_line":"        self.recon_cache_path \u003d conf.get(\u0027recon_cache_path\u0027,"},{"line_number":50,"context_line":"                                         \u0027/var/cache/swift\u0027)"},{"line_number":51,"context_line":"        self.object_recon_cache \u003d os.path.join(self.recon_cache_path,"},{"line_number":52,"context_line":"                                               \u0027object.recon\u0027)"},{"line_number":53,"context_line":"        self.container_recon_cache \u003d os.path.join(self.recon_cache_path,"}],"source_content_type":"text/x-python","patch_set":10,"id":"f2425d9f_8d0348dc","line":50,"range":{"start_line":50,"start_character":42,"end_line":50,"end_character":58},"updated":"2021-03-19 15:26:33.000000000","message":"slightly off-topic: seems like this should be declared once and imported wherever else it is used e.g. in relinker.py","commit_id":"8aa713f3208a1c333b15b1f999e1aac9cec5db58"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"8cb4f1b3dbbc6a4e5704ebab8600ed991ce8d54f","unresolved":true,"context_lines":[{"line_number":57,"context_line":"        self.drive_recon_cache \u003d os.path.join(self.recon_cache_path,"},{"line_number":58,"context_line":"                                              \u0027drive.recon\u0027)"},{"line_number":59,"context_line":"        self.relink_recon_cache \u003d os.path.join(self.recon_cache_path,"},{"line_number":60,"context_line":"                                               \"relink.recon\")"},{"line_number":61,"context_line":"        self.account_ring_path \u003d os.path.join(swift_dir, \u0027account.ring.gz\u0027)"},{"line_number":62,"context_line":"        self.container_ring_path \u003d os.path.join(swift_dir, \u0027container.ring.gz\u0027)"},{"line_number":63,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"919d3066_1d4821d9","line":60,"range":{"start_line":60,"start_character":48,"end_line":60,"end_character":60},"updated":"2021-03-19 15:26:33.000000000","message":"in relinker.py we have:\n\n  RECON_FILE\n\ncould be worth declaring that in this file and importing to relinker.py? They have to remain consistent","commit_id":"8aa713f3208a1c333b15b1f999e1aac9cec5db58"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"4b15ab9cfec169c8580c83e6bc56b42b036ebde3","unresolved":true,"context_lines":[{"line_number":57,"context_line":"        self.drive_recon_cache \u003d os.path.join(self.recon_cache_path,"},{"line_number":58,"context_line":"                                              \u0027drive.recon\u0027)"},{"line_number":59,"context_line":"        self.relink_recon_cache \u003d os.path.join(self.recon_cache_path,"},{"line_number":60,"context_line":"                                               \"relink.recon\")"},{"line_number":61,"context_line":"        self.account_ring_path \u003d os.path.join(swift_dir, \u0027account.ring.gz\u0027)"},{"line_number":62,"context_line":"        self.container_ring_path \u003d os.path.join(swift_dir, \u0027container.ring.gz\u0027)"},{"line_number":63,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"08bb93df_3c44d1ce","line":60,"range":{"start_line":60,"start_character":48,"end_line":60,"end_character":60},"in_reply_to":"919d3066_1d4821d9","updated":"2021-03-21 23:03:20.000000000","message":"MAybe, but we dont seem to do it for any others. And maybe importing from a middleware looks a little weird.\n\nMaybe I\u0027ll create a follow up to clean up all recon paths to be constants. Maybe make something like swift/common/recon_defaults.py or recon_common.py or something. I\u0027ll have a play.","commit_id":"8aa713f3208a1c333b15b1f999e1aac9cec5db58"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"8cb4f1b3dbbc6a4e5704ebab8600ed991ce8d54f","unresolved":true,"context_lines":[{"line_number":336,"context_line":"        return time.time()"},{"line_number":337,"context_line":""},{"line_number":338,"context_line":"    def get_relink_info(self):"},{"line_number":339,"context_line":"        \"\"\"get relinker info, if any\"\"\""},{"line_number":340,"context_line":""},{"line_number":341,"context_line":"        return self._from_recon_cache([\"progress\"],"},{"line_number":342,"context_line":"                                      self.relink_recon_cache)"}],"source_content_type":"text/x-python","patch_set":10,"id":"49545c60_c07012fa","line":339,"range":{"start_line":339,"start_character":30,"end_line":339,"end_character":36},"updated":"2021-03-19 15:26:33.000000000","message":"AFAICT an exception is logged if there isn\u0027t any, which is unfortunate given the temporary nature of the relinker stats","commit_id":"8aa713f3208a1c333b15b1f999e1aac9cec5db58"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"4b15ab9cfec169c8580c83e6bc56b42b036ebde3","unresolved":true,"context_lines":[{"line_number":336,"context_line":"        return time.time()"},{"line_number":337,"context_line":""},{"line_number":338,"context_line":"    def get_relink_info(self):"},{"line_number":339,"context_line":"        \"\"\"get relinker info, if any\"\"\""},{"line_number":340,"context_line":""},{"line_number":341,"context_line":"        return self._from_recon_cache([\"progress\"],"},{"line_number":342,"context_line":"                                      self.relink_recon_cache)"}],"source_content_type":"text/x-python","patch_set":10,"id":"561fa47b_1cbe0a70","line":339,"range":{"start_line":339,"start_character":30,"end_line":339,"end_character":36},"in_reply_to":"49545c60_c07012fa","updated":"2021-03-21 23:03:20.000000000","message":"I guess we could add a new method or an param to _from_recon_cache to ignore errors.","commit_id":"8aa713f3208a1c333b15b1f999e1aac9cec5db58"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"134275bf7fa2f5682b76444acd3fd4888c993305","unresolved":true,"context_lines":[{"line_number":74,"context_line":"        :params cache_keys: list of cache items to retrieve"},{"line_number":75,"context_line":"        :params cache_file: cache file to retrieve items from."},{"line_number":76,"context_line":"        :params openr: open to use [for unittests]"},{"line_number":77,"context_line":"        :params ignore_errors: Some recon stats are very temporary, in this"},{"line_number":78,"context_line":"            case it would be better to not log if things are missing."},{"line_number":79,"context_line":"        :return: dict of cache items and their values or none if not found"},{"line_number":80,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":12,"id":"f9f966fe_0386ba7a","line":77,"range":{"start_line":77,"start_character":31,"end_line":77,"end_character":66},"updated":"2021-03-22 11:30:09.000000000","message":"I wasn\u0027t thinking it through fully on last review - the relinker recon file is AFAICT permanent once created - nothing removes it or even empties it after a period. But unlike other recon files the relinker recon file won\u0027t exist *until* the relinker runs.\n\nSo we either get exceptions logged if the relinker endpoint is queried before relinker has ever run, or we (as you have here) suppress the exception for relinker file, but then if relinker has run and the file goes missing there\u0027s no error log.\n\nMaybe worth getting some more opinions because I am wondering if I was wrong first time, and we should accept that if you query relinker recon before relinker runs then there\u0027s a spurious exception because otherwise we lose the exception when the file *should* exist after relinker runs.","commit_id":"d09cb426f391cae6963186b0b4b5c04cdaf9700d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"134275bf7fa2f5682b76444acd3fd4888c993305","unresolved":true,"context_lines":[{"line_number":83,"context_line":"                recondata \u003d json.load(f)"},{"line_number":84,"context_line":"                return dict((key, recondata.get(key)) for key in cache_keys)"},{"line_number":85,"context_line":"        except IOError:"},{"line_number":86,"context_line":"            if not ignore_errors:"},{"line_number":87,"context_line":"                self.logger.exception(_(\u0027Error reading recon cache file\u0027))"},{"line_number":88,"context_line":"        except ValueError:"},{"line_number":89,"context_line":"            # finding data and error parsing even if ignored seems like a good"}],"source_content_type":"text/x-python","patch_set":12,"id":"cb522638_ab291c52","line":86,"updated":"2021-03-22 11:30:09.000000000","message":"maybe narrow this to ignore just ENOENT","commit_id":"d09cb426f391cae6963186b0b4b5c04cdaf9700d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"134275bf7fa2f5682b76444acd3fd4888c993305","unresolved":true,"context_lines":[{"line_number":86,"context_line":"            if not ignore_errors:"},{"line_number":87,"context_line":"                self.logger.exception(_(\u0027Error reading recon cache file\u0027))"},{"line_number":88,"context_line":"        except ValueError:"},{"line_number":89,"context_line":"            # finding data and error parsing even if ignored seems like a good"},{"line_number":90,"context_line":"            # exception to log."},{"line_number":91,"context_line":"            self.logger.exception(_(\u0027Error parsing recon cache file\u0027))"},{"line_number":92,"context_line":"        except Exception:"},{"line_number":93,"context_line":"            if not ignore_errors:"}],"source_content_type":"text/x-python","patch_set":12,"id":"58f95bfc_4297a999","line":90,"range":{"start_line":89,"start_character":12,"end_line":90,"end_character":31},"updated":"2021-03-22 11:30:09.000000000","message":"+1\n\nso would it be better named ignore_missing?","commit_id":"d09cb426f391cae6963186b0b4b5c04cdaf9700d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"134275bf7fa2f5682b76444acd3fd4888c993305","unresolved":true,"context_lines":[{"line_number":90,"context_line":"            # exception to log."},{"line_number":91,"context_line":"            self.logger.exception(_(\u0027Error parsing recon cache file\u0027))"},{"line_number":92,"context_line":"        except Exception:"},{"line_number":93,"context_line":"            if not ignore_errors:"},{"line_number":94,"context_line":"                self.logger.exception(_(\u0027Error retrieving recon data\u0027))"},{"line_number":95,"context_line":"        return dict((key, None) for key in cache_keys)"},{"line_number":96,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"1beb6f2d_6ebbd6cc","line":93,"updated":"2021-03-22 11:30:09.000000000","message":"not sure about this - perhaps we should just be ignoring the conditions we expect (i.e file doesn\u0027t exist)","commit_id":"d09cb426f391cae6963186b0b4b5c04cdaf9700d"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"15829e7d55eeedfd975452574f5905017df0089d","unresolved":true,"context_lines":[{"line_number":57,"context_line":"        self.drive_recon_cache \u003d os.path.join(self.recon_cache_path,"},{"line_number":58,"context_line":"                                              \u0027drive.recon\u0027)"},{"line_number":59,"context_line":"        self.relink_recon_cache \u003d os.path.join(self.recon_cache_path,"},{"line_number":60,"context_line":"                                               \"relinker.recon\")"},{"line_number":61,"context_line":"        self.account_ring_path \u003d os.path.join(swift_dir, \u0027account.ring.gz\u0027)"},{"line_number":62,"context_line":"        self.container_ring_path \u003d os.path.join(swift_dir, \u0027container.ring.gz\u0027)"},{"line_number":63,"context_line":""}],"source_content_type":"text/x-python","patch_set":15,"id":"1ed0f71f_0ead0f39","line":60,"range":{"start_line":60,"start_character":48,"end_line":60,"end_character":62},"updated":"2021-03-30 20:07:39.000000000","message":"Should this come from the constant in swift.cli.relinker? I suppose the others don\u0027t do anything like that... *shrug*","commit_id":"368c931c4ebc833e76854e0b4335c9f7d43259f7"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"0eb4f2f8aa69031d82a1521b2332c248605c5829","unresolved":true,"context_lines":[{"line_number":57,"context_line":"        self.drive_recon_cache \u003d os.path.join(self.recon_cache_path,"},{"line_number":58,"context_line":"                                              \u0027drive.recon\u0027)"},{"line_number":59,"context_line":"        self.relink_recon_cache \u003d os.path.join(self.recon_cache_path,"},{"line_number":60,"context_line":"                                               \"relinker.recon\")"},{"line_number":61,"context_line":"        self.account_ring_path \u003d os.path.join(swift_dir, \u0027account.ring.gz\u0027)"},{"line_number":62,"context_line":"        self.container_ring_path \u003d os.path.join(swift_dir, \u0027container.ring.gz\u0027)"},{"line_number":63,"context_line":""}],"source_content_type":"text/x-python","patch_set":15,"id":"c840ac3d_52b493dc","line":60,"range":{"start_line":60,"start_character":48,"end_line":60,"end_character":62},"in_reply_to":"1ed0f71f_0ead0f39","updated":"2021-03-30 23:01:34.000000000","message":"yeah, totally agree. Wasn\u0027t sure if that should be imported into the middleware or visa versa. A nice follow up for recon might be to create a swift/common/recon-contants or some named file to store between the 2 files. And more so when it comes to the recon bin tool and cron.","commit_id":"368c931c4ebc833e76854e0b4335c9f7d43259f7"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"15829e7d55eeedfd975452574f5905017df0089d","unresolved":true,"context_lines":[{"line_number":75,"context_line":"        :params cache_file: cache file to retrieve items from."},{"line_number":76,"context_line":"        :params openr: open to use [for unittests]"},{"line_number":77,"context_line":"        :params ignore_missing: Some recon stats are very temporary, in this"},{"line_number":78,"context_line":"            case it would be better to not log if things are missing."},{"line_number":79,"context_line":"        :return: dict of cache items and their values or none if not found"},{"line_number":80,"context_line":"        \"\"\""},{"line_number":81,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":15,"id":"34ec4484_06505745","line":78,"updated":"2021-03-30 20:07:39.000000000","message":"I think we might prefer this quietness more generally:\n\n* https://bugs.launchpad.net/swift/+bug/1646410\n* http://lists.openstack.org/pipermail/openstack/2016-December/018065.html","commit_id":"368c931c4ebc833e76854e0b4335c9f7d43259f7"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"7eb6d7105063afca136774f4bef67d2eb7f6c95d","unresolved":true,"context_lines":[{"line_number":75,"context_line":"        :params cache_file: cache file to retrieve items from."},{"line_number":76,"context_line":"        :params openr: open to use [for unittests]"},{"line_number":77,"context_line":"        :params ignore_missing: Some recon stats are very temporary, in this"},{"line_number":78,"context_line":"            case it would be better to not log if things are missing."},{"line_number":79,"context_line":"        :return: dict of cache items and their values or none if not found"},{"line_number":80,"context_line":"        \"\"\""},{"line_number":81,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":15,"id":"0a8b2ef5_39a2a06c","line":78,"in_reply_to":"34ec4484_06505745","updated":"2021-03-31 01:14:36.000000000","message":"Oh interesting, maybe we could add ignore_missing to driveaudit too.","commit_id":"368c931c4ebc833e76854e0b4335c9f7d43259f7"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"15829e7d55eeedfd975452574f5905017df0089d","unresolved":true,"context_lines":[{"line_number":344,"context_line":"    def get_relinker_info(self):"},{"line_number":345,"context_line":"        \"\"\"get relinker info, if any\"\"\""},{"line_number":346,"context_line":""},{"line_number":347,"context_line":"        return self._from_recon_cache([\"progress\"],"},{"line_number":348,"context_line":"                                      self.relink_recon_cache,"},{"line_number":349,"context_line":"                                      ignore_missing\u003dTrue)"},{"line_number":350,"context_line":""}],"source_content_type":"text/x-python","patch_set":15,"id":"82ae05d8_270ee7df","line":347,"range":{"start_line":347,"start_character":40,"end_line":347,"end_character":48},"updated":"2021-03-30 20:07:39.000000000","message":"What do we want the API to look like when checking in on multiple policies? Policy in path? X-Backend-Storage-Policy-Index header?","commit_id":"368c931c4ebc833e76854e0b4335c9f7d43259f7"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"7eb6d7105063afca136774f4bef67d2eb7f6c95d","unresolved":true,"context_lines":[{"line_number":344,"context_line":"    def get_relinker_info(self):"},{"line_number":345,"context_line":"        \"\"\"get relinker info, if any\"\"\""},{"line_number":346,"context_line":""},{"line_number":347,"context_line":"        return self._from_recon_cache([\"progress\"],"},{"line_number":348,"context_line":"                                      self.relink_recon_cache,"},{"line_number":349,"context_line":"                                      ignore_missing\u003dTrue)"},{"line_number":350,"context_line":""}],"source_content_type":"text/x-python","patch_set":15,"id":"d14cb9a9_69ac638f","line":347,"range":{"start_line":347,"start_character":40,"end_line":347,"end_character":48},"in_reply_to":"54dc4258_f7e543b2","updated":"2021-03-31 01:14:36.000000000","message":"So now that i\u0027ve reworked it progress is now the top level for all policies. I did this in case we need to ever expend and send more stats out, or calulate the last complete or whatever can be put outside of the top level progress. Ie we may have at some point:\n\n {\n   \u0027progress\u0027{\u003cprogress stats\u003e},\n   \u0027stats\u0027 {\u003cother stats?\u003e},\n   \u0027finished_relink_cycle\u0027: \"time we finished\"\n }\n\nIn the recon api we currently use /recon/\u003cendpoint\u003e/{account,container,object} for endpoints that change specifically for different storage endpoints. So not sure we should overload this to add the policy.","commit_id":"368c931c4ebc833e76854e0b4335c9f7d43259f7"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"0eb4f2f8aa69031d82a1521b2332c248605c5829","unresolved":true,"context_lines":[{"line_number":344,"context_line":"    def get_relinker_info(self):"},{"line_number":345,"context_line":"        \"\"\"get relinker info, if any\"\"\""},{"line_number":346,"context_line":""},{"line_number":347,"context_line":"        return self._from_recon_cache([\"progress\"],"},{"line_number":348,"context_line":"                                      self.relink_recon_cache,"},{"line_number":349,"context_line":"                                      ignore_missing\u003dTrue)"},{"line_number":350,"context_line":""}],"source_content_type":"text/x-python","patch_set":15,"id":"850867e5_6fa534bc","line":347,"range":{"start_line":347,"start_character":40,"end_line":347,"end_character":48},"in_reply_to":"82ae05d8_270ee7df","updated":"2021-03-30 23:01:34.000000000","message":"oh yeah, I forgot to update for multiple polices here! great catch. I asusme on a normal recon call we want all the stats? so probably should return all policies.\n\nMaybe make the recon interface:\n\n   /recon/relinker/\u003cpolicy-id or name\u003e\n\nAnd leaving it out would be all polices?","commit_id":"368c931c4ebc833e76854e0b4335c9f7d43259f7"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"3b3b10a4f832d7a2c818a8cb726dda2e1b78e5e6","unresolved":true,"context_lines":[{"line_number":344,"context_line":"    def get_relinker_info(self):"},{"line_number":345,"context_line":"        \"\"\"get relinker info, if any\"\"\""},{"line_number":346,"context_line":""},{"line_number":347,"context_line":"        return self._from_recon_cache([\"progress\"],"},{"line_number":348,"context_line":"                                      self.relink_recon_cache,"},{"line_number":349,"context_line":"                                      ignore_missing\u003dTrue)"},{"line_number":350,"context_line":""}],"source_content_type":"text/x-python","patch_set":15,"id":"54dc4258_f7e543b2","line":347,"range":{"start_line":347,"start_character":40,"end_line":347,"end_character":48},"in_reply_to":"850867e5_6fa534bc","updated":"2021-03-30 23:30:19.000000000","message":"I like both those ideas. We\u0027ve got it all loaded up in our head anyway, may as well return it all!","commit_id":"368c931c4ebc833e76854e0b4335c9f7d43259f7"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"b7f0e3b8e061e83404a86140b60364d63a058c0e","unresolved":true,"context_lines":[{"line_number":345,"context_line":"        \"\"\"get relinker info, if any\"\"\""},{"line_number":346,"context_line":""},{"line_number":347,"context_line":"        stat_keys \u003d [get_policy_string(\u0027progress\u0027, p) for p in POLICIES]"},{"line_number":348,"context_line":"        stat_keys.extend([\u0027start_time\u0027, \u0027total_time\u0027, \u0027stats\u0027])"},{"line_number":349,"context_line":"        return self._from_recon_cache(stat_keys,"},{"line_number":350,"context_line":"                                      self.relink_recon_cache,"},{"line_number":351,"context_line":"                                      ignore_missing\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":24,"id":"acd5a0df_6bbdcae4","line":348,"updated":"2021-04-14 18:21:26.000000000","message":"this is pretty coupled with the recon dump structure - it\u0027s not obvious to me that it makes more sense for it all to be in the same patch or separate","commit_id":"5b355b34ab8c457b2f09734e3a5a6a17330932c9"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7a0500eb3b3152b939255184b9bcb9514b66c589","unresolved":true,"context_lines":[{"line_number":394,"context_line":"            content \u003d self.get_time()"},{"line_number":395,"context_line":"        elif rcheck \u003d\u003d \"sharding\":"},{"line_number":396,"context_line":"            content \u003d self.get_sharding_info()"},{"line_number":397,"context_line":"        elif rcheck \u003d\u003d \"relinker\":"},{"line_number":398,"context_line":"            content \u003d self.get_relinker_info()"},{"line_number":399,"context_line":"        else:"},{"line_number":400,"context_line":"            content \u003d \"Invalid path: %s\" % req.path"}],"source_content_type":"text/x-python","patch_set":35,"id":"d1e9a22f_c8e224e4","line":397,"updated":"2021-04-29 20:02:46.000000000","message":"Should this have a\n\n ... and rtype \u003d\u003d \u0027object\u0027\n\nsimilar to the expirer (L373)?","commit_id":"0e91c39cc002e93bbd5fe41ebf079431c960614a"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"33842612f19a4cb329e72479ed5923fe82a397f7","unresolved":true,"context_lines":[{"line_number":394,"context_line":"            content \u003d self.get_time()"},{"line_number":395,"context_line":"        elif rcheck \u003d\u003d \"sharding\":"},{"line_number":396,"context_line":"            content \u003d self.get_sharding_info()"},{"line_number":397,"context_line":"        elif rcheck \u003d\u003d \"relinker\":"},{"line_number":398,"context_line":"            content \u003d self.get_relinker_info()"},{"line_number":399,"context_line":"        else:"},{"line_number":400,"context_line":"            content \u003d \"Invalid path: %s\" % req.path"}],"source_content_type":"text/x-python","patch_set":35,"id":"1b7a33be_d0f24c1b","line":397,"in_reply_to":"1dfdcdc1_e1bbe16d","updated":"2021-05-04 22:37:28.000000000","message":"I was mostly thinking about if/when we need to do db relinking. If we really want to preserve the /recon/relinker endpoint, we could do a carve-out like we do for replication.\n\n*shrug*","commit_id":"0e91c39cc002e93bbd5fe41ebf079431c960614a"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"3de413559ee4837cce29ef3b30b0d14d392828ba","unresolved":true,"context_lines":[{"line_number":394,"context_line":"            content \u003d self.get_time()"},{"line_number":395,"context_line":"        elif rcheck \u003d\u003d \"sharding\":"},{"line_number":396,"context_line":"            content \u003d self.get_sharding_info()"},{"line_number":397,"context_line":"        elif rcheck \u003d\u003d \"relinker\":"},{"line_number":398,"context_line":"            content \u003d self.get_relinker_info()"},{"line_number":399,"context_line":"        else:"},{"line_number":400,"context_line":"            content \u003d \"Invalid path: %s\" % req.path"}],"source_content_type":"text/x-python","patch_set":35,"id":"1dfdcdc1_e1bbe16d","line":397,"in_reply_to":"d1e9a22f_c8e224e4","updated":"2021-04-30 07:18:09.000000000","message":"yeah, but then I think the recon endpoint would be \u0027relinker/object\u0027.","commit_id":"0e91c39cc002e93bbd5fe41ebf079431c960614a"}],"swift/common/utils.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"18d221075af567269b914cc713e3f45f98271418","unresolved":true,"context_lines":[{"line_number":3312,"context_line":"        if mount_check and not ismount(os.path.join(devices, device)):"},{"line_number":3313,"context_line":"            if error_counter is not None:"},{"line_number":3314,"context_line":"                error_counter.setdefault(\u0027unmounted\u0027, [])"},{"line_number":3315,"context_line":"                error_counter[\u0027unmounted\u0027].append(device)"},{"line_number":3316,"context_line":"            if logger:"},{"line_number":3317,"context_line":"                logger.warning("},{"line_number":3318,"context_line":"                    _(\u0027Skipping %s as it is not mounted\u0027), device)"}],"source_content_type":"text/x-python","patch_set":31,"id":"0088aa55_c0c55b32","line":3315,"updated":"2021-04-27 18:00:02.000000000","message":"I guess this could have been a separate patch?\n\nNo other caller uses the error_counter dict, correct?","commit_id":"b70819635d5c9ce0a29d9a9b0bb82197cbab86ab"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"c8225a146c318f8798950ade4fdfe4736be2b276","unresolved":true,"context_lines":[{"line_number":3312,"context_line":"        if mount_check and not ismount(os.path.join(devices, device)):"},{"line_number":3313,"context_line":"            if error_counter is not None:"},{"line_number":3314,"context_line":"                error_counter.setdefault(\u0027unmounted\u0027, [])"},{"line_number":3315,"context_line":"                error_counter[\u0027unmounted\u0027].append(device)"},{"line_number":3316,"context_line":"            if logger:"},{"line_number":3317,"context_line":"                logger.warning("},{"line_number":3318,"context_line":"                    _(\u0027Skipping %s as it is not mounted\u0027), device)"}],"source_content_type":"text/x-python","patch_set":31,"id":"2686401c_8fd1a730","line":3315,"in_reply_to":"0088aa55_c0c55b32","updated":"2021-04-28 00:17:15.000000000","message":"True it could be.\n\n\u003e No other caller uses the error_counter dict, correct?\nnot that I could see","commit_id":"b70819635d5c9ce0a29d9a9b0bb82197cbab86ab"}],"test/unit/cli/test_relinker.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"8cb4f1b3dbbc6a4e5704ebab8600ed991ce8d54f","unresolved":true,"context_lines":[{"line_number":937,"context_line":"            1, name\u003d\u0027ec\u0027, is_default\u003dFalse, ec_type\u003dDEFAULT_TEST_EC_TYPE,"},{"line_number":938,"context_line":"            ec_ndata\u003d4, ec_nparity\u003d2)])"},{"line_number":939,"context_line":"    def test_state_file(self):"},{"line_number":940,"context_line":"        def do_test(pol, additional_recon):"},{"line_number":941,"context_line":"            device_path \u003d os.path.join(self.devices, self.existing_device)"},{"line_number":942,"context_line":"            datadir \u003d get_policy_string(\u0027objects\u0027, pol)"},{"line_number":943,"context_line":"            datadir_path \u003d os.path.join(device_path, datadir)"}],"source_content_type":"text/x-python","patch_set":10,"id":"fc43a92a_fc340252","line":940,"range":{"start_line":940,"start_character":8,"end_line":940,"end_character":43},"updated":"2021-03-19 15:26:33.000000000","message":"maybe move this up to be a class method to avoid the new indent","commit_id":"8aa713f3208a1c333b15b1f999e1aac9cec5db58"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"4b15ab9cfec169c8580c83e6bc56b42b036ebde3","unresolved":false,"context_lines":[{"line_number":937,"context_line":"            1, name\u003d\u0027ec\u0027, is_default\u003dFalse, ec_type\u003dDEFAULT_TEST_EC_TYPE,"},{"line_number":938,"context_line":"            ec_ndata\u003d4, ec_nparity\u003d2)])"},{"line_number":939,"context_line":"    def test_state_file(self):"},{"line_number":940,"context_line":"        def do_test(pol, additional_recon):"},{"line_number":941,"context_line":"            device_path \u003d os.path.join(self.devices, self.existing_device)"},{"line_number":942,"context_line":"            datadir \u003d get_policy_string(\u0027objects\u0027, pol)"},{"line_number":943,"context_line":"            datadir_path \u003d os.path.join(device_path, datadir)"}],"source_content_type":"text/x-python","patch_set":10,"id":"2c5c9041_00d39198","line":940,"range":{"start_line":940,"start_character":8,"end_line":940,"end_character":43},"in_reply_to":"fc43a92a_fc340252","updated":"2021-03-21 23:03:20.000000000","message":"Done","commit_id":"8aa713f3208a1c333b15b1f999e1aac9cec5db58"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"8cb4f1b3dbbc6a4e5704ebab8600ed991ce8d54f","unresolved":true,"context_lines":[{"line_number":989,"context_line":"                    \"next_part_power\": PART_POWER + 1,"},{"line_number":990,"context_line":"                    \"state\": {\u002796\u0027: True, \u0027227\u0027: False}})"},{"line_number":991,"context_line":"            recon_progress \u003d utils.load_recon_cache(self.recon_cache)"},{"line_number":992,"context_line":"            expected_progress \u003d {"},{"line_number":993,"context_line":"                get_policy_string(\u0027progress\u0027, pol): {"},{"line_number":994,"context_line":"                    \u0027sda1\u0027: {\u0027parts_done\u0027: 1,"},{"line_number":995,"context_line":"                             \u0027step\u0027: \u0027relink\u0027,"},{"line_number":996,"context_line":"                             \u0027timestamp\u0027: mock.ANY,"},{"line_number":997,"context_line":"                             \u0027total_parts\u0027: 2}}}"},{"line_number":998,"context_line":"            expected_progress.update(additional_recon)"},{"line_number":999,"context_line":"            self.assertEqual(recon_progress, expected_progress)"},{"line_number":1000,"context_line":""},{"line_number":1001,"context_line":"            # Restart relinking after only part 96 was done"},{"line_number":1002,"context_line":"            self.assertEqual([\u0027227\u0027],"}],"source_content_type":"text/x-python","patch_set":10,"id":"ee4e5c64_7e063efd","line":999,"range":{"start_line":992,"start_character":2,"end_line":999,"end_character":4},"updated":"2021-03-19 15:26:33.000000000","message":"I need reminding what happens when recon dumps are updated - is the whole dict overwritten?\n\nThis assertion implies that the first policy to be tested has been overwritten by the second - if that is correct, then what happens when two relinker processes are running on two devices or two policies simultaneously?\n\nOIC, is that what additional_recon is doing - adding the last test iteration expectation to this one?\n\nI might do it the other way round to make it more obvious i.e. pass in \u0027expected_recon\u0027 to the test, update it in the test","commit_id":"8aa713f3208a1c333b15b1f999e1aac9cec5db58"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"4b15ab9cfec169c8580c83e6bc56b42b036ebde3","unresolved":true,"context_lines":[{"line_number":989,"context_line":"                    \"next_part_power\": PART_POWER + 1,"},{"line_number":990,"context_line":"                    \"state\": {\u002796\u0027: True, \u0027227\u0027: False}})"},{"line_number":991,"context_line":"            recon_progress \u003d utils.load_recon_cache(self.recon_cache)"},{"line_number":992,"context_line":"            expected_progress \u003d {"},{"line_number":993,"context_line":"                get_policy_string(\u0027progress\u0027, pol): {"},{"line_number":994,"context_line":"                    \u0027sda1\u0027: {\u0027parts_done\u0027: 1,"},{"line_number":995,"context_line":"                             \u0027step\u0027: \u0027relink\u0027,"},{"line_number":996,"context_line":"                             \u0027timestamp\u0027: mock.ANY,"},{"line_number":997,"context_line":"                             \u0027total_parts\u0027: 2}}}"},{"line_number":998,"context_line":"            expected_progress.update(additional_recon)"},{"line_number":999,"context_line":"            self.assertEqual(recon_progress, expected_progress)"},{"line_number":1000,"context_line":""},{"line_number":1001,"context_line":"            # Restart relinking after only part 96 was done"},{"line_number":1002,"context_line":"            self.assertEqual([\u0027227\u0027],"}],"source_content_type":"text/x-python","patch_set":10,"id":"263c4ab8_91b0bcf9","line":999,"range":{"start_line":992,"start_character":2,"end_line":999,"end_character":4},"in_reply_to":"ee4e5c64_7e063efd","updated":"2021-03-21 23:03:20.000000000","message":"Yeah, a recon update, pulls and only updates the record your writing down. so in this case only one device dict at a time.","commit_id":"8aa713f3208a1c333b15b1f999e1aac9cec5db58"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"134275bf7fa2f5682b76444acd3fd4888c993305","unresolved":true,"context_lines":[{"line_number":285,"context_line":"            \u0027log_level\u0027: \u0027DEBUG\u0027,"},{"line_number":286,"context_line":"            \u0027policies\u0027: POLICIES,"},{"line_number":287,"context_line":"            \u0027recon_cache_path\u0027: \u0027/var/cache/swift\u0027,"},{"line_number":288,"context_line":"            \u0027recon_cache\u0027: \u0027/var/cache/swift/relinker.recon\u0027,"},{"line_number":289,"context_line":"        }"},{"line_number":290,"context_line":"        mock_relink.assert_called_once_with(exp_conf, mock.ANY, device\u003d\u0027sdx\u0027)"},{"line_number":291,"context_line":"        logger \u003d mock_relink.call_args[0][1]"}],"source_content_type":"text/x-python","patch_set":12,"id":"8031d07a_686d68a8","line":288,"updated":"2021-03-22 11:30:09.000000000","message":"recon_cache entries need to be dropped from exp_conf here and below","commit_id":"d09cb426f391cae6963186b0b4b5c04cdaf9700d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"2ede9cc17d369e75f707dd114041b66bf0891193","unresolved":true,"context_lines":[{"line_number":2417,"context_line":"                \"state\": state})"},{"line_number":2418,"context_line":"        recon_progress \u003d utils.load_recon_cache(self.recon_cache)"},{"line_number":2419,"context_line":"        expected_recon_data \u003d {"},{"line_number":2420,"context_line":"            \u0027progress\u0027: {"},{"line_number":2421,"context_line":"                \u0027part_power\u0027: PART_POWER,"},{"line_number":2422,"context_line":"                \u0027next_part_power\u0027: PART_POWER + 1,"},{"line_number":2423,"context_line":"                \u0027sda1\u0027: {"}],"source_content_type":"text/x-python","patch_set":21,"id":"28a647c3_7ac8f2bd","line":2420,"range":{"start_line":2420,"start_character":12,"end_line":2420,"end_character":22},"updated":"2021-04-12 14:05:10.000000000","message":"so this is the progress for policy 0, and if there had been a policy 1 we\u0027d also have a key progress-1. I wonder if it would be more obvious, and easier to parse, if we had:\n\n  progress{\n      0: {\n          \u0027part_power\u0027: PART_POWER,\n          \u0027next_part_power\u0027: PART_POWER + 1,\n          \u0027sda1\u0027: {\n              \u0027parts_done\u0027: 1,\n              \u0027step\u0027: \u0027relink\u0027,\n              \u0027timestamp\u0027: mock.ANY,\n              \u0027total_parts\u0027: 1\n          },\n      1: {\n             ...\n         }\n  }\n\ni.e. policy indexes as keys","commit_id":"b59449401ef30240b76f2549d4d1758fd19de10c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"2ede9cc17d369e75f707dd114041b66bf0891193","unresolved":true,"context_lines":[{"line_number":2426,"context_line":"                    \u0027timestamp\u0027: mock.ANY,"},{"line_number":2427,"context_line":"                    \u0027total_parts\u0027: 1}},"},{"line_number":2428,"context_line":"            \u0027start_time\u0027: ts1,"},{"line_number":2429,"context_line":"            \u0027stats\u0027: {"},{"line_number":2430,"context_line":"                \u0027errors\u0027: 0,"},{"line_number":2431,"context_line":"                \u0027files\u0027: 1,"},{"line_number":2432,"context_line":"                \u0027hash_dirs\u0027: 1,"}],"source_content_type":"text/x-python","patch_set":21,"id":"dd8ddc92_550bdc90","line":2429,"range":{"start_line":2429,"start_character":12,"end_line":2429,"end_character":19},"updated":"2021-04-12 14:05:10.000000000","message":"and this is the stats aggregated across *all* policies - I don\u0027t think we get a stats-1 if there had been a policy-1, but it would be useful to know which policy(s) any errors had occurred in, so we might only repeat a step for policies with errors","commit_id":"b59449401ef30240b76f2549d4d1758fd19de10c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"dd5851baecf6f69ab7c7c026ca192545cd401233","unresolved":true,"context_lines":[{"line_number":2469,"context_line":"                \u0027part_power\u0027: PART_POWER + 1,"},{"line_number":2470,"context_line":"                \u0027next_part_power\u0027: PART_POWER + 1,"},{"line_number":2471,"context_line":"                \u0027sda1\u0027: {"},{"line_number":2472,"context_line":"                    \u0027parts_done\u0027: 1,"},{"line_number":2473,"context_line":"                    \u0027step\u0027: \u0027cleanup\u0027,"},{"line_number":2474,"context_line":"                    \u0027timestamp\u0027: mock.ANY,"},{"line_number":2475,"context_line":"                    \u0027total_parts\u0027: 1}},"}],"source_content_type":"text/x-python","patch_set":21,"id":"488dd8fe_5af9a40b","line":2472,"range":{"start_line":2472,"start_character":34,"end_line":2472,"end_character":35},"updated":"2021-04-12 16:38:37.000000000","message":"this will be 2 if self.next_part \u003c 2 ** PART_POWER","commit_id":"b59449401ef30240b76f2549d4d1758fd19de10c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"dd5851baecf6f69ab7c7c026ca192545cd401233","unresolved":true,"context_lines":[{"line_number":2589,"context_line":"                \"state\": {\u002796\u0027: True, \u0027227\u0027: False}})"},{"line_number":2590,"context_line":"        recon_progress \u003d utils.load_recon_cache(self.recon_cache)"},{"line_number":2591,"context_line":"        expected_recon_data.update({"},{"line_number":2592,"context_line":"            get_policy_string(\u0027progress\u0027, pol): {"},{"line_number":2593,"context_line":"                \u0027next_part_power\u0027: PART_POWER + 1,"},{"line_number":2594,"context_line":"                \u0027part_power\u0027: PART_POWER,"},{"line_number":2595,"context_line":"                \u0027sda1\u0027: {\u0027parts_done\u0027: 1,"}],"source_content_type":"text/x-python","patch_set":21,"id":"349ef827_b2b5bffc","line":2592,"updated":"2021-04-12 16:38:37.000000000","message":"I think this would be stronger if asserting the value for both policies e.g.on second pass, should check that the first policy data is still intact","commit_id":"b59449401ef30240b76f2549d4d1758fd19de10c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"2ede9cc17d369e75f707dd114041b66bf0891193","unresolved":true,"context_lines":[{"line_number":2774,"context_line":"    def test_state_file(self):"},{"line_number":2775,"context_line":"        expected_recon_data \u003d {}"},{"line_number":2776,"context_line":"        for policy in POLICIES:"},{"line_number":2777,"context_line":"            # because we specifying a device, it should be itself reset"},{"line_number":2778,"context_line":"            expected_recon_data.update({"},{"line_number":2779,"context_line":"                get_policy_string(\u0027progress\u0027, policy): {"},{"line_number":2780,"context_line":"                    \u0027next_part_power\u0027: 9, \u0027part_power\u0027: 8}})"}],"source_content_type":"text/x-python","patch_set":21,"id":"21bd2761_12161089","line":2777,"range":{"start_line":2777,"start_character":22,"end_line":2777,"end_character":26},"updated":"2021-04-12 14:05:10.000000000","message":"nit: typo: \u0027we are\u0027","commit_id":"b59449401ef30240b76f2549d4d1758fd19de10c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"dd5851baecf6f69ab7c7c026ca192545cd401233","unresolved":true,"context_lines":[{"line_number":2779,"context_line":"                get_policy_string(\u0027progress\u0027, policy): {"},{"line_number":2780,"context_line":"                    \u0027next_part_power\u0027: 9, \u0027part_power\u0027: 8}})"},{"line_number":2781,"context_line":"            expected_recon_data \u003d self._test_state_file("},{"line_number":2782,"context_line":"                policy, expected_recon_data)"},{"line_number":2783,"context_line":""},{"line_number":2784,"context_line":"    def test_cleanup_relinked_ok(self):"},{"line_number":2785,"context_line":"        self._common_test_cleanup()"}],"source_content_type":"text/x-python","patch_set":21,"id":"e3c34027_aff08f01","line":2782,"updated":"2021-04-12 16:38:37.000000000","message":"can we make any assertion about the collated stats here? this is one of few places where multiple policies are tested","commit_id":"b59449401ef30240b76f2549d4d1758fd19de10c"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"b7f0e3b8e061e83404a86140b60364d63a058c0e","unresolved":true,"context_lines":[{"line_number":2519,"context_line":"                    \u0027removed\u0027: 0,"},{"line_number":2520,"context_line":"                    \u0027timestamp\u0027: mock.ANY}"},{"line_number":2521,"context_line":"            },"},{"line_number":2522,"context_line":"            \u0027total_time\u0027: 1.0}"},{"line_number":2523,"context_line":"        self.assertEqual(recon_progress, expected_recon_data)"},{"line_number":2524,"context_line":""},{"line_number":2525,"context_line":"        self.rb.increase_partition_power()"}],"source_content_type":"text/x-python","patch_set":24,"id":"6acb1850_aa65d768","line":2522,"updated":"2021-04-14 18:21:26.000000000","message":"it\u0027s pretty nice to have it laid out like this!  good technical investment!","commit_id":"5b355b34ab8c457b2f09734e3a5a6a17330932c9"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"66c41dfad6399d1bdbebbad80b02487aa14062a0","unresolved":true,"context_lines":[{"line_number":2507,"context_line":"                    \"state\": state})"},{"line_number":2508,"context_line":"        recon_progress \u003d utils.load_recon_cache(self.recon_cache)"},{"line_number":2509,"context_line":"        expected_recon_data \u003d {"},{"line_number":2510,"context_line":"            \u0027progress\u0027: {"},{"line_number":2511,"context_line":"                \u0027part_power\u0027: PART_POWER,"},{"line_number":2512,"context_line":"                \u0027next_part_power\u0027: PART_POWER + 1,"},{"line_number":2513,"context_line":"                \u0027sda1\u0027: {"}],"source_content_type":"text/x-python","patch_set":25,"id":"f841079a_7cc1cae0","line":2510,"range":{"start_line":2510,"start_character":13,"end_line":2510,"end_character":21},"updated":"2021-04-16 18:31:32.000000000","message":"I still \u0027progress\u0027 find this confusing :/\n\nThe lack of nesting support in recon is frustrating, but i think I\u0027d at least prefer \u0027policy-0\u0027, \u0027policy-1\u0027 ... we don\u0027t have to stick to the object ring legacy naming convention, so we could add \u0027-0\u0027 for policy 0.","commit_id":"aad814e5163dbc8843adce04d120be6b558a0124"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"d1a256b8635bd3c4f575aaaa6e009bb0d47c1eab","unresolved":true,"context_lines":[{"line_number":2507,"context_line":"                    \"state\": state})"},{"line_number":2508,"context_line":"        recon_progress \u003d utils.load_recon_cache(self.recon_cache)"},{"line_number":2509,"context_line":"        expected_recon_data \u003d {"},{"line_number":2510,"context_line":"            \u0027progress\u0027: {"},{"line_number":2511,"context_line":"                \u0027part_power\u0027: PART_POWER,"},{"line_number":2512,"context_line":"                \u0027next_part_power\u0027: PART_POWER + 1,"},{"line_number":2513,"context_line":"                \u0027sda1\u0027: {"}],"source_content_type":"text/x-python","patch_set":25,"id":"d8219ea6_64482545","line":2510,"range":{"start_line":2510,"start_character":13,"end_line":2510,"end_character":21},"in_reply_to":"f841079a_7cc1cae0","updated":"2021-04-19 03:01:24.000000000","message":"That\u0027s an idea. But we then couldn\u0027t use or would have to change get_policy_string.","commit_id":"aad814e5163dbc8843adce04d120be6b558a0124"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"66c41dfad6399d1bdbebbad80b02487aa14062a0","unresolved":true,"context_lines":[{"line_number":2533,"context_line":"                    \u0027total_time\u0027: mock.ANY,"},{"line_number":2534,"context_line":"                    \u0027total_parts\u0027: 1},"},{"line_number":2535,"context_line":"                \u0027aggregate\u0027: {"},{"line_number":2536,"context_line":"                    \u0027discovered_parts\u0027: 1,"},{"line_number":2537,"context_line":"                    \u0027parts_done\u0027: 1,"},{"line_number":2538,"context_line":"                    \u0027timestamp\u0027: mock.ANY,"},{"line_number":2539,"context_line":"                    \u0027total_combined_time\u0027: mock.ANY}},"},{"line_number":2540,"context_line":"            \u0027start_time\u0027: ts1,"},{"line_number":2541,"context_line":"            \u0027stats\u0027: {"},{"line_number":2542,"context_line":"                \u0027aggregate\u0027: {"}],"source_content_type":"text/x-python","patch_set":25,"id":"f9bac2ee_189c01b9","line":2539,"range":{"start_line":2536,"start_character":21,"end_line":2539,"end_character":41},"updated":"2021-04-16 18:31:32.000000000","message":"I think I\u0027d prefer these to have the same keys as the per-device data i.e. total_parts and total_time - as it is I had to go to the code to figure out that they are the aggregates of the other keys\n\nIn particular, \u0027discovered_parts\u0027 suggests there\u0027s a different semantic vs total_parts","commit_id":"aad814e5163dbc8843adce04d120be6b558a0124"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"d1a256b8635bd3c4f575aaaa6e009bb0d47c1eab","unresolved":true,"context_lines":[{"line_number":2533,"context_line":"                    \u0027total_time\u0027: mock.ANY,"},{"line_number":2534,"context_line":"                    \u0027total_parts\u0027: 1},"},{"line_number":2535,"context_line":"                \u0027aggregate\u0027: {"},{"line_number":2536,"context_line":"                    \u0027discovered_parts\u0027: 1,"},{"line_number":2537,"context_line":"                    \u0027parts_done\u0027: 1,"},{"line_number":2538,"context_line":"                    \u0027timestamp\u0027: mock.ANY,"},{"line_number":2539,"context_line":"                    \u0027total_combined_time\u0027: mock.ANY}},"},{"line_number":2540,"context_line":"            \u0027start_time\u0027: ts1,"},{"line_number":2541,"context_line":"            \u0027stats\u0027: {"},{"line_number":2542,"context_line":"                \u0027aggregate\u0027: {"}],"source_content_type":"text/x-python","patch_set":25,"id":"c8a2a3d2_7c37bbe7","line":2539,"range":{"start_line":2536,"start_character":21,"end_line":2539,"end_character":41},"in_reply_to":"f9bac2ee_189c01b9","updated":"2021-04-19 03:01:24.000000000","message":"discovered_parts just let\u0027s you know that this number may rise as we start working on a new device. Whereas total parts as a per device means it\u0027s static and doesn\u0027t change.. not while we\u0027re processing it anyway.\n\nAnd total_time, happy to change this, just wanted to be clear in the name that this wont equal the total time of the run, because we\u0027d be scanning concurrently, to total_time in the run \"should\" be lower then the aggregate combined total_time. I just thought it might be useful to have the total aggregate time.. maybe it isn\u0027t?","commit_id":"aad814e5163dbc8843adce04d120be6b558a0124"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"fe33b948377bd711287784a49b16567708dbff35","unresolved":true,"context_lines":[{"line_number":51,"context_line":""},{"line_number":52,"context_line":"class TestRelinker(unittest.TestCase):"},{"line_number":53,"context_line":""},{"line_number":54,"context_line":"    maxDiff \u003d None"},{"line_number":55,"context_line":""},{"line_number":56,"context_line":"    def setUp(self):"},{"line_number":57,"context_line":"        skip_if_no_xattrs()"}],"source_content_type":"text/x-python","patch_set":30,"id":"5b67496b_02369630","line":54,"updated":"2021-04-26 21:26:37.000000000","message":"Just for debugging?","commit_id":"cbed96294f376464021d3994bf8f17996434118b"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"fe33b948377bd711287784a49b16567708dbff35","unresolved":true,"context_lines":[{"line_number":3341,"context_line":""},{"line_number":3342,"context_line":"        with mock.patch.object(relinker.logging, \u0027getLogger\u0027,"},{"line_number":3343,"context_line":"                               return_value\u003dself.logger), \\"},{"line_number":3344,"context_line":"                mock.patch(\u0027time.time\u0027, return_value\u003d1e10 - 1):  # far future"},{"line_number":3345,"context_line":"            self.assertEqual(0, relinker.main(["},{"line_number":3346,"context_line":"                \u0027cleanup\u0027,"},{"line_number":3347,"context_line":"                \u0027--swift-dir\u0027, self.testdir,"}],"source_content_type":"text/x-python","patch_set":30,"id":"569371ae_677640ee","line":3344,"updated":"2021-04-26 21:26:37.000000000","message":"FWIW, I got tests passing with something like a\n\n mock.patch.object(relinker, \u0027dump_recon_cache\u0027)\n\naround here so it stopped logging an EPERM. Maybe we want to make some assertions on what\u0027s going out to recon, though?","commit_id":"cbed96294f376464021d3994bf8f17996434118b"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"18d221075af567269b914cc713e3f45f98271418","unresolved":true,"context_lines":[{"line_number":50,"context_line":""},{"line_number":51,"context_line":"class TestRelinker(unittest.TestCase):"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"    maxDiff \u003d None"},{"line_number":54,"context_line":""},{"line_number":55,"context_line":"    def setUp(self):"},{"line_number":56,"context_line":"        skip_if_no_xattrs()"}],"source_content_type":"text/x-python","patch_set":31,"id":"e9680698_162d87d2","line":53,"updated":"2021-04-27 18:00:02.000000000","message":"was this just for debug - should it be removed? IDK","commit_id":"b70819635d5c9ce0a29d9a9b0bb82197cbab86ab"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"c8225a146c318f8798950ade4fdfe4736be2b276","unresolved":true,"context_lines":[{"line_number":50,"context_line":""},{"line_number":51,"context_line":"class TestRelinker(unittest.TestCase):"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"    maxDiff \u003d None"},{"line_number":54,"context_line":""},{"line_number":55,"context_line":"    def setUp(self):"},{"line_number":56,"context_line":"        skip_if_no_xattrs()"}],"source_content_type":"text/x-python","patch_set":31,"id":"8c4179be_aee6304f","line":53,"in_reply_to":"e9680698_162d87d2","updated":"2021-04-28 00:17:15.000000000","message":"good question. I think I sqaushed it in from a follow up patch. But it means we get full diffs in the test output (and in pycharm) which does make debugging failed tests _much_ better.\n\nHappy to remove it. But I\u0027d just have to remember to add it for myself if I ever need bigger diffs generated on failures with things like assertEqual.","commit_id":"b70819635d5c9ce0a29d9a9b0bb82197cbab86ab"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"18d221075af567269b914cc713e3f45f98271418","unresolved":true,"context_lines":[{"line_number":3048,"context_line":"                    \u0027timestamp\u0027: mock.ANY,"},{"line_number":3049,"context_line":"                    \u0027total_parts\u0027: 0,"},{"line_number":3050,"context_line":"                    \u0027total_time\u0027: 0}}})"},{"line_number":3051,"context_line":"        self.assertEqual(recon_progress, expected_recon_data)"},{"line_number":3052,"context_line":"        os.close(r.dev_lock)  # Release the lock"},{"line_number":3053,"context_line":"        return expected_recon_data"},{"line_number":3054,"context_line":""}],"source_content_type":"text/x-python","patch_set":31,"id":"eb6f13fc_109fc1f0","line":3051,"updated":"2021-04-27 18:00:02.000000000","message":"I was expecting to see \u0027workers\u0027 stats too","commit_id":"b70819635d5c9ce0a29d9a9b0bb82197cbab86ab"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"c8225a146c318f8798950ade4fdfe4736be2b276","unresolved":true,"context_lines":[{"line_number":3048,"context_line":"                    \u0027timestamp\u0027: mock.ANY,"},{"line_number":3049,"context_line":"                    \u0027total_parts\u0027: 0,"},{"line_number":3050,"context_line":"                    \u0027total_time\u0027: 0}}})"},{"line_number":3051,"context_line":"        self.assertEqual(recon_progress, expected_recon_data)"},{"line_number":3052,"context_line":"        os.close(r.dev_lock)  # Release the lock"},{"line_number":3053,"context_line":"        return expected_recon_data"},{"line_number":3054,"context_line":""}],"source_content_type":"text/x-python","patch_set":31,"id":"52eacb20_7db7c729","line":3051,"in_reply_to":"eb6f13fc_109fc1f0","updated":"2021-04-28 00:17:15.000000000","message":"hmm, yeah. Thats a good question.. We only call the hooks in this test. But I did start calling update worker stats inside _update_recon. Let me look closer.","commit_id":"b70819635d5c9ce0a29d9a9b0bb82197cbab86ab"}],"test/unit/common/middleware/test_recon.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"b7f0e3b8e061e83404a86140b60364d63a058c0e","unresolved":true,"context_lines":[{"line_number":30,"context_line":"from swift.common.swob import Request"},{"line_number":31,"context_line":"from swift.common.middleware import recon"},{"line_number":32,"context_line":"from swift.common.storage_policy import StoragePolicy"},{"line_number":33,"context_line":"from test.unit import patch_policies, FakeLogger"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"def fake_check_mount(a, b):"}],"source_content_type":"text/x-python","patch_set":24,"id":"8b0d194c_d63a4871","line":33,"updated":"2021-04-14 18:21:26.000000000","message":"please use debug_logger","commit_id":"5b355b34ab8c457b2f09734e3a5a6a17330932c9"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"ca40c1e251085b6cad9625dfa1d6017000161e69","unresolved":true,"context_lines":[{"line_number":30,"context_line":"from swift.common.swob import Request"},{"line_number":31,"context_line":"from swift.common.middleware import recon"},{"line_number":32,"context_line":"from swift.common.storage_policy import StoragePolicy"},{"line_number":33,"context_line":"from test.unit import patch_policies, FakeLogger"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"def fake_check_mount(a, b):"}],"source_content_type":"text/x-python","patch_set":24,"id":"070d9598_6d886cb4","line":33,"in_reply_to":"8b0d194c_d63a4871","updated":"2021-04-14 23:36:21.000000000","message":"kk, will do","commit_id":"5b355b34ab8c457b2f09734e3a5a6a17330932c9"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"b7f0e3b8e061e83404a86140b60364d63a058c0e","unresolved":true,"context_lines":[{"line_number":484,"context_line":"    def test_from_recon_cache_ioerror(self):"},{"line_number":485,"context_line":"        oart \u003d self.frecon.raise_IOError()"},{"line_number":486,"context_line":"        self.app._from_recon_cache \u003d self.real_from_cache"},{"line_number":487,"context_line":"        self.app.logger \u003d FakeLogger()"},{"line_number":488,"context_line":"        rv \u003d self.app._from_recon_cache([\u0027testkey1\u0027, \u0027notpresentkey\u0027],"},{"line_number":489,"context_line":"                                        \u0027test.cache\u0027, openr\u003doart)"},{"line_number":490,"context_line":"        self.assertEqual(rv, {\u0027notpresentkey\u0027: None, \u0027testkey1\u0027: None})"}],"source_content_type":"text/x-python","patch_set":24,"id":"5b1ebdc7_cabec4ac","line":487,"updated":"2021-04-14 18:21:26.000000000","message":"this setup is repeated - can we move it into setUp?","commit_id":"5b355b34ab8c457b2f09734e3a5a6a17330932c9"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"ca40c1e251085b6cad9625dfa1d6017000161e69","unresolved":true,"context_lines":[{"line_number":484,"context_line":"    def test_from_recon_cache_ioerror(self):"},{"line_number":485,"context_line":"        oart \u003d self.frecon.raise_IOError()"},{"line_number":486,"context_line":"        self.app._from_recon_cache \u003d self.real_from_cache"},{"line_number":487,"context_line":"        self.app.logger \u003d FakeLogger()"},{"line_number":488,"context_line":"        rv \u003d self.app._from_recon_cache([\u0027testkey1\u0027, \u0027notpresentkey\u0027],"},{"line_number":489,"context_line":"                                        \u0027test.cache\u0027, openr\u003doart)"},{"line_number":490,"context_line":"        self.assertEqual(rv, {\u0027notpresentkey\u0027: None, \u0027testkey1\u0027: None})"}],"source_content_type":"text/x-python","patch_set":24,"id":"833a4047_9dbfae4f","line":487,"in_reply_to":"5b1ebdc7_cabec4ac","updated":"2021-04-14 23:36:21.000000000","message":"good call!","commit_id":"5b355b34ab8c457b2f09734e3a5a6a17330932c9"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"a441c3c4b62ddfd64e4533b2cdce02d700d271f5","unresolved":true,"context_lines":[{"line_number":30,"context_line":"from swift.common.swob import Request"},{"line_number":31,"context_line":"from swift.common.middleware import recon"},{"line_number":32,"context_line":"from swift.common.storage_policy import StoragePolicy"},{"line_number":33,"context_line":"from test.unit import patch_policies, FakeLogger"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"def fake_check_mount(a, b):"}],"source_content_type":"text/x-python","patch_set":37,"id":"2e9b815a_ad90088a","line":33,"range":{"start_line":33,"start_character":38,"end_line":33,"end_character":48},"updated":"2021-04-30 12:00:48.000000000","message":"why move away from debug_logger?","commit_id":"2fad8e44627d07829aa7bb369d7641c4ce3dce16"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"33842612f19a4cb329e72479ed5923fe82a397f7","unresolved":true,"context_lines":[{"line_number":30,"context_line":"from swift.common.swob import Request"},{"line_number":31,"context_line":"from swift.common.middleware import recon"},{"line_number":32,"context_line":"from swift.common.storage_policy import StoragePolicy"},{"line_number":33,"context_line":"from test.unit import patch_policies, FakeLogger"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"def fake_check_mount(a, b):"}],"source_content_type":"text/x-python","patch_set":37,"id":"0e4cfc73_9fd22997","line":33,"range":{"start_line":33,"start_character":38,"end_line":33,"end_character":48},"in_reply_to":"2e9b815a_ad90088a","updated":"2021-05-04 22:37:28.000000000","message":"I\u0027m also curious -- I felt like we were generally moving towards more use of debug_logger, since it shows up in test failures better, or something like that?","commit_id":"2fad8e44627d07829aa7bb369d7641c4ce3dce16"}],"test/unit/common/test_utils.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7a0500eb3b3152b939255184b9bcb9514b66c589","unresolved":true,"context_lines":[{"line_number":6622,"context_line":"            self.assertEqual(1, len(logger.get_lines_for_level(\u0027warning\u0027)))"},{"line_number":6623,"context_line":"            self.assertEqual({\u0027unlistable_partitions\u0027: expected},"},{"line_number":6624,"context_line":"                             error_counter)"},{"line_number":6625,"context_line":"            self.assertEqual(1, len(error_counter[\u0027unlistable_partitions\u0027]))"},{"line_number":6626,"context_line":""},{"line_number":6627,"context_line":"        # file under devices/"},{"line_number":6628,"context_line":"        devices \u003d os.path.join(tmpdir, \u0027devices3\u0027)"}],"source_content_type":"text/x-python","patch_set":35,"id":"cfd4a878_96b9aa19","line":6625,"updated":"2021-04-29 20:02:46.000000000","message":"nit: We could probably drop this; it\u0027s implied from the assertEqual above.","commit_id":"0e91c39cc002e93bbd5fe41ebf079431c960614a"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"3de413559ee4837cce29ef3b30b0d14d392828ba","unresolved":false,"context_lines":[{"line_number":6622,"context_line":"            self.assertEqual(1, len(logger.get_lines_for_level(\u0027warning\u0027)))"},{"line_number":6623,"context_line":"            self.assertEqual({\u0027unlistable_partitions\u0027: expected},"},{"line_number":6624,"context_line":"                             error_counter)"},{"line_number":6625,"context_line":"            self.assertEqual(1, len(error_counter[\u0027unlistable_partitions\u0027]))"},{"line_number":6626,"context_line":""},{"line_number":6627,"context_line":"        # file under devices/"},{"line_number":6628,"context_line":"        devices \u003d os.path.join(tmpdir, \u0027devices3\u0027)"}],"source_content_type":"text/x-python","patch_set":35,"id":"5f3d17c2_ec914b1b","line":6625,"in_reply_to":"cfd4a878_96b9aa19","updated":"2021-04-30 07:18:09.000000000","message":"Done","commit_id":"0e91c39cc002e93bbd5fe41ebf079431c960614a"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7a0500eb3b3152b939255184b9bcb9514b66c589","unresolved":true,"context_lines":[{"line_number":6675,"context_line":"        self.assertEqual([], list(locations))"},{"line_number":6676,"context_line":"        self.assertEqual(1, len(logger.get_lines_for_level(\u0027warning\u0027)))"},{"line_number":6677,"context_line":"        self.assertEqual({\u0027unmounted\u0027: [\u0027device\u0027]}, error_counter)"},{"line_number":6678,"context_line":"        self.assertEqual(1, len(error_counter[\u0027unmounted\u0027]))"},{"line_number":6679,"context_line":""},{"line_number":6680,"context_line":""},{"line_number":6681,"context_line":"class TestGreenAsyncPile(unittest.TestCase):"}],"source_content_type":"text/x-python","patch_set":35,"id":"efe05633_1730343d","line":6678,"updated":"2021-04-29 20:02:46.000000000","message":"ditto","commit_id":"0e91c39cc002e93bbd5fe41ebf079431c960614a"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"3de413559ee4837cce29ef3b30b0d14d392828ba","unresolved":false,"context_lines":[{"line_number":6675,"context_line":"        self.assertEqual([], list(locations))"},{"line_number":6676,"context_line":"        self.assertEqual(1, len(logger.get_lines_for_level(\u0027warning\u0027)))"},{"line_number":6677,"context_line":"        self.assertEqual({\u0027unmounted\u0027: [\u0027device\u0027]}, error_counter)"},{"line_number":6678,"context_line":"        self.assertEqual(1, len(error_counter[\u0027unmounted\u0027]))"},{"line_number":6679,"context_line":""},{"line_number":6680,"context_line":""},{"line_number":6681,"context_line":"class TestGreenAsyncPile(unittest.TestCase):"}],"source_content_type":"text/x-python","patch_set":35,"id":"b60ef51b_ae404039","line":6678,"in_reply_to":"efe05633_1730343d","updated":"2021-04-30 07:18:09.000000000","message":"Done","commit_id":"0e91c39cc002e93bbd5fe41ebf079431c960614a"}]}
