)]}'
{"swift/proxy/controllers/base.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"654ec616dfa3ce84614c83c73d7d448f7038af64","unresolved":false,"context_lines":[{"line_number":1148,"context_line":"                valid_ps \u003d True"},{"line_number":1149,"context_line":"                src_ts \u003d Timestamp(src_headers.get(\u0027x-backend-timestamp\u0027, 0))"},{"line_number":1150,"context_line":"                for (i, (status, headers)) in enumerate(zip("},{"line_number":1151,"context_line":"                        self.statuses, self.source_headers)):"},{"line_number":1152,"context_line":"                    hdrs \u003d HeaderKeyDict(headers)"},{"line_number":1153,"context_line":"                    ts \u003d Timestamp(hdrs.get(\u0027X-Backend-Timestamp\u0027, 0))"},{"line_number":1154,"context_line":"                    if status \u003d\u003d HTTP_NOT_FOUND and ts \u003e src_ts:"}],"source_content_type":"text/x-python","patch_set":1,"id":"7a8ec9b2_05a3069e","line":1151,"updated":"2016-09-15 22:30:37.000000000","message":"this seems to be a somewhat inefficient search - to dig through all of the response headers every time to find the most recently timestamp of a 404 response iff such a 404 response exists?\n\nWith X-Newest I don\u0027t think we\u0027d even have a 404 responses that includes x-backend-timestamps fields - but we\u0027re still doing this search 2 * replica times?\n\nas we discover 404\u0027s can we just keep a local \"max_404_timestamp\" up-to-date such that when we get a 200 just double check \"possible_timestamp \u003c max_404_timestamp\" then convert it a 404 instead?","commit_id":"b5a198f2ca86ab3858d3d70df7faa42d1f8b8949"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"dc17319603f208743f171ca2969caf8c8f1a4639","unresolved":false,"context_lines":[{"line_number":1152,"context_line":""},{"line_number":1153,"context_line":"                # a possible source should only be added as a valid source"},{"line_number":1154,"context_line":"                # if its timestamp is newer than previously found tombstones"},{"line_number":1155,"context_line":"                hdrs \u003d HeaderKeyDict(possible_source.getheaders())"},{"line_number":1156,"context_line":"                ps_timestamp \u003d Timestamp(hdrs.get(\u0027X-Backend-Timestamp\u0027, 0))"},{"line_number":1157,"context_line":"                if ps_timestamp \u003e\u003d self.latest_404_timestamp:"},{"line_number":1158,"context_line":"                    self.statuses.append(possible_source.status)"}],"source_content_type":"text/x-python","patch_set":4,"id":"ba5da102_13a7700b","line":1155,"range":{"start_line":1155,"start_character":23,"end_line":1155,"end_character":36},"updated":"2016-11-03 21:34:07.000000000","message":"I thought the point of pulling src_headers out of the if self.used_source_etag: block was so we could avoid this and just say\n\n src_headers.get(\u0027x-backend-timestamp\u0027, 0)\n\nbelow?","commit_id":"bc73ea19efef068ed01a05f163bbe06d96476436"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"5c41927aae0d002a0fb21eaea38795d5dde9648b","unresolved":false,"context_lines":[{"line_number":1152,"context_line":""},{"line_number":1153,"context_line":"                # a possible source should only be added as a valid source"},{"line_number":1154,"context_line":"                # if its timestamp is newer than previously found tombstones"},{"line_number":1155,"context_line":"                hdrs \u003d HeaderKeyDict(possible_source.getheaders())"},{"line_number":1156,"context_line":"                ps_timestamp \u003d Timestamp(hdrs.get(\u0027X-Backend-Timestamp\u0027, 0))"},{"line_number":1157,"context_line":"                if ps_timestamp \u003e\u003d self.latest_404_timestamp:"},{"line_number":1158,"context_line":"                    self.statuses.append(possible_source.status)"}],"source_content_type":"text/x-python","patch_set":4,"id":"1a430d35_b8c1f482","line":1155,"range":{"start_line":1155,"start_character":23,"end_line":1155,"end_character":36},"in_reply_to":"ba5da102_13a7700b","updated":"2017-10-24 18:36:05.000000000","message":"duh! done","commit_id":"bc73ea19efef068ed01a05f163bbe06d96476436"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"dc17319603f208743f171ca2969caf8c8f1a4639","unresolved":false,"context_lines":[{"line_number":1170,"context_line":"            self.source_headers.append(possible_source.getheaders())"},{"line_number":1171,"context_line":""},{"line_number":1172,"context_line":"            # if 404, record the timestamp"},{"line_number":1173,"context_line":"            if self.server_type \u003d\u003d \u0027Object\u0027 and \\"},{"line_number":1174,"context_line":"                    possible_source.status \u003d\u003d HTTP_NOT_FOUND:"},{"line_number":1175,"context_line":"                hdrs \u003d HeaderKeyDict(possible_source.getheaders())"},{"line_number":1176,"context_line":"                ts \u003d Timestamp(hdrs.get(\u0027X-Backend-Timestamp\u0027, 0))"}],"source_content_type":"text/x-python","patch_set":4,"id":"ba5da102_d33c1895","line":1173,"range":{"start_line":1173,"start_character":36,"end_line":1173,"end_character":42},"updated":"2016-11-03 21:34:07.000000000","message":"Why don\u0027t we want similar behavior for account/container responses? Or is it that we simply *can\u0027t* reliably?","commit_id":"bc73ea19efef068ed01a05f163bbe06d96476436"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"c3c459840aed0ff79e1cfecac487da1f1caaf56a","unresolved":false,"context_lines":[{"line_number":1152,"context_line":"                # a possible source should only be added as a valid source"},{"line_number":1153,"context_line":"                # if its timestamp is newer than previously found tombstones"},{"line_number":1154,"context_line":"                ps_timestamp \u003d Timestamp("},{"line_number":1155,"context_line":"                    src_headers.get(\u0027x-backend-timestamp\u0027, 0))"},{"line_number":1156,"context_line":"                if ps_timestamp \u003e\u003d self.latest_404_timestamp:"},{"line_number":1157,"context_line":"                    self.statuses.append(possible_source.status)"},{"line_number":1158,"context_line":"                    self.reasons.append(possible_source.reason)"}],"source_content_type":"text/x-python","patch_set":5,"id":"da36d5c6_afbcc606","line":1155,"range":{"start_line":1155,"start_character":37,"end_line":1155,"end_character":56},"updated":"2017-02-24 05:05:01.000000000","message":"I think we want x-backend-data-timestamp here. If we get back\n\n t1.data + t3.meta\n t2.ts\n\nand no .data after t2, we have enough in our head to know that we should 404.","commit_id":"51f4721e4da7d0adde26c2bd12f912ada32327c7"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"e4f71698551d9a31c210877d2c92b246c82d2379","unresolved":false,"context_lines":[{"line_number":1152,"context_line":"                # a possible source should only be added as a valid source"},{"line_number":1153,"context_line":"                # if its timestamp is newer than previously found tombstones"},{"line_number":1154,"context_line":"                ps_timestamp \u003d Timestamp("},{"line_number":1155,"context_line":"                    src_headers.get(\u0027x-backend-timestamp\u0027, 0))"},{"line_number":1156,"context_line":"                if ps_timestamp \u003e\u003d self.latest_404_timestamp:"},{"line_number":1157,"context_line":"                    self.statuses.append(possible_source.status)"},{"line_number":1158,"context_line":"                    self.reasons.append(possible_source.reason)"}],"source_content_type":"text/x-python","patch_set":5,"id":"df140735_00878cd9","line":1155,"range":{"start_line":1155,"start_character":37,"end_line":1155,"end_character":56},"in_reply_to":"da36d5c6_afbcc606","updated":"2017-06-01 21:34:35.000000000","message":"I actually changed it to something similar to source_key()","commit_id":"51f4721e4da7d0adde26c2bd12f912ada32327c7"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"09e5b69302903bb0374adbd286fab85ea7001796","unresolved":false,"context_lines":[{"line_number":1159,"context_line":"                    self.bodies.append(None)"},{"line_number":1160,"context_line":"                    self.source_headers.append(possible_source.getheaders())"},{"line_number":1161,"context_line":"                    self.sources.append((possible_source, node))"},{"line_number":1162,"context_line":"                    if not self.newest:  # one good source is enough"},{"line_number":1163,"context_line":"                        return True"},{"line_number":1164,"context_line":"        else:"},{"line_number":1165,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"da36d5c6_2db1cc47","line":1162,"updated":"2017-02-23 18:36:20.000000000","message":"So what happens when the client requests x-newest, then we see, in order,\n\n 200 at t1\n 404 at t2\n 200 at t1 \u003c-- gets thrown away because it predates t2\n 404 at t2\n 404       \u003c-- no timestamp; not a tombstone\n 500\n\n(assuming 3 replica, 2*replica request_node_count)\n\nWould we return that first 200? Do we ever make another comparison against latest_404_timestamp?","commit_id":"51f4721e4da7d0adde26c2bd12f912ada32327c7"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"0a0149699e182df4ddbcfa3d404111b65e887de4","unresolved":false,"context_lines":[{"line_number":1159,"context_line":"                    self.bodies.append(None)"},{"line_number":1160,"context_line":"                    self.source_headers.append(possible_source.getheaders())"},{"line_number":1161,"context_line":"                    self.sources.append((possible_source, node))"},{"line_number":1162,"context_line":"                    if not self.newest:  # one good source is enough"},{"line_number":1163,"context_line":"                        return True"},{"line_number":1164,"context_line":"        else:"},{"line_number":1165,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"da36d5c6_ecf7b156","line":1162,"in_reply_to":"da36d5c6_2db1cc47","updated":"2017-02-23 20:56:51.000000000","message":"Yup, sure enough, we\u0027ll 200. Unit test: http://paste.openstack.org/show/600281/","commit_id":"51f4721e4da7d0adde26c2bd12f912ada32327c7"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"e4f71698551d9a31c210877d2c92b246c82d2379","unresolved":false,"context_lines":[{"line_number":1159,"context_line":"                    self.bodies.append(None)"},{"line_number":1160,"context_line":"                    self.source_headers.append(possible_source.getheaders())"},{"line_number":1161,"context_line":"                    self.sources.append((possible_source, node))"},{"line_number":1162,"context_line":"                    if not self.newest:  # one good source is enough"},{"line_number":1163,"context_line":"                        return True"},{"line_number":1164,"context_line":"        else:"},{"line_number":1165,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"df140735_7d98341a","line":1162,"in_reply_to":"da36d5c6_ecf7b156","updated":"2017-06-01 21:34:35.000000000","message":"I added a fix, but that looks pretty hacky, let me know what you think.","commit_id":"51f4721e4da7d0adde26c2bd12f912ada32327c7"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"09e5b69302903bb0374adbd286fab85ea7001796","unresolved":false,"context_lines":[{"line_number":1169,"context_line":"            self.source_headers.append(possible_source.getheaders())"},{"line_number":1170,"context_line":""},{"line_number":1171,"context_line":"            # if 404, record the timestamp"},{"line_number":1172,"context_line":"            if self.server_type \u003d\u003d \u0027Object\u0027 and \\"},{"line_number":1173,"context_line":"                    possible_source.status \u003d\u003d HTTP_NOT_FOUND:"},{"line_number":1174,"context_line":"                hdrs \u003d HeaderKeyDict(possible_source.getheaders())"},{"line_number":1175,"context_line":"                ts \u003d Timestamp(hdrs.get(\u0027X-Backend-Timestamp\u0027, 0))"}],"source_content_type":"text/x-python","patch_set":5,"id":"da36d5c6_b200bd02","line":1172,"updated":"2017-02-23 18:36:20.000000000","message":"Can/should we do this for non-objects, too?","commit_id":"51f4721e4da7d0adde26c2bd12f912ada32327c7"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"5e81c3ded1f307067ab8fbb3690a2addcf75a648","unresolved":false,"context_lines":[{"line_number":1169,"context_line":"            self.source_headers.append(possible_source.getheaders())"},{"line_number":1170,"context_line":""},{"line_number":1171,"context_line":"            # if 404, record the timestamp"},{"line_number":1172,"context_line":"            if self.server_type \u003d\u003d \u0027Object\u0027 and \\"},{"line_number":1173,"context_line":"                    possible_source.status \u003d\u003d HTTP_NOT_FOUND:"},{"line_number":1174,"context_line":"                hdrs \u003d HeaderKeyDict(possible_source.getheaders())"},{"line_number":1175,"context_line":"                ts \u003d Timestamp(hdrs.get(\u0027X-Backend-Timestamp\u0027, 0))"}],"source_content_type":"text/x-python","patch_set":5,"id":"df140735_06a9e4dd","line":1172,"in_reply_to":"da36d5c6_b200bd02","updated":"2017-05-31 22:13:45.000000000","message":"I\u0027d be interested to try and remove it only for code complexity issues - I don\u0027t find it strictly necessary; but if we code it this way someone will assume it was on purpose (they can always come read these review comments).\n\nI don\u0027t have a good gut feeling for how often clients encounter 404\u0027s on container listings - it might be useful.  The scenario would be something like delete container at t2 and 2/3 replicas respond 2XX then on a subsequent GET you still see the remaining container.\n\nThe question is do containers return an accurate x-backend-timestamp with their 404 responses to indicate when the container was deleted vs 200 response headers indicating the last put-timestamp or object-update?\n\nPerhaps a comment that state explicitly the limit to Object\u0027s was to reduce scope - and in principle it \"should\" be able to be applied with a/c with sufficient testing and validation?","commit_id":"51f4721e4da7d0adde26c2bd12f912ada32327c7"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"9fe82782a50accccbc250222c56451a177ca7c8e","unresolved":false,"context_lines":[{"line_number":1154,"context_line":"                ps_timestamp \u003d Timestamp("},{"line_number":1155,"context_line":"                    src_headers.get(\u0027x-backend-data-timestamp\u0027) or"},{"line_number":1156,"context_line":"                    src_headers.get(\u0027x-backend-timestamp\u0027) or"},{"line_number":1157,"context_line":"                    src_headers.get(\u0027x-put-timestamp\u0027) or"},{"line_number":1158,"context_line":"                    src_headers.get(\u0027x-timestamp\u0027) or 0)"},{"line_number":1159,"context_line":"                if ps_timestamp \u003e\u003d self.latest_404_timestamp:"},{"line_number":1160,"context_line":"                    self.statuses.append(possible_source.status)"}],"source_content_type":"text/x-python","patch_set":6,"id":"df140735_c3597a8e","line":1157,"updated":"2017-06-01 22:06:41.000000000","message":"Oh boy, so many permutations...\n\nI\u0027ve gotta look into the history of all of these, but my gut says we want x-put-timestamp higher priority than x-backend-timestamp...","commit_id":"ca50202cc0bbcd5fa9bf6e415e45a7d16e6ba637"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"305a6765472beb3ceb1385daef58ab6045a96cdb","unresolved":false,"context_lines":[{"line_number":1154,"context_line":"                ps_timestamp \u003d Timestamp("},{"line_number":1155,"context_line":"                    src_headers.get(\u0027x-backend-data-timestamp\u0027) or"},{"line_number":1156,"context_line":"                    src_headers.get(\u0027x-backend-timestamp\u0027) or"},{"line_number":1157,"context_line":"                    src_headers.get(\u0027x-put-timestamp\u0027) or"},{"line_number":1158,"context_line":"                    src_headers.get(\u0027x-timestamp\u0027) or 0)"},{"line_number":1159,"context_line":"                if ps_timestamp \u003e\u003d self.latest_404_timestamp:"},{"line_number":1160,"context_line":"                    self.statuses.append(possible_source.status)"}],"source_content_type":"text/x-python","patch_set":6,"id":"df140735_1aa455a5","line":1157,"in_reply_to":"df140735_c3597a8e","updated":"2017-06-02 20:05:05.000000000","message":"yeah, I basically used the same exact thing as source_keys plus added x-backend-data-timestamp at the top.","commit_id":"ca50202cc0bbcd5fa9bf6e415e45a7d16e6ba637"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"9fe82782a50accccbc250222c56451a177ca7c8e","unresolved":false,"context_lines":[{"line_number":1178,"context_line":"            if self.server_type \u003d\u003d \u0027Object\u0027 and \\"},{"line_number":1179,"context_line":"                    possible_source.status \u003d\u003d HTTP_NOT_FOUND:"},{"line_number":1180,"context_line":"                hdrs \u003d HeaderKeyDict(possible_source.getheaders())"},{"line_number":1181,"context_line":"                ts \u003d Timestamp(hdrs.get(\u0027X-Backend-Timestamp\u0027, 0))"},{"line_number":1182,"context_line":"                if ts \u003e self.latest_404_timestamp:"},{"line_number":1183,"context_line":"                    self.latest_404_timestamp \u003d ts"},{"line_number":1184,"context_line":"            if possible_source.status \u003d\u003d HTTP_INSUFFICIENT_STORAGE:"}],"source_content_type":"text/x-python","patch_set":6,"id":"df140735_7e424540","line":1181,"updated":"2017-06-01 22:06:41.000000000","message":"Thinking more about my earlier concern, what headers do we get back with a tombstone that also has some meta? Which timestamp is used for x-backend-timestamp?","commit_id":"ca50202cc0bbcd5fa9bf6e415e45a7d16e6ba637"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"305a6765472beb3ceb1385daef58ab6045a96cdb","unresolved":false,"context_lines":[{"line_number":1178,"context_line":"            if self.server_type \u003d\u003d \u0027Object\u0027 and \\"},{"line_number":1179,"context_line":"                    possible_source.status \u003d\u003d HTTP_NOT_FOUND:"},{"line_number":1180,"context_line":"                hdrs \u003d HeaderKeyDict(possible_source.getheaders())"},{"line_number":1181,"context_line":"                ts \u003d Timestamp(hdrs.get(\u0027X-Backend-Timestamp\u0027, 0))"},{"line_number":1182,"context_line":"                if ts \u003e self.latest_404_timestamp:"},{"line_number":1183,"context_line":"                    self.latest_404_timestamp \u003d ts"},{"line_number":1184,"context_line":"            if possible_source.status \u003d\u003d HTTP_INSUFFICIENT_STORAGE:"}],"source_content_type":"text/x-python","patch_set":6,"id":"df140735_fa7be124","line":1181,"in_reply_to":"df140735_7e424540","updated":"2017-06-02 20:05:05.000000000","message":"Not sure I understand your question, but X-Timestamp is stored on the .ts file\n\n[vagrant@server0 4]$ swift-raw-metadata node/sdb4/objects/856/fc3/d6189d8bc3e1a7755fa0c9b1a2e1ffc3/1496413846.93633.ts \n{\u0027X-Timestamp\u0027: \u00271496413846.93633\u0027, \u0027name\u0027: \u0027/AUTH_test/c1/obj\u0027}\n\nand is returned as X-Backend-Timestamp from the object server:\n\n[vagrant@server0 4]$ curl -g -I -XHEAD \"http://127.0.0.1:6040/sdb4/856/AUTH_test/c1/obj\" -H \"X-Backend-Storage-Policy-Index: 0\"\nHTTP/1.1 404 Not Found\nX-Backend-Timestamp: 1496413846.93633\nContent-Type: text/html; charset\u003dUTF-8\nContent-Length: 0\nDate: Fri, 02 Jun 2017 17:26:49 GMT","commit_id":"ca50202cc0bbcd5fa9bf6e415e45a7d16e6ba637"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"9fe82782a50accccbc250222c56451a177ca7c8e","unresolved":false,"context_lines":[{"line_number":1224,"context_line":"            for s in self.sources:"},{"line_number":1225,"context_line":"                source_time \u003d source_key(s[0])"},{"line_number":1226,"context_line":"                if source_time \u003c self.latest_404_timestamp:"},{"line_number":1227,"context_line":"                    s_junk, n_junk \u003d self.sources.pop()"},{"line_number":1228,"context_line":""},{"line_number":1229,"context_line":"        if self.sources:"},{"line_number":1230,"context_line":"            self.sources.sort(key\u003dlambda s: source_key(s[0]))"}],"source_content_type":"text/x-python","patch_set":6,"id":"df140735_0391b247","line":1227,"updated":"2017-06-01 22:06:41.000000000","message":"...we just start popping them off the *end*, while we\u0027re looping through the list? I feel like we want something more like\n\n self.sources \u003d [s for s in self.sources\n                 if source_key(s[0]) \u003e\u003d self.latest_404_timestamp]\n\nwhich doesn\u0027t even need the if. Though again I\u0027m worrying about a .meta making the object seem newer than it should be -- I\u0027m not sure source_key is the right answer here...","commit_id":"ca50202cc0bbcd5fa9bf6e415e45a7d16e6ba637"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"305a6765472beb3ceb1385daef58ab6045a96cdb","unresolved":false,"context_lines":[{"line_number":1224,"context_line":"            for s in self.sources:"},{"line_number":1225,"context_line":"                source_time \u003d source_key(s[0])"},{"line_number":1226,"context_line":"                if source_time \u003c self.latest_404_timestamp:"},{"line_number":1227,"context_line":"                    s_junk, n_junk \u003d self.sources.pop()"},{"line_number":1228,"context_line":""},{"line_number":1229,"context_line":"        if self.sources:"},{"line_number":1230,"context_line":"            self.sources.sort(key\u003dlambda s: source_key(s[0]))"}],"source_content_type":"text/x-python","patch_set":6,"id":"df140735_e760e503","line":1227,"in_reply_to":"df140735_0391b247","updated":"2017-06-02 20:05:05.000000000","message":"we could create a common method similar to source_key, or even add a parameter to source_key where the x-backend-data-timestamp is first looked at.","commit_id":"ca50202cc0bbcd5fa9bf6e415e45a7d16e6ba637"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"4a8ea92e48b7b67fd3d57d408aad4af6cd644ea8","unresolved":false,"context_lines":[{"line_number":91,"context_line":""},{"line_number":92,"context_line":"    :param resp: bufferedhttp response object"},{"line_number":93,"context_line":"    \"\"\""},{"line_number":94,"context_line":"    return Timestamp(resp.getheader(\u0027x-backend-timestamp\u0027) or"},{"line_number":95,"context_line":"                     resp.getheader(\u0027x-put-timestamp\u0027) or"},{"line_number":96,"context_line":"                     resp.getheader(\u0027x-timestamp\u0027) or 0)"},{"line_number":97,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"3f4b6375_54f1b194","line":94,"updated":"2017-10-24 05:17:41.000000000","message":"Seeing as we\u0027re using an \u0027or\u0027 here, it should be safe to add an:\n\n  resp.getheader(\u0027x-backend-data-timestamp\u0027) or\n\nOtherwise, the correct source could be dropped down in the X-Newest check. something like a delete at t2 on some node, but there exists some older metadata of t1 along side new data at t3.. although I can\u0027t see how we\u0027d get older metadata then data unless there was a replication failure:\n  \n  t1 metadata\n  t3 data\n  t2 ts\n\nWith the check as it is, we\u0027d only compare t1 with t2 and never look at t3.\n\nHowever, I can\u0027t think of a way this state could happen, unless a call to cleaup_ondisk_files after a replication sync never happens. So maybe it\u0027s fine.\n\nBut adding it shouldn\u0027t hurt right?","commit_id":"db10ead6e7974504fd0db4e13299689d2b82e859"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"5c41927aae0d002a0fb21eaea38795d5dde9648b","unresolved":false,"context_lines":[{"line_number":91,"context_line":""},{"line_number":92,"context_line":"    :param resp: bufferedhttp response object"},{"line_number":93,"context_line":"    \"\"\""},{"line_number":94,"context_line":"    return Timestamp(resp.getheader(\u0027x-backend-timestamp\u0027) or"},{"line_number":95,"context_line":"                     resp.getheader(\u0027x-put-timestamp\u0027) or"},{"line_number":96,"context_line":"                     resp.getheader(\u0027x-timestamp\u0027) or 0)"},{"line_number":97,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"3f4b6375_7e8a356a","line":94,"in_reply_to":"3f4b6375_54f1b194","updated":"2017-10-24 18:36:05.000000000","message":"Done","commit_id":"db10ead6e7974504fd0db4e13299689d2b82e859"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"4a8ea92e48b7b67fd3d57d408aad4af6cd644ea8","unresolved":false,"context_lines":[{"line_number":743,"context_line":"        self.concurrency \u003d concurrency"},{"line_number":744,"context_line":"        self.node \u003d None"},{"line_number":745,"context_line":"        self.header_provider \u003d header_provider"},{"line_number":746,"context_line":"        self.latest_404_timestamp \u003d 0"},{"line_number":747,"context_line":""},{"line_number":748,"context_line":"        # stuff from request"},{"line_number":749,"context_line":"        self.req_method \u003d req.method"}],"source_content_type":"text/x-python","patch_set":7,"id":"3f4b6375_b1e917b8","line":746,"updated":"2017-10-24 05:17:41.000000000","message":"NIT: we assume in all checks and when we update it that latest_404_timestamp is a Timestamp, yet initially it\u0027s a 0. Which works, so ok, but it may potentially get us into trouble one day if there never is a 404, yet we want to manipulate this timestamp for some reason, so:\n\n  self.latest_404_timestamp \u003d Timestamp(0)\n\nWould be more correct.","commit_id":"db10ead6e7974504fd0db4e13299689d2b82e859"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"5c41927aae0d002a0fb21eaea38795d5dde9648b","unresolved":false,"context_lines":[{"line_number":743,"context_line":"        self.concurrency \u003d concurrency"},{"line_number":744,"context_line":"        self.node \u003d None"},{"line_number":745,"context_line":"        self.header_provider \u003d header_provider"},{"line_number":746,"context_line":"        self.latest_404_timestamp \u003d 0"},{"line_number":747,"context_line":""},{"line_number":748,"context_line":"        # stuff from request"},{"line_number":749,"context_line":"        self.req_method \u003d req.method"}],"source_content_type":"text/x-python","patch_set":7,"id":"3f4b6375_5e7bf979","line":746,"in_reply_to":"3f4b6375_b1e917b8","updated":"2017-10-24 18:36:05.000000000","message":"Done","commit_id":"db10ead6e7974504fd0db4e13299689d2b82e859"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"fa1ceb2e6b92cf228c64e9827706320d007b6208","unresolved":false,"context_lines":[{"line_number":1185,"context_line":"                    self.source_headers.append(possible_source.getheaders())"},{"line_number":1186,"context_line":"                    self.sources.append((possible_source, node))"},{"line_number":1187,"context_line":"                    if not self.newest:  # one good source is enough"},{"line_number":1188,"context_line":"                        return True"},{"line_number":1189,"context_line":"        else:"},{"line_number":1190,"context_line":""},{"line_number":1191,"context_line":"            self.statuses.append(possible_source.status)"}],"source_content_type":"text/x-python","patch_set":8,"id":"3f4b6375_28c38359","line":1188,"updated":"2017-11-02 09:29:14.000000000","message":"Hmm... I\u0027m wondering if it\u0027s ok to loose source info (status, reason, etc...) when ps_timestamp is older than latest_404_timestamp.\n\nThe original  code seems to add those info in any cases. (even in the case, different etag object found, it adds HTTP_NOT_FOUND to the status list.","commit_id":"8d882095375dc53acdafafac40aa2efc3bafbcd4"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"c51b36463c9007e036604cd1141353afdc5dba19","unresolved":false,"context_lines":[{"line_number":1185,"context_line":"                    self.source_headers.append(possible_source.getheaders())"},{"line_number":1186,"context_line":"                    self.sources.append((possible_source, node))"},{"line_number":1187,"context_line":"                    if not self.newest:  # one good source is enough"},{"line_number":1188,"context_line":"                        return True"},{"line_number":1189,"context_line":"        else:"},{"line_number":1190,"context_line":""},{"line_number":1191,"context_line":"            self.statuses.append(possible_source.status)"}],"source_content_type":"text/x-python","patch_set":8,"id":"3f4b6375_4cdeb33e","line":1188,"in_reply_to":"3f4b6375_28c38359","updated":"2017-11-03 02:33:57.000000000","message":"OK. This works in my view. I was worried about lack of adding to the status to self.statuses list could cause 503 in the best_response but it never happened at my follow up.\n\nIn my conclusion, this is safe because when skipping the stale object here, at least the newer 404 will remain in the list and then the best_response will be able to find the 404 with quorum_size(len(statuses)) (i.e. 1 for quorum) .\n\nAs well as this, it seems like adding HTTP_NOT_FOUND when the different ec etag case seems redundant (actually, when comment out the L1168-L1171, no unit tests failed but that\u0027s not related to this change so it\u0027s ok to be this as it is.","commit_id":"8d882095375dc53acdafafac40aa2efc3bafbcd4"}],"test/probe/test_object_handoff.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"dc17319603f208743f171ca2969caf8c8f1a4639","unresolved":false,"context_lines":[{"line_number":286,"context_line":"        handoff_data \u003d direct_client.direct_get_object("},{"line_number":287,"context_line":"            another_onode, opart, self.account, container, obj, headers\u003d{"},{"line_number":288,"context_line":"                \u0027X-Backend-Storage-Policy-Index\u0027: self.policy.idx})[-1]"},{"line_number":289,"context_line":"        self.assertEqual(handoff_data, \u0027VERIFY\u0027)"},{"line_number":290,"context_line":""},{"line_number":291,"context_line":"        # Indirectly (i.e., through proxy) try to GET object, it should return"},{"line_number":292,"context_line":"        # a 404, before bug #1560574, the proxy would return the stale object"}],"source_content_type":"text/x-python","patch_set":4,"id":"ba5da102_587587c8","line":289,"range":{"start_line":289,"start_character":40,"end_line":289,"end_character":46},"updated":"2016-11-03 21:34:07.000000000","message":"Didn\u0027t we have to do something special to have the probe tests account for encryption in the pipeline?\n\nCompare against our stashing of on-disk data around line 61 then verifying again at line 86.","commit_id":"bc73ea19efef068ed01a05f163bbe06d96476436"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"5c41927aae0d002a0fb21eaea38795d5dde9648b","unresolved":false,"context_lines":[{"line_number":286,"context_line":"        handoff_data \u003d direct_client.direct_get_object("},{"line_number":287,"context_line":"            another_onode, opart, self.account, container, obj, headers\u003d{"},{"line_number":288,"context_line":"                \u0027X-Backend-Storage-Policy-Index\u0027: self.policy.idx})[-1]"},{"line_number":289,"context_line":"        self.assertEqual(handoff_data, \u0027VERIFY\u0027)"},{"line_number":290,"context_line":""},{"line_number":291,"context_line":"        # Indirectly (i.e., through proxy) try to GET object, it should return"},{"line_number":292,"context_line":"        # a 404, before bug #1560574, the proxy would return the stale object"}],"source_content_type":"text/x-python","patch_set":4,"id":"1a430d35_58cad0a2","line":289,"range":{"start_line":289,"start_character":40,"end_line":289,"end_character":46},"in_reply_to":"ba5da102_587587c8","updated":"2017-10-24 18:36:05.000000000","message":"Done","commit_id":"bc73ea19efef068ed01a05f163bbe06d96476436"}]}
