)]}'
{"swift/proxy/controllers/obj.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"a1382d6743913287898ee4c5249783079387e28b","unresolved":true,"context_lines":[{"line_number":2171,"context_line":"        headers \u003d get.last_headers"},{"line_number":2172,"context_line":"        # Add the response to the appropriate bucket keyed by data file"},{"line_number":2173,"context_line":"        # timestamp. Fall back to using X-Backend-Timestamp as key for object"},{"line_number":2174,"context_line":"        # servers that have not been upgraded."},{"line_number":2175,"context_line":"        t_data_file \u003d headers.get(\u0027X-Backend-Data-Timestamp\u0027)"},{"line_number":2176,"context_line":"        t_obj \u003d headers.get(\u0027X-Backend-Timestamp\u0027, headers.get(\u0027X-Timestamp\u0027))"},{"line_number":2177,"context_line":"        if t_data_file:"}],"source_content_type":"text/x-python","patch_set":1,"id":"2a92bc1e_692d6c5e","line":2174,"range":{"start_line":2174,"start_character":18,"end_line":2174,"end_character":45},"updated":"2021-01-15 22:58:09.000000000","message":"...since 2.10.0 (https://github.com/openstack/swift/commit/44a8617). That was actually more recent than I was thinking...","commit_id":"2bc88671a50ed96446f8c9d2f9814775976f79ae"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"a1382d6743913287898ee4c5249783079387e28b","unresolved":true,"context_lines":[{"line_number":2179,"context_line":"        elif t_obj:"},{"line_number":2180,"context_line":"            timestamp \u003d Timestamp(t_obj)"},{"line_number":2181,"context_line":"        else:"},{"line_number":2182,"context_line":"            # Don\u0027t think this should ever come up in practice,"},{"line_number":2183,"context_line":"            # but tests cover it"},{"line_number":2184,"context_line":"            timestamp \u003d None"},{"line_number":2185,"context_line":"        self._get_bucket(timestamp).add_response(get, parts_iter)"},{"line_number":2186,"context_line":""},{"line_number":2187,"context_line":"        # The node may also have alternate fragments indexes (possibly at"}],"source_content_type":"text/x-python","patch_set":1,"id":"bb3d344a_8a85f40e","line":2184,"range":{"start_line":2182,"start_character":12,"end_line":2184,"end_character":28},"updated":"2021-01-15 22:58:09.000000000","message":"We\u0027re *pretty darn sure* that this doesn\u0027t come up in practice, right? Would it be better for us to just bomb out instead? Or maybe just discard this getter and see what we can do with the other responses coming in.","commit_id":"2bc88671a50ed96446f8c9d2f9814775976f79ae"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"ce86f3588ba7ffb213c5121de253691812fe2ee2","unresolved":true,"context_lines":[{"line_number":2179,"context_line":"        elif t_obj:"},{"line_number":2180,"context_line":"            timestamp \u003d Timestamp(t_obj)"},{"line_number":2181,"context_line":"        else:"},{"line_number":2182,"context_line":"            # Don\u0027t think this should ever come up in practice,"},{"line_number":2183,"context_line":"            # but tests cover it"},{"line_number":2184,"context_line":"            timestamp \u003d None"},{"line_number":2185,"context_line":"        self._get_bucket(timestamp).add_response(get, parts_iter)"},{"line_number":2186,"context_line":""},{"line_number":2187,"context_line":"        # The node may also have alternate fragments indexes (possibly at"}],"source_content_type":"text/x-python","patch_set":1,"id":"cb87f07c_bf3e0285","line":2184,"range":{"start_line":2182,"start_character":12,"end_line":2184,"end_character":28},"in_reply_to":"bb3d344a_8a85f40e","updated":"2021-01-19 11:35:08.000000000","message":"valid concern, but I don\u0027t think this patch changes anything here - we\u0027d continue to create a good bucket which would never update its timestamp because we\u0027d only ever add responses with no timestamp.","commit_id":"2bc88671a50ed96446f8c9d2f9814775976f79ae"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"fab6c9ba592d1c32ae2eaeb97a432a12510c9f28","unresolved":true,"context_lines":[{"line_number":1998,"context_line":"        self.timestamp \u003d timestamp"},{"line_number":1999,"context_line":"        # if no timestamp when init\u0027d then the bucket will update its timestamp"},{"line_number":2000,"context_line":"        # as responses are added"},{"line_number":2001,"context_line":"        self.update_timestamp \u003d timestamp is None"},{"line_number":2002,"context_line":"        self.gets \u003d collections.defaultdict(list)"},{"line_number":2003,"context_line":"        self.alt_nodes \u003d collections.defaultdict(list)"},{"line_number":2004,"context_line":"        self._durable \u003d False"}],"source_content_type":"text/x-python","patch_set":2,"id":"aa8f6d79_b373b8c5","line":2001,"updated":"2021-01-19 16:18:27.000000000","message":"There\u0027s a lot of overlap from buckets of errors and buckets with frags - this is a very small difference to keep in mind - it begs the question \"when do we initialize with a timestamp vs. without\"","commit_id":"cc3fa3cc0fa51df0e3eb872744da428a7e742cea"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"fab6c9ba592d1c32ae2eaeb97a432a12510c9f28","unresolved":true,"context_lines":[{"line_number":2018,"context_line":"        \"\"\""},{"line_number":2019,"context_line":"        headers \u003d getter.last_headers"},{"line_number":2020,"context_line":"        timestamp_str \u003d headers.get(\u0027X-Backend-Timestamp\u0027,"},{"line_number":2021,"context_line":"                                    headers.get(\u0027X-Timestamp\u0027))"},{"line_number":2022,"context_line":"        if timestamp_str and self.update_timestamp:"},{"line_number":2023,"context_line":"            # 404s will keep the most recent timestamp"},{"line_number":2024,"context_line":"            self.timestamp \u003d max(Timestamp(timestamp_str), self.timestamp)"}],"source_content_type":"text/x-python","patch_set":2,"id":"45d9e7db_6a03623d","line":2021,"updated":"2021-01-19 16:18:27.000000000","message":"For me ...\n\n        timestamp_str \u003d headers.get(\u0027X-Backend-Data-Timestamp\u0027,\n                                    headers.get(\u0027X-Backend-Timestamp\u0027,\n                                                headers.get(\u0027X-Timestamp\u0027)))\n\n... works, and I could probably articulate what I imagine as some minor advantages.","commit_id":"cc3fa3cc0fa51df0e3eb872744da428a7e742cea"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4b777b3c9ea5c1d38b1e83bd2f551284541b3cb7","unresolved":true,"context_lines":[{"line_number":2018,"context_line":"        \"\"\""},{"line_number":2019,"context_line":"        headers \u003d getter.last_headers"},{"line_number":2020,"context_line":"        timestamp_str \u003d headers.get(\u0027X-Backend-Timestamp\u0027,"},{"line_number":2021,"context_line":"                                    headers.get(\u0027X-Timestamp\u0027))"},{"line_number":2022,"context_line":"        if timestamp_str and self.update_timestamp:"},{"line_number":2023,"context_line":"            # 404s will keep the most recent timestamp"},{"line_number":2024,"context_line":"            self.timestamp \u003d max(Timestamp(timestamp_str), self.timestamp)"}],"source_content_type":"text/x-python","patch_set":2,"id":"0c57b5d0_3da88836","line":2021,"in_reply_to":"45d9e7db_6a03623d","updated":"2021-01-19 16:57:27.000000000","message":"That\u0027s (to my mind) a pretty big change in what timestamp_str means -- but maybe that\u0027s a good thing?","commit_id":"cc3fa3cc0fa51df0e3eb872744da428a7e742cea"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"fab6c9ba592d1c32ae2eaeb97a432a12510c9f28","unresolved":true,"context_lines":[{"line_number":2020,"context_line":"        timestamp_str \u003d headers.get(\u0027X-Backend-Timestamp\u0027,"},{"line_number":2021,"context_line":"                                    headers.get(\u0027X-Timestamp\u0027))"},{"line_number":2022,"context_line":"        if timestamp_str and self.update_timestamp:"},{"line_number":2023,"context_line":"            # 404s will keep the most recent timestamp"},{"line_number":2024,"context_line":"            self.timestamp \u003d max(Timestamp(timestamp_str), self.timestamp)"},{"line_number":2025,"context_line":"        if not self.gets:"},{"line_number":2026,"context_line":"            # stash first set of backend headers, which will be used to"}],"source_content_type":"text/x-python","patch_set":2,"id":"101faad7_6225fbaf","line":2023,"updated":"2021-01-19 16:18:27.000000000","message":"For me ...\n\n        if timestamp_str and not is_success(getter.last_status):\n\n... also works and I could probably articulate what I imagine as some minor advantages.","commit_id":"cc3fa3cc0fa51df0e3eb872744da428a7e742cea"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4b777b3c9ea5c1d38b1e83bd2f551284541b3cb7","unresolved":true,"context_lines":[{"line_number":2020,"context_line":"        timestamp_str \u003d headers.get(\u0027X-Backend-Timestamp\u0027,"},{"line_number":2021,"context_line":"                                    headers.get(\u0027X-Timestamp\u0027))"},{"line_number":2022,"context_line":"        if timestamp_str and self.update_timestamp:"},{"line_number":2023,"context_line":"            # 404s will keep the most recent timestamp"},{"line_number":2024,"context_line":"            self.timestamp \u003d max(Timestamp(timestamp_str), self.timestamp)"},{"line_number":2025,"context_line":"        if not self.gets:"},{"line_number":2026,"context_line":"            # stash first set of backend headers, which will be used to"}],"source_content_type":"text/x-python","patch_set":2,"id":"75e4d298_fbaa706b","line":2023,"in_reply_to":"101faad7_6225fbaf","updated":"2021-01-19 16:57:27.000000000","message":"So I\u0027m a little torn here -- on the one hand, \"have timestamp and is not successful\" seems way more direct/in line with the comment. On the other hand, I kind of liked the fact that with the flag, *the bucket is in charge*, rather than having this behavior depend upon what you end up putting *into* the bucket.","commit_id":"cc3fa3cc0fa51df0e3eb872744da428a7e742cea"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"54c4a9085dff705a9222787f607a9a58f8e38872","unresolved":true,"context_lines":[{"line_number":2020,"context_line":"        timestamp_str \u003d headers.get(\u0027X-Backend-Timestamp\u0027,"},{"line_number":2021,"context_line":"                                    headers.get(\u0027X-Timestamp\u0027))"},{"line_number":2022,"context_line":"        if timestamp_str and self.update_timestamp:"},{"line_number":2023,"context_line":"            # 404s will keep the most recent timestamp"},{"line_number":2024,"context_line":"            self.timestamp \u003d max(Timestamp(timestamp_str), self.timestamp)"},{"line_number":2025,"context_line":"        if not self.gets:"},{"line_number":2026,"context_line":"            # stash first set of backend headers, which will be used to"}],"source_content_type":"text/x-python","patch_set":2,"id":"71d98e54_69cc25f3","line":2023,"in_reply_to":"75e4d298_fbaa706b","updated":"2021-01-21 19:30:01.000000000","message":"I found this comment \"the bucket is in charge\" particularly convincing.  I think my aversion to class sparwl was the only reason I didn\u0027t accept - \"these two types are buckets are similar but different things\"","commit_id":"cc3fa3cc0fa51df0e3eb872744da428a7e742cea"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4b777b3c9ea5c1d38b1e83bd2f551284541b3cb7","unresolved":true,"context_lines":[{"line_number":2021,"context_line":"                                    headers.get(\u0027X-Timestamp\u0027))"},{"line_number":2022,"context_line":"        if timestamp_str and self.update_timestamp:"},{"line_number":2023,"context_line":"            # 404s will keep the most recent timestamp"},{"line_number":2024,"context_line":"            self.timestamp \u003d max(Timestamp(timestamp_str), self.timestamp)"},{"line_number":2025,"context_line":"        if not self.gets:"},{"line_number":2026,"context_line":"            # stash first set of backend headers, which will be used to"},{"line_number":2027,"context_line":"            # populate a client response"}],"source_content_type":"text/x-python","patch_set":2,"id":"a5b1f023_486344b0","line":2024,"updated":"2021-01-19 16:57:27.000000000","message":"Side note: I\u0027m somewhat surprised that this didn\u0027t cause a TypeError on py3 before, but I guess we anticipated comparisons against None:\n\n \u003e\u003e\u003e Timestamp.now() \u003e None\n True\n \u003e\u003e\u003e Timestamp.now() \u003c None\n False\n \u003e\u003e\u003e Timestamp(0) \u003e None\n True\n \u003e\u003e\u003e Timestamp(0) \u003c None\n False","commit_id":"cc3fa3cc0fa51df0e3eb872744da428a7e742cea"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4b777b3c9ea5c1d38b1e83bd2f551284541b3cb7","unresolved":true,"context_lines":[{"line_number":2026,"context_line":"            # stash first set of backend headers, which will be used to"},{"line_number":2027,"context_line":"            # populate a client response"},{"line_number":2028,"context_line":"            self.status \u003d getter.last_status"},{"line_number":2029,"context_line":"            # TODO: each bucket is for a single *data* timestamp, but sources"},{"line_number":2030,"context_line":"            # in the same bucket may have different *metadata* timestamps if"},{"line_number":2031,"context_line":"            # some backends have more recent .meta files than others. Currently"},{"line_number":2032,"context_line":"            # we just use the last received metadata headers - this behavior is"}],"source_content_type":"text/x-python","patch_set":2,"id":"72e7da64_f65358f7","line":2029,"updated":"2021-01-19 16:57:27.000000000","message":"I feel like we\u0027re *so close* to being able to resolve this TODO...","commit_id":"cc3fa3cc0fa51df0e3eb872744da428a7e742cea"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4b777b3c9ea5c1d38b1e83bd2f551284541b3cb7","unresolved":true,"context_lines":[{"line_number":2978,"context_line":"        req.range \u003d orig_range"},{"line_number":2979,"context_line":"        best_bucket \u003d buckets.choose_best_bucket()"},{"line_number":2980,"context_line":"        if best_bucket.shortfall \u003c\u003d 0 and best_bucket.durable:"},{"line_number":2981,"context_line":"            # headers can come from any of the getters"},{"line_number":2982,"context_line":"            resp_headers \u003d best_bucket.headers"},{"line_number":2983,"context_line":"            resp_headers.pop(\u0027Content-Range\u0027, None)"},{"line_number":2984,"context_line":"            eccl \u003d resp_headers.get(\u0027X-Object-Sysmeta-Ec-Content-Length\u0027)"}],"source_content_type":"text/x-python","patch_set":2,"id":"14d71594_b39000fb","line":2981,"range":{"start_line":2981,"start_character":14,"end_line":2981,"end_character":54},"updated":"2021-01-19 16:57:27.000000000","message":"Hmm... I\u0027m not sure this has been true following fast-POST...","commit_id":"cc3fa3cc0fa51df0e3eb872744da428a7e742cea"}],"test/unit/proxy/test_server.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"a1382d6743913287898ee4c5249783079387e28b","unresolved":true,"context_lines":[{"line_number":7915,"context_line":"                    # morph a data file into a meta file;"},{"line_number":7916,"context_line":"                    # note: a real meta file would not have content"},{"line_number":7917,"context_line":"                    dest_file \u003d dest_file.replace("},{"line_number":7918,"context_line":"                        \u0027#%d.data\u0027 % frag_info[\u0027frag_index\u0027], \u0027.meta\u0027)"},{"line_number":7919,"context_line":"                move(os.path.join(src, src_files[0]),"},{"line_number":7920,"context_line":"                     os.path.join(dest, dest_file))"},{"line_number":7921,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"fb212949_fc0f839d","line":7918,"range":{"start_line":7918,"start_character":24,"end_line":7918,"end_character":34},"updated":"2021-01-15 22:58:09.000000000","message":"So this only works with durable\u003dFalse then? I wonder if there should be two schemas, like\n\n {ref: ..., meta: True}\n\nand\n\n {ref: ..., frag_index: N, durable: bool}\n\nSpeaking of, we should probably update the comment above.","commit_id":"2bc88671a50ed96446f8c9d2f9814775976f79ae"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"ce86f3588ba7ffb213c5121de253691812fe2ee2","unresolved":true,"context_lines":[{"line_number":7915,"context_line":"                    # morph a data file into a meta file;"},{"line_number":7916,"context_line":"                    # note: a real meta file would not have content"},{"line_number":7917,"context_line":"                    dest_file \u003d dest_file.replace("},{"line_number":7918,"context_line":"                        \u0027#%d.data\u0027 % frag_info[\u0027frag_index\u0027], \u0027.meta\u0027)"},{"line_number":7919,"context_line":"                move(os.path.join(src, src_files[0]),"},{"line_number":7920,"context_line":"                     os.path.join(dest, dest_file))"},{"line_number":7921,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"c941f74a_a26c341e","line":7918,"range":{"start_line":7918,"start_character":24,"end_line":7918,"end_character":34},"in_reply_to":"fb212949_fc0f839d","updated":"2021-01-19 11:35:08.000000000","message":"Done\n\nThe frag_index is used to dig out a data file to copy back to the obj dir so I\u0027ll leave that but remove the need for durable\u003dFalse","commit_id":"2bc88671a50ed96446f8c9d2f9814775976f79ae"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"a1382d6743913287898ee4c5249783079387e28b","unresolved":true,"context_lines":[{"line_number":8052,"context_line":"        }"},{"line_number":8053,"context_line":""},{"line_number":8054,"context_line":"        resp \u003d self._setup_nodes_and_do_GET(objs, node_state)"},{"line_number":8055,"context_line":"        self.assertEqual(resp.status_int, 200)"},{"line_number":8056,"context_line":"        self.assertEqual(resp.body, objs[\u0027obj1\u0027][\u0027body\u0027])"},{"line_number":8057,"context_line":"        self.assertEqual(ts_3.normal, resp.headers[\u0027X-Timestamp\u0027])"},{"line_number":8058,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"bf3c6682_e44aa9db","line":8055,"updated":"2021-01-15 22:58:09.000000000","message":"Pops with a 503 when I back out the fix.","commit_id":"2bc88671a50ed96446f8c9d2f9814775976f79ae"}]}
