)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"7c9f1fc4159833fac58575f845520c1e15f36e2f","unresolved":false,"context_lines":[{"line_number":17,"context_line":"request, when set this timeout becomes 0, meaning all requests are"},{"line_number":18,"context_line":"sent at the same time."},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"It also adds a new perameter to the proxy configuration called"},{"line_number":21,"context_line":"concurrency_timeout, which allows you to change the timeout to"},{"line_number":22,"context_line":"something other then 0. (0 \u003c\u003d concurrency_timeout \u003c node_timeout)"},{"line_number":23,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":18,"id":"fa1b9901_be954841","line":20,"updated":"2015-08-17 21:01:18.000000000","message":"Thanks, this change was discussed at the hackathon last week and will be reworded. I\u0027ll make the change in the commit message when I push it :)","commit_id":"882ac5590de4388347e2a9216894f10ade8da765"},{"author":{"_account_id":16896,"name":"Ondřej Nový","email":"novy@ondrej.org","username":"onovy"},"change_message_id":"5dc5be83e277686ec6fe5bb343ad80b06c77168c","unresolved":false,"context_lines":[{"line_number":17,"context_line":"request, when set this timeout becomes 0, meaning all requests are"},{"line_number":18,"context_line":"sent at the same time."},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"It also adds a new perameter to the proxy configuration called"},{"line_number":21,"context_line":"concurrency_timeout, which allows you to change the timeout to"},{"line_number":22,"context_line":"something other then 0. (0 \u003c\u003d concurrency_timeout \u003c node_timeout)"},{"line_number":23,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":18,"id":"fa1b9901_a3d8cf1e","line":20,"updated":"2015-08-17 20:41:56.000000000","message":"typo perameter -\u003e parameter.","commit_id":"882ac5590de4388347e2a9216894f10ade8da765"}],"doc/source/deployment_guide.rst":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"c89698fa5483e41933e23cfdac0492ac41063b7f","unresolved":false,"context_lines":[{"line_number":1396,"context_line":"                                               any other number will stagger the"},{"line_number":1397,"context_line":"                                               firing of the threads. This number"},{"line_number":1398,"context_line":"                                               should be between 0 and node_timeout."},{"line_number":1399,"context_line":"                                               The default is node_timeout (10)."},{"line_number":1400,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":1401,"context_line":""},{"line_number":1402,"context_line":"[tempauth]"}],"source_content_type":"text/x-rst","patch_set":25,"id":"9aed3d3a_2a79bec8","line":1399,"updated":"2016-03-01 13:59:55.000000000","message":"I think the default was less than node_timeout when concurrent_gets is on, maybe?","commit_id":"bd67c1959fddd278ec9bae2752a59a8cdc42a5ff"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d70f43c16de45b9f03d461614f6db091fd109319","unresolved":false,"context_lines":[{"line_number":1389,"context_line":"                                               the EC case, this parameter only"},{"line_number":1390,"context_line":"                                               effects an EC HEAD as an EC GET"},{"line_number":1391,"context_line":"                                               behaves differently."},{"line_number":1392,"context_line":"concurrency_timeout           10               This parameter controls how long"},{"line_number":1393,"context_line":"                                               to wait before firing off the"},{"line_number":1394,"context_line":"                                               next concurrent_get thread. A"},{"line_number":1395,"context_line":"                                               value of 0 would we fully concurrent"}],"source_content_type":"text/x-rst","patch_set":26,"id":"5aef4532_d9749669","line":1392,"updated":"2016-03-09 16:09:31.000000000","message":"default is conn_timeout","commit_id":"4d6d54f228001cd835e3abf6d8fca82d1fae562d"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"c25fb967237a2b9740687f5c73dd45a902ce23ae","unresolved":false,"context_lines":[{"line_number":1389,"context_line":"                                               the EC case, this parameter only"},{"line_number":1390,"context_line":"                                               effects an EC HEAD as an EC GET"},{"line_number":1391,"context_line":"                                               behaves differently."},{"line_number":1392,"context_line":"concurrency_timeout           10               This parameter controls how long"},{"line_number":1393,"context_line":"                                               to wait before firing off the"},{"line_number":1394,"context_line":"                                               next concurrent_get thread. A"},{"line_number":1395,"context_line":"                                               value of 0 would we fully concurrent"}],"source_content_type":"text/x-rst","patch_set":26,"id":"3afc51ec_8a42be0e","line":1392,"in_reply_to":"5aef4532_d9749669","updated":"2016-03-15 02:15:34.000000000","message":"Done","commit_id":"4d6d54f228001cd835e3abf6d8fca82d1fae562d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d70f43c16de45b9f03d461614f6db091fd109319","unresolved":false,"context_lines":[{"line_number":1396,"context_line":"                                               any other number will stagger the"},{"line_number":1397,"context_line":"                                               firing of the threads. This number"},{"line_number":1398,"context_line":"                                               should be between 0 and node_timeout."},{"line_number":1399,"context_line":"                                               The default is node_timeout (10)."},{"line_number":1400,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":1401,"context_line":""},{"line_number":1402,"context_line":"[tempauth]"}],"source_content_type":"text/x-rst","patch_set":26,"id":"5aef4532_19027eb4","line":1399,"updated":"2016-03-09 16:09:31.000000000","message":"default is conn_timeout","commit_id":"4d6d54f228001cd835e3abf6d8fca82d1fae562d"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"c25fb967237a2b9740687f5c73dd45a902ce23ae","unresolved":false,"context_lines":[{"line_number":1396,"context_line":"                                               any other number will stagger the"},{"line_number":1397,"context_line":"                                               firing of the threads. This number"},{"line_number":1398,"context_line":"                                               should be between 0 and node_timeout."},{"line_number":1399,"context_line":"                                               The default is node_timeout (10)."},{"line_number":1400,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":1401,"context_line":""},{"line_number":1402,"context_line":"[tempauth]"}],"source_content_type":"text/x-rst","patch_set":26,"id":"3afc51ec_6a45b215","line":1399,"in_reply_to":"5aef4532_19027eb4","updated":"2016-03-15 02:15:34.000000000","message":"Done","commit_id":"4d6d54f228001cd835e3abf6d8fca82d1fae562d"}],"etc/proxy-server.conf-sample":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"e65e55003164e7f4d81a56e8e21fe428a07ebf79","unresolved":false,"context_lines":[{"line_number":157,"context_line":"# affinity cases, equally-sorting nodes are still randomly chosen to"},{"line_number":158,"context_line":"# spread load."},{"line_number":159,"context_line":"# The valid values for sorting_method are \"affinity\", \"shuffle\", and \"timing\"."},{"line_number":160,"context_line":"# sorting_method \u003d shuffle"},{"line_number":161,"context_line":"#"},{"line_number":162,"context_line":"# If the \"timing\" sorting_method is used, the timings will only be valid for"},{"line_number":163,"context_line":"# the number of seconds configured by timing_expiry."}],"source_content_type":"application/octet-stream","patch_set":12,"id":"5a890539_d8fe05ae","side":"PARENT","line":160,"updated":"2014-11-21 01:08:36.000000000","message":"OMG, this setting is entirely missing from doc/source/deployment_guide.rst as well as many others :\u0027(","commit_id":"477ec4133bd8dc20183e4a7c9bf9710cdc16548d"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"3061ebb771cd2d1abdcaa8dd7a0bfdb392a85dda","unresolved":false,"context_lines":[{"line_number":157,"context_line":"# affinity cases, equally-sorting nodes are still randomly chosen to"},{"line_number":158,"context_line":"# spread load."},{"line_number":159,"context_line":"# The valid values for sorting_method are \"affinity\", \"shuffle\", and \"timing\"."},{"line_number":160,"context_line":"# sorting_method \u003d shuffle"},{"line_number":161,"context_line":"#"},{"line_number":162,"context_line":"# If the \"timing\" sorting_method is used, the timings will only be valid for"},{"line_number":163,"context_line":"# the number of seconds configured by timing_expiry."}],"source_content_type":"application/octet-stream","patch_set":12,"id":"5a890539_fdc82a58","side":"PARENT","line":160,"in_reply_to":"5a890539_d8fe05ae","updated":"2014-12-01 04:43:15.000000000","message":"Yes it is, good spot :)","commit_id":"477ec4133bd8dc20183e4a7c9bf9710cdc16548d"},{"author":{"_account_id":597,"name":"Pete Zaitcev","email":"zaitcev@kotori.zaitcev.us","username":"zaitcev"},"change_message_id":"94333c8de9435fe9b0613bae29fb97c2b0a14869","unresolved":false,"context_lines":[{"line_number":151,"context_line":"# put_queue_depth \u003d 10"},{"line_number":152,"context_line":"#"},{"line_number":153,"context_line":"# Storage nodes can be chosen at random (shuffle), by using timing"},{"line_number":154,"context_line":"# measurements (timing), by using an explicit match (affinity) or can be"},{"line_number":155,"context_line":"# attempted to be hit at the same time (concurrent)."},{"line_number":156,"context_line":"# Using timing measurements may allow for lower overall latency, while"},{"line_number":157,"context_line":"# using affinity allows for finer control. In both the timing and"}],"source_content_type":"application/octet-stream","patch_set":12,"id":"5a890539_41a2194c","line":154,"updated":"2014-12-02 19:33:50.000000000","message":"\", or by accessing all primary nodes simultaniously (concurrent)\". Be simpler.","commit_id":"17409a3546ce46c51d65befbc1756eed746784d7"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"fb6608da219caa42a54c4867148623b84c325a1a","unresolved":false,"context_lines":[{"line_number":151,"context_line":"# put_queue_depth \u003d 10"},{"line_number":152,"context_line":"#"},{"line_number":153,"context_line":"# Storage nodes can be chosen at random (shuffle), by using timing"},{"line_number":154,"context_line":"# measurements (timing), by using an explicit match (affinity) or can be"},{"line_number":155,"context_line":"# attempted to be hit at the same time (concurrent)."},{"line_number":156,"context_line":"# Using timing measurements may allow for lower overall latency, while"},{"line_number":157,"context_line":"# using affinity allows for finer control. In both the timing and"}],"source_content_type":"application/octet-stream","patch_set":12,"id":"5a890539_e3de7bd9","line":154,"in_reply_to":"5a890539_41a2194c","updated":"2014-12-04 05:21:55.000000000","message":"Done","commit_id":"17409a3546ce46c51d65befbc1756eed746784d7"},{"author":{"_account_id":597,"name":"Pete Zaitcev","email":"zaitcev@kotori.zaitcev.us","username":"zaitcev"},"change_message_id":"94333c8de9435fe9b0613bae29fb97c2b0a14869","unresolved":false,"context_lines":[{"line_number":157,"context_line":"# using affinity allows for finer control. In both the timing and"},{"line_number":158,"context_line":"# affinity cases, equally-sorting nodes are still randomly chosen to"},{"line_number":159,"context_line":"# spread load."},{"line_number":160,"context_line":"# Using concurrent, a request will be sent to all the primary nodes at the same"},{"line_number":161,"context_line":"# time and will use the storage node that responds first."},{"line_number":162,"context_line":"# The valid values for sorting_method are \"affinity\", \"shuffle\", \"timing\", or"},{"line_number":163,"context_line":"# \"concurrent\"."}],"source_content_type":"application/octet-stream","patch_set":12,"id":"5a890539_21b6ed8a","line":160,"updated":"2014-12-02 19:33:50.000000000","message":"I would drop this - concurrent is concurrent.","commit_id":"17409a3546ce46c51d65befbc1756eed746784d7"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"fb6608da219caa42a54c4867148623b84c325a1a","unresolved":false,"context_lines":[{"line_number":157,"context_line":"# using affinity allows for finer control. In both the timing and"},{"line_number":158,"context_line":"# affinity cases, equally-sorting nodes are still randomly chosen to"},{"line_number":159,"context_line":"# spread load."},{"line_number":160,"context_line":"# Using concurrent, a request will be sent to all the primary nodes at the same"},{"line_number":161,"context_line":"# time and will use the storage node that responds first."},{"line_number":162,"context_line":"# The valid values for sorting_method are \"affinity\", \"shuffle\", \"timing\", or"},{"line_number":163,"context_line":"# \"concurrent\"."}],"source_content_type":"application/octet-stream","patch_set":12,"id":"5a890539_63ea8b75","line":160,"in_reply_to":"5a890539_21b6ed8a","updated":"2014-12-04 05:21:55.000000000","message":"Done","commit_id":"17409a3546ce46c51d65befbc1756eed746784d7"},{"author":{"_account_id":995,"name":"David Goetz","email":"david.goetz@rackspace.com","username":"david-goetz"},"change_message_id":"8d3f3fbdabf08aeb61c310cfd4da65a550ece3e2","unresolved":false,"context_lines":[{"line_number":166,"context_line":"#"},{"line_number":167,"context_line":"# You can choose the number of concurrent threads to use during a GET/HEAD."},{"line_number":168,"context_line":"# In the EC case, this parameter only effects an EC HEAD as an EC GET behaves"},{"line_number":169,"context_line":"# differently."},{"line_number":170,"context_line":"# max_concurrent_gets \u003d 1"},{"line_number":171,"context_line":"#"},{"line_number":172,"context_line":"# This parameter controls how long to wait before firing off the next"}],"source_content_type":"application/octet-stream","patch_set":21,"id":"7a2fa921_614a88c7","line":169,"updated":"2015-10-06 18:54:34.000000000","message":"so what if we made this:\nconcurrent_gets \u003d false\n\ni feel like this should eventually be default behavior and after this thing has been proved to be a big help we can default it to true. \n\nso when it is doing:\n\npile \u003d GreenAsyncPile(self.concurrency)\n\ninstead of self.concurrency it will be the # of primary nodes. \n\nI think that not only will that make the configs easier but for people with multiple storage policies a 5 copy ring can act differently that a 2 copy ring or a EC ring.","commit_id":"50cb0f75837c0ca148579a7d5ea26fc8f97686ca"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"0c2aa0c0da6fd9aa8b8dbdf1acba8f924e0c184d","unresolved":false,"context_lines":[{"line_number":166,"context_line":"#"},{"line_number":167,"context_line":"# You can choose the number of concurrent threads to use during a GET/HEAD."},{"line_number":168,"context_line":"# In the EC case, this parameter only effects an EC HEAD as an EC GET behaves"},{"line_number":169,"context_line":"# differently."},{"line_number":170,"context_line":"# max_concurrent_gets \u003d 1"},{"line_number":171,"context_line":"#"},{"line_number":172,"context_line":"# This parameter controls how long to wait before firing off the next"}],"source_content_type":"application/octet-stream","patch_set":21,"id":"7a2fa921_6f38f1ef","line":169,"in_reply_to":"7a2fa921_614a88c7","updated":"2015-10-08 01:30:29.000000000","message":"I used to work exactly that way.. can\u0027t remember why it changed. I remember thinking it was a good idea at the time, but maybe for some reason having it more configurable was good, but your right, it would make more sense to have it replica/n_data(for EC HEADs) concurrency so different policies get the effect. \n\nOr maybe it would be better per policy configuration and default it to replicas.","commit_id":"50cb0f75837c0ca148579a7d5ea26fc8f97686ca"},{"author":{"_account_id":995,"name":"David Goetz","email":"david.goetz@rackspace.com","username":"david-goetz"},"change_message_id":"8d3f3fbdabf08aeb61c310cfd4da65a550ece3e2","unresolved":false,"context_lines":[{"line_number":173,"context_line":"# concurrent_get thread. A value of 0 would we fully concurrent any other"},{"line_number":174,"context_line":"# number will stagger the firing of the threads. This number should be"},{"line_number":175,"context_line":"# between 0 and node_timeout. The default is node_timeout (10)."},{"line_number":176,"context_line":"# concurrency_timeout \u003d 10"},{"line_number":177,"context_line":"#"},{"line_number":178,"context_line":"# The maximum time (seconds) that a large object connection is allowed to last."},{"line_number":179,"context_line":"# max_large_object_get_time \u003d 86400"}],"source_content_type":"application/octet-stream","patch_set":21,"id":"7a2fa921_a1274011","line":176,"updated":"2015-10-06 18:54:34.000000000","message":"i think we should default this to conn_timeout","commit_id":"50cb0f75837c0ca148579a7d5ea26fc8f97686ca"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"0c2aa0c0da6fd9aa8b8dbdf1acba8f924e0c184d","unresolved":false,"context_lines":[{"line_number":173,"context_line":"# concurrent_get thread. A value of 0 would we fully concurrent any other"},{"line_number":174,"context_line":"# number will stagger the firing of the threads. This number should be"},{"line_number":175,"context_line":"# between 0 and node_timeout. The default is node_timeout (10)."},{"line_number":176,"context_line":"# concurrency_timeout \u003d 10"},{"line_number":177,"context_line":"#"},{"line_number":178,"context_line":"# The maximum time (seconds) that a large object connection is allowed to last."},{"line_number":179,"context_line":"# max_large_object_get_time \u003d 86400"}],"source_content_type":"application/octet-stream","patch_set":21,"id":"7a2fa921_cf0ee53a","line":176,"in_reply_to":"7a2fa921_a1274011","updated":"2015-10-08 01:30:29.000000000","message":"Right so the staggering can happen. Good idea, I just defaulted to current configuration.\n\nThis should also probably change to:\n\n  # concurreny_timeout \u003d\n\nAs if not concurrency_timeout then that\u0027s when it will default to conn_timeout.. so it isn\u0027t actually defaulted to a number.","commit_id":"50cb0f75837c0ca148579a7d5ea26fc8f97686ca"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"f4735207d9f1fe2ab0133587fb0dc61b2dc4438c","unresolved":false,"context_lines":[{"line_number":167,"context_line":"# You can choose the number of concurrent threads to use during a GET/HEAD."},{"line_number":168,"context_line":"# In the EC case, this parameter only effects an EC HEAD as an EC GET behaves"},{"line_number":169,"context_line":"# differently."},{"line_number":170,"context_line":"# max_concurrent_gets \u003d 1"},{"line_number":171,"context_line":"#"},{"line_number":172,"context_line":"# This parameter controls how long to wait before firing off the next"},{"line_number":173,"context_line":"# concurrent_get thread. A value of 0 would we fully concurrent any other"}],"source_content_type":"application/octet-stream","patch_set":22,"id":"ba8a016a_10488e2c","line":170,"updated":"2015-11-18 05:07:26.000000000","message":"As a follow up question based of David\u0027s comments in the last patchset:\n\nWould it be too confusing to something in between. Like possible versions could be:\n\n false/off \u003d\u003d concurrency of 1.\n true/on \u003d\u003d concurrency of replica count (or ndata for EC HEAD)\n # \u003d\u003d concurrency number override.\n\nAlthough a ternary switch like that might be a little confusing for ops.","commit_id":"5a26314ff92d57b86470ee9a4410307131bc5f72"},{"author":{"_account_id":995,"name":"David Goetz","email":"david.goetz@rackspace.com","username":"david-goetz"},"change_message_id":"fc138a531c8edb7e9f40a46267a6ee0d57867098","unresolved":false,"context_lines":[{"line_number":167,"context_line":"# You can choose the number of concurrent threads to use during a GET/HEAD."},{"line_number":168,"context_line":"# In the EC case, this parameter only effects an EC HEAD as an EC GET behaves"},{"line_number":169,"context_line":"# differently."},{"line_number":170,"context_line":"# max_concurrent_gets \u003d 1"},{"line_number":171,"context_line":"#"},{"line_number":172,"context_line":"# This parameter controls how long to wait before firing off the next"},{"line_number":173,"context_line":"# concurrent_get thread. A value of 0 would we fully concurrent any other"}],"source_content_type":"application/octet-stream","patch_set":22,"id":"ba8a016a_72dbfbec","line":170,"in_reply_to":"ba8a016a_10488e2c","updated":"2015-11-18 17:42:46.000000000","message":"ok- i am going to look at this review again :) sorry for the delay. I still do like the\n\nconcurrent_gets \u003d true/false\n\nidea. Would anybody ever not set this to the replica count? since they are staggered with the timeout i can\u0027t think of a reason why you would want to. just having true/false would be simpler, more flexible, and would allow us to just have this turned on by default later on with less complication.\n\nI\u0027d say unless somebody comes up with a good example for setting it to a number then we should just leave it to true/false.","commit_id":"5a26314ff92d57b86470ee9a4410307131bc5f72"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"2c56d1dae3ee93048caf77791a0d87a70728dc79","unresolved":false,"context_lines":[{"line_number":167,"context_line":"# You can choose the number of concurrent threads to use during a GET/HEAD."},{"line_number":168,"context_line":"# In the EC case, this parameter only effects an EC HEAD as an EC GET behaves"},{"line_number":169,"context_line":"# differently."},{"line_number":170,"context_line":"# max_concurrent_gets \u003d 1"},{"line_number":171,"context_line":"#"},{"line_number":172,"context_line":"# This parameter controls how long to wait before firing off the next"},{"line_number":173,"context_line":"# concurrent_get thread. A value of 0 would we fully concurrent any other"}],"source_content_type":"application/octet-stream","patch_set":22,"id":"ba8a016a_c0115f53","line":170,"in_reply_to":"ba8a016a_25d63d28","updated":"2015-11-20 00:55:18.000000000","message":"I don\u0027t recall the specifics - but yeah someone thought tying it to replica-count was arbitrary.\n\nmulti-region maybe?\n\nis there much of a difference in two and three?  do you really ever want sixteen?","commit_id":"5a26314ff92d57b86470ee9a4410307131bc5f72"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"68648bb6366b6b9e31fa4633efbb2151b36cd6dc","unresolved":false,"context_lines":[{"line_number":167,"context_line":"# You can choose the number of concurrent threads to use during a GET/HEAD."},{"line_number":168,"context_line":"# In the EC case, this parameter only effects an EC HEAD as an EC GET behaves"},{"line_number":169,"context_line":"# differently."},{"line_number":170,"context_line":"# max_concurrent_gets \u003d 1"},{"line_number":171,"context_line":"#"},{"line_number":172,"context_line":"# This parameter controls how long to wait before firing off the next"},{"line_number":173,"context_line":"# concurrent_get thread. A value of 0 would we fully concurrent any other"}],"source_content_type":"application/octet-stream","patch_set":22,"id":"ba8a016a_25d63d28","line":170,"in_reply_to":"ba8a016a_72dbfbec","updated":"2015-11-20 00:36:12.000000000","message":"I like your reasoning, let me change it to true/false, and wait for someone to complain :P","commit_id":"5a26314ff92d57b86470ee9a4410307131bc5f72"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"f4735207d9f1fe2ab0133587fb0dc61b2dc4438c","unresolved":false,"context_lines":[{"line_number":172,"context_line":"# This parameter controls how long to wait before firing off the next"},{"line_number":173,"context_line":"# concurrent_get thread. A value of 0 would we fully concurrent any other"},{"line_number":174,"context_line":"# number will stagger the firing of the threads. This number should be"},{"line_number":175,"context_line":"# between 0 and node_timeout. The default is node_timeout (10)."},{"line_number":176,"context_line":"# concurrency_timeout \u003d 10"},{"line_number":177,"context_line":"#"},{"line_number":178,"context_line":"# The maximum time (seconds) that a large object connection is allowed to last."}],"source_content_type":"application/octet-stream","patch_set":22,"id":"ba8a016a_f0faaabc","line":175,"updated":"2015-11-18 05:07:26.000000000","message":"Will change this to default to conn_timeout (0.5 by default). So staggering will be on by default.","commit_id":"5a26314ff92d57b86470ee9a4410307131bc5f72"},{"author":{"_account_id":330,"name":"John Dickinson","email":"me@not.mn","username":"notmyname"},"change_message_id":"85f64230eca280c0c2c7907fffa80c6383caaf9e","unresolved":false,"context_lines":[{"line_number":176,"context_line":"# turn on concurrent_gets below, then replica count threads will be used."},{"line_number":177,"context_line":"# With addition of the concurrency_timeout option this will allow swift to send"},{"line_number":178,"context_line":"# out GET/HEAD requests to the storage nodes concurrently and answer with the"},{"line_number":179,"context_line":"# first to respond. As EC behaves differently this parameter only effects an"},{"line_number":180,"context_line":"# EC HEAD."},{"line_number":181,"context_line":"# concurrent_gets \u003d off"},{"line_number":182,"context_line":"#"}],"source_content_type":"application/octet-stream","patch_set":25,"id":"bae84128_cea42159","line":179,"updated":"2016-02-25 19:46:48.000000000","message":"nit: affects","commit_id":"bd67c1959fddd278ec9bae2752a59a8cdc42a5ff"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"0d6334ff57f4144b6960af9490de450863590996","unresolved":false,"context_lines":[{"line_number":176,"context_line":"# turn on concurrent_gets below, then replica count threads will be used."},{"line_number":177,"context_line":"# With addition of the concurrency_timeout option this will allow swift to send"},{"line_number":178,"context_line":"# out GET/HEAD requests to the storage nodes concurrently and answer with the"},{"line_number":179,"context_line":"# first to respond. As EC behaves differently this parameter only effects an"},{"line_number":180,"context_line":"# EC HEAD."},{"line_number":181,"context_line":"# concurrent_gets \u003d off"},{"line_number":182,"context_line":"#"}],"source_content_type":"application/octet-stream","patch_set":25,"id":"9aed3d3a_daaa3719","line":179,"in_reply_to":"bae84128_cea42159","updated":"2016-02-25 22:44:31.000000000","message":"Thanks, will fix.","commit_id":"bd67c1959fddd278ec9bae2752a59a8cdc42a5ff"},{"author":{"_account_id":330,"name":"John Dickinson","email":"me@not.mn","username":"notmyname"},"change_message_id":"85f64230eca280c0c2c7907fffa80c6383caaf9e","unresolved":false,"context_lines":[{"line_number":184,"context_line":"# concurrent_get thread. A value of 0 would we fully concurrent, any other"},{"line_number":185,"context_line":"# number will stagger the firing of the threads. This number should be"},{"line_number":186,"context_line":"# between 0 and node_timeout. The default is the conn_timeout (0.5)."},{"line_number":187,"context_line":"# concurrency_timeout \u003d"},{"line_number":188,"context_line":"#"},{"line_number":189,"context_line":"# Set to the number of nodes to contact for a normal request. You can use"},{"line_number":190,"context_line":"# \u0027* replicas\u0027 at the end to have it use the number given times the number of"}],"source_content_type":"application/octet-stream","patch_set":25,"id":"bae84128_515390e1","line":187,"updated":"2016-02-25 19:46:48.000000000","message":"why didn\u0027t you add the default here?","commit_id":"bd67c1959fddd278ec9bae2752a59a8cdc42a5ff"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"0d6334ff57f4144b6960af9490de450863590996","unresolved":false,"context_lines":[{"line_number":184,"context_line":"# concurrent_get thread. A value of 0 would we fully concurrent, any other"},{"line_number":185,"context_line":"# number will stagger the firing of the threads. This number should be"},{"line_number":186,"context_line":"# between 0 and node_timeout. The default is the conn_timeout (0.5)."},{"line_number":187,"context_line":"# concurrency_timeout \u003d"},{"line_number":188,"context_line":"#"},{"line_number":189,"context_line":"# Set to the number of nodes to contact for a normal request. You can use"},{"line_number":190,"context_line":"# \u0027* replicas\u0027 at the end to have it use the number given times the number of"}],"source_content_type":"application/octet-stream","patch_set":25,"id":"9aed3d3a_3aec03c7","line":187,"in_reply_to":"bae84128_515390e1","updated":"2016-02-25 22:44:31.000000000","message":"Yeah good question\n\nI know we like the have whatever the default value is here, so by uncommenting it shouldn\u0027t change anything on the running system, however in this case the default is whatever the conn_timeout is, which by default is 0.5, but doesn\u0027t actually mean it\u0027s 0.5.\n\nAlthough yeah, I\u0027m happy to just set the default to 0.5 in the commented out setting I guess.","commit_id":"bd67c1959fddd278ec9bae2752a59a8cdc42a5ff"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d70f43c16de45b9f03d461614f6db091fd109319","unresolved":false,"context_lines":[{"line_number":177,"context_line":"# With addition of the concurrency_timeout option this will allow swift to send"},{"line_number":178,"context_line":"# out GET/HEAD requests to the storage nodes concurrently and answer with the"},{"line_number":179,"context_line":"# first to respond. As EC behaves differently this parameter only affects an"},{"line_number":180,"context_line":"# EC HEAD."},{"line_number":181,"context_line":"# concurrent_gets \u003d off"},{"line_number":182,"context_line":"#"},{"line_number":183,"context_line":"# This parameter controls how long to wait before firing off the next"}],"source_content_type":"application/octet-stream","patch_set":26,"id":"5aef4532_7638f13d","line":180,"updated":"2016-03-09 16:09:31.000000000","message":"nit: last sentence could be confusing\n\n  \"With an EC policy the parameter only affects HEAD requests.\"","commit_id":"4d6d54f228001cd835e3abf6d8fca82d1fae562d"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"c25fb967237a2b9740687f5c73dd45a902ce23ae","unresolved":false,"context_lines":[{"line_number":177,"context_line":"# With addition of the concurrency_timeout option this will allow swift to send"},{"line_number":178,"context_line":"# out GET/HEAD requests to the storage nodes concurrently and answer with the"},{"line_number":179,"context_line":"# first to respond. As EC behaves differently this parameter only affects an"},{"line_number":180,"context_line":"# EC HEAD."},{"line_number":181,"context_line":"# concurrent_gets \u003d off"},{"line_number":182,"context_line":"#"},{"line_number":183,"context_line":"# This parameter controls how long to wait before firing off the next"}],"source_content_type":"application/octet-stream","patch_set":26,"id":"3afc51ec_0ac06e7a","line":180,"in_reply_to":"5aef4532_7638f13d","updated":"2016-03-15 02:15:34.000000000","message":"Done","commit_id":"4d6d54f228001cd835e3abf6d8fca82d1fae562d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d70f43c16de45b9f03d461614f6db091fd109319","unresolved":false,"context_lines":[{"line_number":181,"context_line":"# concurrent_gets \u003d off"},{"line_number":182,"context_line":"#"},{"line_number":183,"context_line":"# This parameter controls how long to wait before firing off the next"},{"line_number":184,"context_line":"# concurrent_get thread. A value of 0 would we fully concurrent, any other"},{"line_number":185,"context_line":"# number will stagger the firing of the threads. This number should be"},{"line_number":186,"context_line":"# between 0 and node_timeout. The default is what ever you set for the"},{"line_number":187,"context_line":"# conn_timeout parameter."}],"source_content_type":"application/octet-stream","patch_set":26,"id":"5aef4532_161fedb7","line":184,"updated":"2016-03-09 16:09:31.000000000","message":"s/we/be","commit_id":"4d6d54f228001cd835e3abf6d8fca82d1fae562d"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"c25fb967237a2b9740687f5c73dd45a902ce23ae","unresolved":false,"context_lines":[{"line_number":181,"context_line":"# concurrent_gets \u003d off"},{"line_number":182,"context_line":"#"},{"line_number":183,"context_line":"# This parameter controls how long to wait before firing off the next"},{"line_number":184,"context_line":"# concurrent_get thread. A value of 0 would we fully concurrent, any other"},{"line_number":185,"context_line":"# number will stagger the firing of the threads. This number should be"},{"line_number":186,"context_line":"# between 0 and node_timeout. The default is what ever you set for the"},{"line_number":187,"context_line":"# conn_timeout parameter."}],"source_content_type":"application/octet-stream","patch_set":26,"id":"3afc51ec_4a38b6a0","line":184,"in_reply_to":"5aef4532_161fedb7","updated":"2016-03-15 02:15:34.000000000","message":"Done","commit_id":"4d6d54f228001cd835e3abf6d8fca82d1fae562d"}],"swift/common/utils.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"9894ccaf3940dee65d9bed31a117453965b9baf9","unresolved":false,"context_lines":[{"line_number":2088,"context_line":""},{"line_number":2089,"context_line":"    @property"},{"line_number":2090,"context_line":"    def inflight(self):"},{"line_number":2091,"context_line":"        return self._inflight"},{"line_number":2092,"context_line":""},{"line_number":2093,"context_line":"    def spawn(self, func, *args, **kwargs):"},{"line_number":2094,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":13,"id":"5a890539_c22cdd04","line":2091,"updated":"2014-12-04 06:46:27.000000000","message":"yeah that\u0027s fine i guess","commit_id":"725c8019030d53c904955d6f1548b53a86829050"}],"swift/proxy/controllers/base.py":[{"author":{"_account_id":5189,"name":"Yuan Zhou","email":"dunk007@gmail.com","username":"yuan-zhou"},"change_message_id":"4f292dc4dae143f1dd839dcba5594a747e75dedf","unresolved":false,"context_lines":[{"line_number":838,"context_line":""},{"line_number":839,"context_line":"        if pile:"},{"line_number":840,"context_line":"            for _junk in pile:"},{"line_number":841,"context_line":"                if self.sources:"},{"line_number":842,"context_line":"                    break"},{"line_number":843,"context_line":"                else:"},{"line_number":844,"context_line":"                    continue"}],"source_content_type":"text/x-python","patch_set":5,"id":"fa98f980_afbe55fd","line":841,"updated":"2014-09-10 08:57:50.000000000","message":"in normal case one response is enough but if self.newest is set as true, we should collect all the 3 response here and let below sort code pick up the newest one.","commit_id":"f1b52b732221b5c58ff613b286c4a152f93aea16"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"c5b993f958e95d988a83ec4235c755f5b8a9b15c","unresolved":false,"context_lines":[{"line_number":838,"context_line":""},{"line_number":839,"context_line":"        if pile:"},{"line_number":840,"context_line":"            for _junk in pile:"},{"line_number":841,"context_line":"                if self.sources:"},{"line_number":842,"context_line":"                    break"},{"line_number":843,"context_line":"                else:"},{"line_number":844,"context_line":"                    continue"}],"source_content_type":"text/x-python","patch_set":5,"id":"fa98f980_88e16b2c","line":841,"in_reply_to":"fa98f980_afbe55fd","updated":"2014-09-11 02:12:49.000000000","message":"Nice spot! \n\nI\u0027m now letting the loop end if newest is set (because of timeout or because all the threads have returned).","commit_id":"f1b52b732221b5c58ff613b286c4a152f93aea16"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"e65e55003164e7f4d81a56e8e21fe428a07ebf79","unresolved":false,"context_lines":[{"line_number":745,"context_line":"            if getattr(source, \u0027swift_conn\u0027, None):"},{"line_number":746,"context_line":"                close_swift_conn(source)"},{"line_number":747,"context_line":""},{"line_number":748,"context_line":"    def _make_node_request(self, node, node_timeout):"},{"line_number":749,"context_line":"        if node in self.used_nodes:"},{"line_number":750,"context_line":"            return False"},{"line_number":751,"context_line":"        start_node_timing \u003d time.time()"}],"source_content_type":"text/x-python","patch_set":12,"id":"5a890539_981b9d1b","line":748,"updated":"2014-11-21 01:08:36.000000000","message":"this is a good clean method extraction - nice work, much cleaner","commit_id":"17409a3546ce46c51d65befbc1756eed746784d7"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"e65e55003164e7f4d81a56e8e21fe428a07ebf79","unresolved":false,"context_lines":[{"line_number":829,"context_line":""},{"line_number":830,"context_line":"        concurrent_reads \u003d self.app.concurrent_reads"},{"line_number":831,"context_line":"        pile \u003d GreenAsyncPile(len(start_nodes))"},{"line_number":832,"context_line":"        wait_timeout \u003d 0 if concurrent_reads else node_timeout"},{"line_number":833,"context_line":""},{"line_number":834,"context_line":"        for node in nodes:"},{"line_number":835,"context_line":"            pile.spawn(self._make_node_request, node, node_timeout)"}],"source_content_type":"text/x-python","patch_set":12,"id":"5a890539_9e6d459c","line":832,"updated":"2014-11-21 01:08:36.000000000","message":"this is *super* versatile - I think @redbo was really onto something here\n\nIn fact I experimented with different wait_timeouts and I think there\u0027s a lot of value to be had with a wait_timeout that\u0027s even as long as say - half your node_timeout.  Where there\u0027s this sliding value tradeoff from how flat your long tail requests are and how many nodes are wasting their time on requests that will never be served.\n\nSo much to the point that I think it should be tunable separately.","commit_id":"17409a3546ce46c51d65befbc1756eed746784d7"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0f2a7eb45ba75757553119fc6748319c03170413","unresolved":false,"context_lines":[{"line_number":829,"context_line":""},{"line_number":830,"context_line":"        concurrent_reads \u003d self.app.concurrent_reads"},{"line_number":831,"context_line":"        pile \u003d GreenAsyncPile(len(start_nodes))"},{"line_number":832,"context_line":"        wait_timeout \u003d 0 if concurrent_reads else node_timeout"},{"line_number":833,"context_line":""},{"line_number":834,"context_line":"        for node in nodes:"},{"line_number":835,"context_line":"            pile.spawn(self._make_node_request, node, node_timeout)"}],"source_content_type":"text/x-python","patch_set":12,"id":"5a890539_fd0b9721","line":832,"in_reply_to":"5a890539_9e6d459c","updated":"2014-11-21 17:37:12.000000000","message":"@Clay - so could be a single config option \u0027concurrency_timeout \u003d 0 \u003c val \u003c node_timeout\u0027?\n\n@Anyone Question: if wait_timeout \u003d\u003d node_timeout i.e. non-concurrent, then might the wait_timeout on the pile.waitall() on next line pop before the node_timeout on the _make_node_request thread? In which case there is a risk of spawning another make_node_request before the first has had time to succeed.\n\n(I\u0027m not super familiar with eventlet timeout handling - maybe it somehow prevents this).\n\nAlso, I\u0027m wondering if it would make sense to always go with wait_timeout \u003d 0 if self.newest? If I understand current behavior, then self.newest causes requests to go to all nodes eventually.","commit_id":"17409a3546ce46c51d65befbc1756eed746784d7"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"e65e55003164e7f4d81a56e8e21fe428a07ebf79","unresolved":false,"context_lines":[{"line_number":833,"context_line":""},{"line_number":834,"context_line":"        for node in nodes:"},{"line_number":835,"context_line":"            pile.spawn(self._make_node_request, node, node_timeout)"},{"line_number":836,"context_line":"            results \u003d pile.waitall(wait_timeout)"},{"line_number":837,"context_line":"            if True in results:"},{"line_number":838,"context_line":"                break"},{"line_number":839,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"5a890539_de9a6d6d","line":836,"updated":"2014-11-21 01:08:36.000000000","message":"so when I tested this functionally I got a lot more 404\u0027s on the backend than I expected.  What seemed to be going on is that the pile will block on the spawn first spawn call \u003e size (len(start_nodes)) - but only until a request pops out - once it does the next blocked spawn drops right down in the queue (most of time to the first handoff) so we\u0027re kicking off one extra 404 request for every GET when you would sort of expect that we make 3 requests and then give them up to node_timeout to respond.\n\nThe fix maybe as simple as changing wait_timeout to node_timeout after you\u0027ve put in last primary node?","commit_id":"17409a3546ce46c51d65befbc1756eed746784d7"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"785b9d6cfb77076f892a0813a488d3c520deadf4","unresolved":false,"context_lines":[{"line_number":833,"context_line":""},{"line_number":834,"context_line":"        for node in nodes:"},{"line_number":835,"context_line":"            pile.spawn(self._make_node_request, node, node_timeout)"},{"line_number":836,"context_line":"            results \u003d pile.waitall(wait_timeout)"},{"line_number":837,"context_line":"            if True in results:"},{"line_number":838,"context_line":"                break"},{"line_number":839,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"5a890539_6bf0cbc9","line":836,"in_reply_to":"5a890539_de9a6d6d","updated":"2014-12-02 06:22:34.000000000","message":"So far I am testing with something like:\n\n  for node in nodes:\n      pile.spawn(self._make_node_request, node, node_timeout)\n          _timeout \u003d wait_timeout if pile.inflight \u003c\u003d len(start_nodes) \\\n              else node_timeout\n      results \u003d pile.waitall(_timeout)\n      if True in results:\n            break\n\nNOTE: I seperated into a _timeout variable for debugging :)\n\nWhere I have added a property to GreenAsyncPile:\n\n    @property\n    def inflight(self):\n        return self._inflight\n\nSo once the max run queue is full len(start_nodes) the timeout becomes node timeout.\n\nI can add a diff with what I have so far.. but wont post a new patchset until I have addressed all comments.","commit_id":"17409a3546ce46c51d65befbc1756eed746784d7"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0f2a7eb45ba75757553119fc6748319c03170413","unresolved":false,"context_lines":[{"line_number":839,"context_line":""},{"line_number":840,"context_line":"        # Wait for all the green threads to finish/timeout."},{"line_number":841,"context_line":"        for _junk in pile:"},{"line_number":842,"context_line":"            if not self.newest and self.sources:"},{"line_number":843,"context_line":"                break"},{"line_number":844,"context_line":""},{"line_number":845,"context_line":"        if self.sources:"}],"source_content_type":"text/x-python","patch_set":12,"id":"5a890539_0adbb8ed","line":842,"updated":"2014-11-21 17:37:12.000000000","message":"Could this be :\n\n if _junk:\n     break\n\nsince _make_node_request is already testing self.newest?","commit_id":"17409a3546ce46c51d65befbc1756eed746784d7"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"785b9d6cfb77076f892a0813a488d3c520deadf4","unresolved":false,"context_lines":[{"line_number":839,"context_line":""},{"line_number":840,"context_line":"        # Wait for all the green threads to finish/timeout."},{"line_number":841,"context_line":"        for _junk in pile:"},{"line_number":842,"context_line":"            if not self.newest and self.sources:"},{"line_number":843,"context_line":"                break"},{"line_number":844,"context_line":""},{"line_number":845,"context_line":"        if self.sources:"}],"source_content_type":"text/x-python","patch_set":12,"id":"5a890539_cbbc5fde","line":842,"in_reply_to":"5a890539_0adbb8ed","updated":"2014-12-02 06:22:34.000000000","message":"Hmm, yeah.. you might be right there :)","commit_id":"17409a3546ce46c51d65befbc1756eed746784d7"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"e65e55003164e7f4d81a56e8e21fe428a07ebf79","unresolved":false,"context_lines":[{"line_number":840,"context_line":"        # Wait for all the green threads to finish/timeout."},{"line_number":841,"context_line":"        for _junk in pile:"},{"line_number":842,"context_line":"            if not self.newest and self.sources:"},{"line_number":843,"context_line":"                break"},{"line_number":844,"context_line":""},{"line_number":845,"context_line":"        if self.sources:"},{"line_number":846,"context_line":"            self.sources.sort(key\u003dlambda s: source_key(s[0]))"}],"source_content_type":"text/x-python","patch_set":12,"id":"5a890539_be1a0115","line":843,"updated":"2014-11-21 01:08:36.000000000","message":"I\u0027d like to see this comment expanded, because I\u0027m not entirely sure what this code is trying to achieve.  I will point out that once a response/job/coro gets popped from the AsyncPile queue via waitall it is *not* returned as part of iteration - so this particular iteration ends up waiting on the *next* response after you\u0027re sort of already selected the first responder.  It doesn\u0027t have any functional impact in the non-concurrent node_sort option since you generally didn\u0027t spawn the second request before you broke out of the fill loop - but in the concurrent read case it *can* be devastating!","commit_id":"17409a3546ce46c51d65befbc1756eed746784d7"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"785b9d6cfb77076f892a0813a488d3c520deadf4","unresolved":false,"context_lines":[{"line_number":840,"context_line":"        # Wait for all the green threads to finish/timeout."},{"line_number":841,"context_line":"        for _junk in pile:"},{"line_number":842,"context_line":"            if not self.newest and self.sources:"},{"line_number":843,"context_line":"                break"},{"line_number":844,"context_line":""},{"line_number":845,"context_line":"        if self.sources:"},{"line_number":846,"context_line":"            self.sources.sort(key\u003dlambda s: source_key(s[0]))"}],"source_content_type":"text/x-python","patch_set":12,"id":"5a890539_ebb3db07","line":843,"in_reply_to":"5a890539_05772bd5","updated":"2014-12-02 06:22:34.000000000","message":"Thanks Alistair, that looks much neater :)","commit_id":"17409a3546ce46c51d65befbc1756eed746784d7"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0f2a7eb45ba75757553119fc6748319c03170413","unresolved":false,"context_lines":[{"line_number":840,"context_line":"        # Wait for all the green threads to finish/timeout."},{"line_number":841,"context_line":"        for _junk in pile:"},{"line_number":842,"context_line":"            if not self.newest and self.sources:"},{"line_number":843,"context_line":"                break"},{"line_number":844,"context_line":""},{"line_number":845,"context_line":"        if self.sources:"},{"line_number":846,"context_line":"            self.sources.sort(key\u003dlambda s: source_key(s[0]))"}],"source_content_type":"text/x-python","patch_set":12,"id":"5a890539_05772bd5","line":843,"in_reply_to":"5a890539_be1a0115","updated":"2014-11-21 17:37:12.000000000","message":"So do lines 840 - 843 need to be conditional on not already having a good source? e.g.\n\n    if not any(results):\n        # Wait for sufficient good sources.\n        for result in pile:\n            if result:\n                break","commit_id":"17409a3546ce46c51d65befbc1756eed746784d7"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"9894ccaf3940dee65d9bed31a117453965b9baf9","unresolved":false,"context_lines":[{"line_number":837,"context_line":"        for node in nodes:"},{"line_number":838,"context_line":"            pile.spawn(self._make_node_request, node, node_timeout)"},{"line_number":839,"context_line":"            _timeout \u003d wait_timeout if pile.inflight \u003c\u003d len(start_nodes) \\"},{"line_number":840,"context_line":"                else node_timeout"},{"line_number":841,"context_line":"            results \u003d pile.waitall(_timeout)"},{"line_number":842,"context_line":"            if True in results:"},{"line_number":843,"context_line":"                break"}],"source_content_type":"text/x-python","patch_set":13,"id":"5a890539_62cde95c","line":840,"updated":"2014-12-04 06:46:27.000000000","message":"@acoles - any ideas here?  feels like if ! concurrent_reads this is \"node_timeout if True else node_timeout\" or something?\n\nanyway I think that\u0027s right, i\u0027ll test it.","commit_id":"725c8019030d53c904955d6f1548b53a86829050"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"2c68ae0b77564f5f94f6fc3ab79d445916d388a2","unresolved":false,"context_lines":[{"line_number":837,"context_line":"        for node in nodes:"},{"line_number":838,"context_line":"            pile.spawn(self._make_node_request, node, node_timeout)"},{"line_number":839,"context_line":"            _timeout \u003d wait_timeout if pile.inflight \u003c\u003d len(start_nodes) \\"},{"line_number":840,"context_line":"                else node_timeout"},{"line_number":841,"context_line":"            results \u003d pile.waitall(_timeout)"},{"line_number":842,"context_line":"            if True in results:"},{"line_number":843,"context_line":"                break"}],"source_content_type":"text/x-python","patch_set":13,"id":"5a890539_7afe4e6b","line":840,"in_reply_to":"5a890539_62cde95c","updated":"2014-12-05 02:03:58.000000000","message":"Lol, yeah this has become a bit ugly now.. we could:\n\n  if concurrent_reads:\n      _timeout \u003d concurrency_timeout if pile.inflight \u003c\u003d len(start_nodes) \\\n          else node_timeout\n  else:\n      _timeout \u003d node_timeout\n\nThen we can remove the wait_timeout altogether. That is probably easier to read as well.","commit_id":"725c8019030d53c904955d6f1548b53a86829050"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"9894ccaf3940dee65d9bed31a117453965b9baf9","unresolved":false,"context_lines":[{"line_number":846,"context_line":"            # Wait for sufficient good sources."},{"line_number":847,"context_line":"            for result in pile:"},{"line_number":848,"context_line":"                if result:"},{"line_number":849,"context_line":"                    break"},{"line_number":850,"context_line":""},{"line_number":851,"context_line":"        if self.sources:"},{"line_number":852,"context_line":"            self.sources.sort(key\u003dlambda s: source_key(s[0]))"}],"source_content_type":"text/x-python","patch_set":13,"id":"5a890539_82aad56e","line":849,"updated":"2014-12-04 06:46:27.000000000","message":"much better (that acoles is pretty darn good huh...)","commit_id":"725c8019030d53c904955d6f1548b53a86829050"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"e9bf737b2fa928a0492110f465bc75bae88af49b","unresolved":false,"context_lines":[{"line_number":839,"context_line":"                    if pile.inflight \u003c\u003d len(start_nodes) else node_timeout"},{"line_number":840,"context_line":"            else:"},{"line_number":841,"context_line":"                _timeout \u003d node_timeout"},{"line_number":842,"context_line":"            results \u003d pile.waitall(_timeout)"},{"line_number":843,"context_line":"            if True in results:"},{"line_number":844,"context_line":"                break"},{"line_number":845,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"da86d52c_96bc2d08","line":842,"updated":"2015-02-04 05:28:20.000000000","message":"It\u0027s been a while since I looked at this, I now need to re-familarise myself with it.. I\u0027ll go double check, but nice spot Yuan.","commit_id":"41edac50bc1bb7c3b0b04506502a582f0863ecf7"},{"author":{"_account_id":5189,"name":"Yuan Zhou","email":"dunk007@gmail.com","username":"yuan-zhou"},"change_message_id":"a9fe190ab6f4a0618069acf4282973231f4af3a4","unresolved":false,"context_lines":[{"line_number":839,"context_line":"                    if pile.inflight \u003c\u003d len(start_nodes) else node_timeout"},{"line_number":840,"context_line":"            else:"},{"line_number":841,"context_line":"                _timeout \u003d node_timeout"},{"line_number":842,"context_line":"            results \u003d pile.waitall(_timeout)"},{"line_number":843,"context_line":"            if True in results:"},{"line_number":844,"context_line":"                break"},{"line_number":845,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"3a961159_2902d6b3","line":842,"updated":"2014-12-15 08:50:48.000000000","message":"Matthew, is this line trying to collect the return value? looks like it should  be:\n\nresults.append(pile.waitall(_timeout)[0])\n\notherwise the results will be [[True]] and the below break won\u0027t work","commit_id":"41edac50bc1bb7c3b0b04506502a582f0863ecf7"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"21f2521a2da0f03af8b7a1eed212e60153102b70","unresolved":false,"context_lines":[{"line_number":839,"context_line":"                    if pile.inflight \u003c\u003d len(start_nodes) else node_timeout"},{"line_number":840,"context_line":"            else:"},{"line_number":841,"context_line":"                _timeout \u003d node_timeout"},{"line_number":842,"context_line":"            results \u003d pile.waitall(_timeout)"},{"line_number":843,"context_line":"            if True in results:"},{"line_number":844,"context_line":"                break"},{"line_number":845,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"da86d52c_f001e805","line":842,"in_reply_to":"3a961159_2902d6b3","updated":"2015-02-04 10:32:16.000000000","message":"Just did some debugging of the code, and the waitall method returns a list of results (return status\u0027 of the threads that have returned), the method we run only returns a single True or False response.\nIn debugging waitall returns a list boolean values, so something like:\n\n  [True]\n\nWhen I hack it to have to wait for all responses I get:\n\n  [True, True, True]\n\nNot [[True]] or [[True], [True]]\n\nIts not just getting the return value, it\u0027s seeing if we get a valid source quickly. If it fails to get a response or a False, then swift needs to wait for all responses (false is due to the x-newest feature) it will then go through all return codes and find the right source. So this is where we choose the first good source to return.","commit_id":"41edac50bc1bb7c3b0b04506502a582f0863ecf7"},{"author":{"_account_id":7479,"name":"paul luse","email":"paul.e.luse@intel.com","username":"peluse"},"change_message_id":"420e336d25dea909748e53cdd8fd6b94ffb9d3cd","unresolved":false,"context_lines":[{"line_number":839,"context_line":"                    if pile.inflight \u003c\u003d len(start_nodes) else node_timeout"},{"line_number":840,"context_line":"            else:"},{"line_number":841,"context_line":"                _timeout \u003d node_timeout"},{"line_number":842,"context_line":"            results \u003d pile.waitall(_timeout)"},{"line_number":843,"context_line":"            if True in results:"},{"line_number":844,"context_line":"                break"},{"line_number":845,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"3a961159_92703c75","line":842,"in_reply_to":"3a961159_2902d6b3","updated":"2014-12-15 17:33:25.000000000","message":"wow, go Yuan!  If that is indeed the case Mathew (I\u0027m sure you would already) but you should check for a possible hole in your corresponding unit tests when you address this","commit_id":"41edac50bc1bb7c3b0b04506502a582f0863ecf7"},{"author":{"_account_id":13777,"name":"Nicolas Trangez","email":"ikke@nicolast.be","username":"nicolast"},"change_message_id":"c22c17678387a1adcf3feb1d51dd8afe3f399275","unresolved":false,"context_lines":[{"line_number":852,"context_line":"        if self.sources:"},{"line_number":853,"context_line":"            self.sources.sort(key\u003dlambda s: source_key(s[0]))"},{"line_number":854,"context_line":"            source, node \u003d self.sources.pop()"},{"line_number":855,"context_line":"            for src, _junk in self.sources:"},{"line_number":856,"context_line":"                close_swift_conn(src)"},{"line_number":857,"context_line":"            self.used_nodes.append(node)"},{"line_number":858,"context_line":"            src_headers \u003d dict("}],"source_content_type":"text/x-python","patch_set":14,"id":"3a961159_3b5f63e6","line":855,"updated":"2015-01-19 12:36:00.000000000","message":"Instead of calling this `_junk`, consider giving it a more descriptive name of what the value actually represents (`_node`?), or simply `_`?","commit_id":"41edac50bc1bb7c3b0b04506502a582f0863ecf7"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"e9bf737b2fa928a0492110f465bc75bae88af49b","unresolved":false,"context_lines":[{"line_number":852,"context_line":"        if self.sources:"},{"line_number":853,"context_line":"            self.sources.sort(key\u003dlambda s: source_key(s[0]))"},{"line_number":854,"context_line":"            source, node \u003d self.sources.pop()"},{"line_number":855,"context_line":"            for src, _junk in self.sources:"},{"line_number":856,"context_line":"                close_swift_conn(src)"},{"line_number":857,"context_line":"            self.used_nodes.append(node)"},{"line_number":858,"context_line":"            src_headers \u003d dict("}],"source_content_type":"text/x-python","patch_set":14,"id":"da86d52c_b6b93117","line":855,"updated":"2015-02-04 05:28:20.000000000","message":"It\u0027s called _junk, to indicate that it is a variable that isn\u0027t used. and _ is usually imported for gettext so don\u0027t want to get it confused.","commit_id":"41edac50bc1bb7c3b0b04506502a582f0863ecf7"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"fb3b786e66a1369a0cff70b902d4d7c2182a10be","unresolved":false,"context_lines":[{"line_number":961,"context_line":"        else:"},{"line_number":962,"context_line":"            return None"},{"line_number":963,"context_line":""},{"line_number":964,"context_line":"    def _make_node_request(self, node, node_timeout):"},{"line_number":965,"context_line":"        if node in self.used_nodes:"},{"line_number":966,"context_line":"            return False"},{"line_number":967,"context_line":"        start_node_timing \u003d time.time()"}],"source_content_type":"text/x-python","patch_set":17,"id":"1a4dcd0f_596c4708","line":964,"updated":"2015-08-10 01:17:22.000000000","message":"this is a clean extraction, in an ideal world it would probably be done in a pre-req patch to simplify this diff.  Honestly if this method extraction was pulled out of the diff the line-change/test-change ratio wouldn\u0027t look nearly so awkward.\n\nMethod needs a doc string.  Words about the return value would be particularly useful.","commit_id":"0e7d36ef399b4b830af85dc10a804d0f5cd70431"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"fb3b786e66a1369a0cff70b902d4d7c2182a10be","unresolved":false,"context_lines":[{"line_number":1044,"context_line":"            node_timeout \u003d self.app.recoverable_node_timeout"},{"line_number":1045,"context_line":""},{"line_number":1046,"context_line":"        concurrent_reads \u003d self.app.concurrent_reads"},{"line_number":1047,"context_line":"        concurrency_timeout \u003d self.app.concurrency_timeout"},{"line_number":1048,"context_line":"        pile \u003d GreenAsyncPile(self.concurrency)"},{"line_number":1049,"context_line":""},{"line_number":1050,"context_line":"        results \u003d list()"}],"source_content_type":"text/x-python","patch_set":17,"id":"1a4dcd0f_79482388","line":1047,"updated":"2015-08-10 01:17:22.000000000","message":"personally I find slightly awkward to pull these config options off the app into locals - instead of just referencing them by self.app.option in place where they are used.  Maybe it was just a line length thing.","commit_id":"0e7d36ef399b4b830af85dc10a804d0f5cd70431"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"fb3b786e66a1369a0cff70b902d4d7c2182a10be","unresolved":false,"context_lines":[{"line_number":1047,"context_line":"        concurrency_timeout \u003d self.app.concurrency_timeout"},{"line_number":1048,"context_line":"        pile \u003d GreenAsyncPile(self.concurrency)"},{"line_number":1049,"context_line":""},{"line_number":1050,"context_line":"        results \u003d list()"},{"line_number":1051,"context_line":"        for node in nodes:"},{"line_number":1052,"context_line":"            pile.spawn(self._make_node_request, node, node_timeout)"},{"line_number":1053,"context_line":"            if concurrent_reads:"}],"source_content_type":"text/x-python","patch_set":17,"id":"1a4dcd0f_f92bd392","line":1050,"updated":"2015-08-10 01:17:22.000000000","message":"so these keeps track of a list of True/False depending on the response of _make_node_request.","commit_id":"0e7d36ef399b4b830af85dc10a804d0f5cd70431"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"fb3b786e66a1369a0cff70b902d4d7c2182a10be","unresolved":false,"context_lines":[{"line_number":1059,"context_line":"            if True in results:"},{"line_number":1060,"context_line":"                break"},{"line_number":1061,"context_line":""},{"line_number":1062,"context_line":"        if not any(results):"},{"line_number":1063,"context_line":"            # Wait for sufficient good sources."},{"line_number":1064,"context_line":"            for result in pile:"},{"line_number":1065,"context_line":"                if result:"}],"source_content_type":"text/x-python","patch_set":17,"id":"1a4dcd0f_b91c6b78","line":1062,"updated":"2015-08-10 01:17:22.000000000","message":"I find this and the four lines above it borderline obfuscated :\\\n\n            if any(pile.waitall(_timeout)):\n                break\n        else:\n            # ran out of nodes, see if any stragglers will finish\n            any(pile)","commit_id":"0e7d36ef399b4b830af85dc10a804d0f5cd70431"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"fb3b786e66a1369a0cff70b902d4d7c2182a10be","unresolved":false,"context_lines":[{"line_number":1065,"context_line":"                if result:"},{"line_number":1066,"context_line":"                    break"},{"line_number":1067,"context_line":""},{"line_number":1068,"context_line":"        if self.sources:"},{"line_number":1069,"context_line":"            self.sources.sort(key\u003dlambda s: source_key(s[0]))"},{"line_number":1070,"context_line":"            source, node \u003d self.sources.pop()"},{"line_number":1071,"context_line":"            for src, _junk in self.sources:"}],"source_content_type":"text/x-python","patch_set":17,"id":"1a4dcd0f_f4475a49","line":1068,"updated":"2015-08-10 01:17:22.000000000","message":"also a refactor - but guard pattern would be better here I think:\n\n    if not self.sources:\n        return None, None\n    ...","commit_id":"0e7d36ef399b4b830af85dc10a804d0f5cd70431"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"fb3b786e66a1369a0cff70b902d4d7c2182a10be","unresolved":false,"context_lines":[{"line_number":1547,"context_line":""},{"line_number":1548,"context_line":"        handler \u003d GetOrHeadHandler(self.app, req, self.server_type, node_iter,"},{"line_number":1549,"context_line":"                                   partition, path, backend_headers,"},{"line_number":1550,"context_line":"                                   concurrency,"},{"line_number":1551,"context_line":"                                   client_chunk_size\u003dclient_chunk_size)"},{"line_number":1552,"context_line":"        res \u003d handler.get_working_response(req)"},{"line_number":1553,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"1a4dcd0f_943616b3","line":1550,"updated":"2015-08-10 01:17:22.000000000","message":"This is the only place a a GetOrHeadHandler is created - something about that bugs me to have to plumb it through GETorHEAD_base like it\u0027s some sort of GetOrHeadHandlerFactory.\n\nWhat is the context that we have outside of GETorHEAD_base that we loose once we\u0027re in here?\n\nIf it\u0027s just if we\u0027re a ReplicatedObjectController it seems like a class attribute would be the way to go.  The ring and any config options will already be available on the app.","commit_id":"0e7d36ef399b4b830af85dc10a804d0f5cd70431"},{"author":{"_account_id":995,"name":"David Goetz","email":"david.goetz@rackspace.com","username":"david-goetz"},"change_message_id":"8d3f3fbdabf08aeb61c310cfd4da65a550ece3e2","unresolved":false,"context_lines":[{"line_number":969,"context_line":"            return None"},{"line_number":970,"context_line":""},{"line_number":971,"context_line":"    def _make_node_request(self, node, node_timeout):"},{"line_number":972,"context_line":"        if node in self.used_nodes:"},{"line_number":973,"context_line":"            return False"},{"line_number":974,"context_line":"        start_node_timing \u003d time.time()"},{"line_number":975,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":21,"id":"7a2fa921_0d1457f3","line":972,"updated":"2015-10-06 18:54:34.000000000","message":"should it check this in the for loop below? i guess it doesn\u0027t matter too much","commit_id":"50cb0f75837c0ca148579a7d5ea26fc8f97686ca"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"7224f0d9e896a6731a74335ed9b68f880e067f13","unresolved":false,"context_lines":[{"line_number":1063,"context_line":"                break"},{"line_number":1064,"context_line":"        else:"},{"line_number":1065,"context_line":"            # ran out of nodes, see if any stagglers will finish"},{"line_number":1066,"context_line":"            any(pile)"},{"line_number":1067,"context_line":""},{"line_number":1068,"context_line":"        if self.sources:"},{"line_number":1069,"context_line":"            self.sources.sort(key\u003dlambda s: source_key(s[0]))"}],"source_content_type":"text/x-python","patch_set":23,"id":"9a8ffd7b_8409a6df","line":1066,"updated":"2015-11-26 05:10:25.000000000","message":"I\u0027m not 100% convinced about the \u0027for..else\u0027 here. I mean it works in most cases, which is great, but really a True is only returned from _make_node_request is its a good source (great) _and_ if it\u0027s not looking for X-Newest (good, as this is most the time).\nBut does this mean X-Newest, which already has to wait for all nodes to respond, now has to wait even longer because it will _always_ hit the else?","commit_id":"0b67b2d0c92ec3e9d854a6ffc123b5461d178413"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"22c7d2b83d23f28c91e0c6528b44e9e738305e7e","unresolved":false,"context_lines":[{"line_number":1063,"context_line":"                break"},{"line_number":1064,"context_line":"        else:"},{"line_number":1065,"context_line":"            # ran out of nodes, see if any stagglers will finish"},{"line_number":1066,"context_line":"            any(pile)"},{"line_number":1067,"context_line":""},{"line_number":1068,"context_line":"        if self.sources:"},{"line_number":1069,"context_line":"            self.sources.sort(key\u003dlambda s: source_key(s[0]))"}],"source_content_type":"text/x-python","patch_set":23,"id":"9a8ffd7b_a4ae2a83","line":1066,"in_reply_to":"9a8ffd7b_8409a6df","updated":"2015-11-26 05:18:12.000000000","message":"I guess X-Newest is going to wait for all requests in pile anyway, so it probably is ok.","commit_id":"0b67b2d0c92ec3e9d854a6ffc123b5461d178413"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d70f43c16de45b9f03d461614f6db091fd109319","unresolved":false,"context_lines":[{"line_number":1062,"context_line":"            # we have the same object (replication) or a fragment archive"},{"line_number":1063,"context_line":"            # from the same object (EC). Otherwise, if the cluster has two"},{"line_number":1064,"context_line":"            # versions of the same object, we might end up switching between"},{"line_number":1065,"context_line":"            # old and new mid-stream and giving garbage to the client."},{"line_number":1066,"context_line":"            self.used_source_etag \u003d src_headers.get("},{"line_number":1067,"context_line":"                \u0027x-object-sysmeta-ec-etag\u0027,"},{"line_number":1068,"context_line":"                src_headers.get(\u0027etag\u0027, \u0027\u0027)).strip(\u0027\"\u0027)"}],"source_content_type":"text/x-python","patch_set":26,"id":"5aef4532_ca403237","side":"PARENT","line":1065,"updated":"2016-03-09 16:09:31.000000000","message":"why lose the comment?","commit_id":"ebe61381c27607adc212402fc64c3b7ae4fef27d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d70f43c16de45b9f03d461614f6db091fd109319","unresolved":false,"context_lines":[{"line_number":972,"context_line":"        else:"},{"line_number":973,"context_line":"            return None"},{"line_number":974,"context_line":""},{"line_number":975,"context_line":"    def _make_node_request(self, node, node_timeout):"},{"line_number":976,"context_line":"        if node in self.used_nodes:"},{"line_number":977,"context_line":"            return False"},{"line_number":978,"context_line":"        start_node_timing \u003d time.time()"}],"source_content_type":"text/x-python","patch_set":26,"id":"5aef4532_38ee42b4","line":975,"updated":"2016-03-09 16:09:31.000000000","message":"very nice extraction","commit_id":"4d6d54f228001cd835e3abf6d8fca82d1fae562d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d70f43c16de45b9f03d461614f6db091fd109319","unresolved":false,"context_lines":[{"line_number":1059,"context_line":"        for node in nodes:"},{"line_number":1060,"context_line":"            pile.spawn(self._make_node_request, node, node_timeout)"},{"line_number":1061,"context_line":"            _timeout \u003d self.app.concurrency_timeout \\"},{"line_number":1062,"context_line":"                if pile.inflight \u003c self.concurrency else node_timeout"},{"line_number":1063,"context_line":"            if pile.waitfirst(_timeout):"},{"line_number":1064,"context_line":"                break"},{"line_number":1065,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":26,"id":"5aef4532_5b323560","line":1062,"updated":"2016-03-09 16:09:31.000000000","message":"Not sure about this...if conncurrent_gets is False, concurrency\u003d\u003d1 and the _timeout value will always be node_timeout, which is less that the timeouts allowed on master for the connection to and reading from each node (i.e. master allows conn_timeout + node_timeout), which is now refactored into _make_node_request.\n\nPerhaps this should be:\n\n  _timeout \u003d self.app.concurrency_timeout \\\n                if pile.inflight \u003c self.concurrency else None\n\nsince None\u003d\u003dno timeout, which is ok because the timeouts in _make_node_request will fire.","commit_id":"4d6d54f228001cd835e3abf6d8fca82d1fae562d"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"c25fb967237a2b9740687f5c73dd45a902ce23ae","unresolved":false,"context_lines":[{"line_number":1059,"context_line":"        for node in nodes:"},{"line_number":1060,"context_line":"            pile.spawn(self._make_node_request, node, node_timeout)"},{"line_number":1061,"context_line":"            _timeout \u003d self.app.concurrency_timeout \\"},{"line_number":1062,"context_line":"                if pile.inflight \u003c self.concurrency else node_timeout"},{"line_number":1063,"context_line":"            if pile.waitfirst(_timeout):"},{"line_number":1064,"context_line":"                break"},{"line_number":1065,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":26,"id":"3afc51ec_e530d3ea","line":1062,"in_reply_to":"5aef4532_5b323560","updated":"2016-03-15 02:15:34.000000000","message":"Wow, nice spot Alistair. the _make_node_requests would be conn_timeout  + node_timeout. I don\u0027t think it\u0027s too big a deal cause if it does timeout, the request will still be picked up in the any(pile).. but yeah this is clearly wrong, we are waiting a shorter time then we allow the connection to take.\n\nI like your simple and easier to maintain solution or None :)","commit_id":"4d6d54f228001cd835e3abf6d8fca82d1fae562d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d70f43c16de45b9f03d461614f6db091fd109319","unresolved":false,"context_lines":[{"line_number":1061,"context_line":"            _timeout \u003d self.app.concurrency_timeout \\"},{"line_number":1062,"context_line":"                if pile.inflight \u003c self.concurrency else node_timeout"},{"line_number":1063,"context_line":"            if pile.waitfirst(_timeout):"},{"line_number":1064,"context_line":"                break"},{"line_number":1065,"context_line":"        else:"},{"line_number":1066,"context_line":"            # ran out of nodes, see if any stagglers will finish"},{"line_number":1067,"context_line":"            any(pile)"}],"source_content_type":"text/x-python","patch_set":26,"id":"5aef4532_35193223","line":1064,"updated":"2016-03-09 16:09:31.000000000","message":"Am I understanding this correctly:\n\n- pile.waitfirst may return False if it times out OR if the response is not useful\n\nSo this can happen:\n\n  - first call to waitfirst times out, issue a concurrent GET :)\n  - very shortly after second call returns False due to first GET completing unsuccessfully, issue another concurrent GET that is not staggered w.r.t. the second.\n\nThat is not what I was expecting. I guess I expected the third GET to only be issued after the second times out (or returns unsuccessful).","commit_id":"4d6d54f228001cd835e3abf6d8fca82d1fae562d"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"c25fb967237a2b9740687f5c73dd45a902ce23ae","unresolved":false,"context_lines":[{"line_number":1061,"context_line":"            _timeout \u003d self.app.concurrency_timeout \\"},{"line_number":1062,"context_line":"                if pile.inflight \u003c self.concurrency else node_timeout"},{"line_number":1063,"context_line":"            if pile.waitfirst(_timeout):"},{"line_number":1064,"context_line":"                break"},{"line_number":1065,"context_line":"        else:"},{"line_number":1066,"context_line":"            # ran out of nodes, see if any stagglers will finish"},{"line_number":1067,"context_line":"            any(pile)"}],"source_content_type":"text/x-python","patch_set":26,"id":"3afc51ec_4a327611","line":1064,"in_reply_to":"5aef4532_35193223","updated":"2016-03-15 02:15:34.000000000","message":"So if x-newest is set, then we need to query all nodes, therefore it will return a False for each node. A False is also returned on timeout, or a not useful response, so yeah. \nOtherwise, once we find a good response we return a True.\n\nConcurrent gets really just staggers the requests. Either by conn_timeout, concurrency_timeout, node_timeout or 0. The latter 2 being one at a time or all at once. \n\nOriginally we used a waitall(timeout), but the new waitfirst(timeout) method really speeds up requests on average, but I guess does have the potential of sending out more requests. And turning concurrent gets on would mean the Ops would need to wear this trade off.","commit_id":"4d6d54f228001cd835e3abf6d8fca82d1fae562d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d70f43c16de45b9f03d461614f6db091fd109319","unresolved":false,"context_lines":[{"line_number":1063,"context_line":"            if pile.waitfirst(_timeout):"},{"line_number":1064,"context_line":"                break"},{"line_number":1065,"context_line":"        else:"},{"line_number":1066,"context_line":"            # ran out of nodes, see if any stagglers will finish"},{"line_number":1067,"context_line":"            any(pile)"},{"line_number":1068,"context_line":""},{"line_number":1069,"context_line":"        if self.sources:"}],"source_content_type":"text/x-python","patch_set":26,"id":"5aef4532_2f6a88ee","line":1066,"updated":"2016-03-09 16:09:31.000000000","message":"s/stagglers/stragglers/\n\nhmmm, staggler conjures up an image of a drunk staggering home from a stag night :)","commit_id":"4d6d54f228001cd835e3abf6d8fca82d1fae562d"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"c25fb967237a2b9740687f5c73dd45a902ce23ae","unresolved":false,"context_lines":[{"line_number":1063,"context_line":"            if pile.waitfirst(_timeout):"},{"line_number":1064,"context_line":"                break"},{"line_number":1065,"context_line":"        else:"},{"line_number":1066,"context_line":"            # ran out of nodes, see if any stagglers will finish"},{"line_number":1067,"context_line":"            any(pile)"},{"line_number":1068,"context_line":""},{"line_number":1069,"context_line":"        if self.sources:"}],"source_content_type":"text/x-python","patch_set":26,"id":"3afc51ec_8a275e63","line":1066,"in_reply_to":"5aef4532_2f6a88ee","updated":"2016-03-15 02:15:34.000000000","message":"Done","commit_id":"4d6d54f228001cd835e3abf6d8fca82d1fae562d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"4e74c0b10dca7f529aec5815e753fe69007d7693","unresolved":false,"context_lines":[{"line_number":974,"context_line":"        else:"},{"line_number":975,"context_line":"            return None"},{"line_number":976,"context_line":""},{"line_number":977,"context_line":"    def _make_node_request(self, node, node_timeout):"},{"line_number":978,"context_line":"        if node in self.used_nodes:"},{"line_number":979,"context_line":"            return False"},{"line_number":980,"context_line":"        start_node_timing \u003d time.time()"}],"source_content_type":"text/x-python","patch_set":27,"id":"1af94dfe_27b508cd","line":977,"updated":"2016-03-15 16:49:17.000000000","message":"logger thread_locals needs to be passed so we get txn id\u0027s in logs from the spawned thread","commit_id":"5a281d578b8dde346de049ec62d3b4a86d3651ed"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"ba6386d0405b3c0b0169ae2f02ea0c2ee5fea84f","unresolved":false,"context_lines":[{"line_number":974,"context_line":"        else:"},{"line_number":975,"context_line":"            return None"},{"line_number":976,"context_line":""},{"line_number":977,"context_line":"    def _make_node_request(self, node, node_timeout, logger_thread_locals):"},{"line_number":978,"context_line":"        self.app.logger.thread_locals \u003d logger_thread_locals"},{"line_number":979,"context_line":"        if node in self.used_nodes:"},{"line_number":980,"context_line":"            return False"}],"source_content_type":"text/x-python","patch_set":28,"id":"1af94dfe_2aa7c30b","line":977,"updated":"2016-03-18 22:20:43.000000000","message":"hrm... doc string explaining the Falsy-ness of the return value would be wonderful here.","commit_id":"f595a7e70492c2751d8c6f5ab60b5512e63281cf"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"ba6386d0405b3c0b0169ae2f02ea0c2ee5fea84f","unresolved":false,"context_lines":[{"line_number":1061,"context_line":""},{"line_number":1062,"context_line":"        for node in nodes:"},{"line_number":1063,"context_line":"            pile.spawn(self._make_node_request, node, node_timeout,"},{"line_number":1064,"context_line":"                       self.app.logger.thread_locals)"},{"line_number":1065,"context_line":"            _timeout \u003d self.app.concurrency_timeout \\"},{"line_number":1066,"context_line":"                if pile.inflight \u003c self.concurrency else None"},{"line_number":1067,"context_line":"            if pile.waitfirst(_timeout):"}],"source_content_type":"text/x-python","patch_set":28,"id":"1af94dfe_470e8ae5","line":1064,"updated":"2016-03-18 22:20:43.000000000","message":"yay thread locals!","commit_id":"f595a7e70492c2751d8c6f5ab60b5512e63281cf"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"ba6386d0405b3c0b0169ae2f02ea0c2ee5fea84f","unresolved":false,"context_lines":[{"line_number":1064,"context_line":"                       self.app.logger.thread_locals)"},{"line_number":1065,"context_line":"            _timeout \u003d self.app.concurrency_timeout \\"},{"line_number":1066,"context_line":"                if pile.inflight \u003c self.concurrency else None"},{"line_number":1067,"context_line":"            if pile.waitfirst(_timeout):"},{"line_number":1068,"context_line":"                break"},{"line_number":1069,"context_line":"        else:"},{"line_number":1070,"context_line":"            # ran out of nodes, see if any stragglers will finish"}],"source_content_type":"text/x-python","patch_set":28,"id":"1af94dfe_c7545acb","line":1067,"updated":"2016-03-18 22:20:43.000000000","message":"oh wow, this line is pretty dense - it\u0027s testing a) did a response come back before timeout and b) was it \"successful\" [1]\n\n1. \"successful\" is sort of a tricky word here, because a x-newest request could append a successful response to sources - but still return None/False.","commit_id":"f595a7e70492c2751d8c6f5ab60b5512e63281cf"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"ba6386d0405b3c0b0169ae2f02ea0c2ee5fea84f","unresolved":false,"context_lines":[{"line_number":1068,"context_line":"                break"},{"line_number":1069,"context_line":"        else:"},{"line_number":1070,"context_line":"            # ran out of nodes, see if any stragglers will finish"},{"line_number":1071,"context_line":"            any(pile)"},{"line_number":1072,"context_line":""},{"line_number":1073,"context_line":"        if self.sources:"},{"line_number":1074,"context_line":"            self.sources.sort(key\u003dlambda s: source_key(s[0]))"}],"source_content_type":"text/x-python","patch_set":28,"id":"1af94dfe_c76bba83","line":1071,"updated":"2016-03-18 22:20:43.000000000","message":"i think x-newest should always end up hitting these case and fully exhausting the iter (up to each requests node_timeout) - which should be correct.","commit_id":"f595a7e70492c2751d8c6f5ab60b5512e63281cf"}],"swift/proxy/controllers/obj.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"fb3b786e66a1369a0cff70b902d4d7c2182a10be","unresolved":false,"context_lines":[{"line_number":992,"context_line":"class ReplicatedObjectController(BaseObjectController):"},{"line_number":993,"context_line":""},{"line_number":994,"context_line":"    def _get_or_head_response(self, req, node_iter, partition, policy):"},{"line_number":995,"context_line":"        concurrency \u003d self.app.get_object_ring(policy.idx).replica_count"},{"line_number":996,"context_line":"        resp \u003d self.GETorHEAD_base("},{"line_number":997,"context_line":"            req, _(\u0027Object\u0027), node_iter, partition,"},{"line_number":998,"context_line":"            req.swift_entity_path, concurrency)"}],"source_content_type":"text/x-python","patch_set":17,"id":"1a4dcd0f_d4025eb4","line":995,"updated":"2015-08-10 01:17:22.000000000","message":"Hrm... I think this coupling might get rid of knob - but it might have been a useful knob.  I\u0027m thinking about all the region deployments where you might have a replica count of 4 or more, but also if sometimes even triple replicated 2 might be enough to get most of the benefit?","commit_id":"0e7d36ef399b4b830af85dc10a804d0f5cd70431"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"fb3b786e66a1369a0cff70b902d4d7c2182a10be","unresolved":false,"context_lines":[{"line_number":2098,"context_line":"            # no fancy EC decoding here, just one plain old HEAD request to"},{"line_number":2099,"context_line":"            # one object server because all fragments hold all metadata"},{"line_number":2100,"context_line":"            # information about the object."},{"line_number":2101,"context_line":"            concurrency \u003d policy.ec_ndata"},{"line_number":2102,"context_line":"            resp \u003d self.GETorHEAD_base("},{"line_number":2103,"context_line":"                req, _(\u0027Object\u0027), node_iter, partition,"},{"line_number":2104,"context_line":"                req.swift_entity_path, concurrency)"}],"source_content_type":"text/x-python","patch_set":17,"id":"1a4dcd0f_94d29633","line":2101,"updated":"2015-08-10 01:17:22.000000000","message":"Oh this is nice, I wasn\u0027t sure if the EC HEADs were going to get the concurrency love.\n\nStill not sure about the coupling, parity fragments have the metadata too; but 14 concurrent requests for every HEAD seems like overkill :\\","commit_id":"0e7d36ef399b4b830af85dc10a804d0f5cd70431"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d70f43c16de45b9f03d461614f6db091fd109319","unresolved":false,"context_lines":[{"line_number":2012,"context_line":"            # with the first response isn\u0027t something useful for EC as it needs"},{"line_number":2013,"context_line":"            # a quorum response from the primary nodes. So we don\u0027t need to"},{"line_number":2014,"context_line":"            # worry about plumbing and sending a concurrency value to"},{"line_number":2015,"context_line":"            # ResumingGetter as the default concurrency value is 1"},{"line_number":2016,"context_line":"            with ContextPool(policy.ec_ndata) as pool:"},{"line_number":2017,"context_line":"                pile \u003d GreenAsyncPile(pool)"},{"line_number":2018,"context_line":"                for _junk in range(policy.ec_ndata):"}],"source_content_type":"text/x-python","patch_set":26,"id":"5aef4532_0c619ad3","line":2015,"updated":"2016-03-09 16:09:31.000000000","message":"Isn\u0027t it more the case that EC already does fully concurrent gets to ec_ndata nodes?","commit_id":"4d6d54f228001cd835e3abf6d8fca82d1fae562d"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"c25fb967237a2b9740687f5c73dd45a902ce23ae","unresolved":false,"context_lines":[{"line_number":2012,"context_line":"            # with the first response isn\u0027t something useful for EC as it needs"},{"line_number":2013,"context_line":"            # a quorum response from the primary nodes. So we don\u0027t need to"},{"line_number":2014,"context_line":"            # worry about plumbing and sending a concurrency value to"},{"line_number":2015,"context_line":"            # ResumingGetter as the default concurrency value is 1"},{"line_number":2016,"context_line":"            with ContextPool(policy.ec_ndata) as pool:"},{"line_number":2017,"context_line":"                pile \u003d GreenAsyncPile(pool)"},{"line_number":2018,"context_line":"                for _junk in range(policy.ec_ndata):"}],"source_content_type":"text/x-python","patch_set":26,"id":"3afc51ec_452d4745","line":2015,"in_reply_to":"5aef4532_0c619ad3","updated":"2016-03-15 02:15:34.000000000","message":"Done","commit_id":"4d6d54f228001cd835e3abf6d8fca82d1fae562d"}],"swift/proxy/server.py":[{"author":{"_account_id":6968,"name":"Christian Schwede","email":"cschwede@nvidia.com","username":"cschwede"},"change_message_id":"4ec68330313d228be80861baf857fb2c9b9886e9","unresolved":false,"context_lines":[{"line_number":206,"context_line":"            conf.get(\u0027disallowed_sections\u0027))"},{"line_number":207,"context_line":"        self.admin_key \u003d conf.get(\u0027admin_key\u0027, None)"},{"line_number":208,"context_line":"        self.concurrent_reads \u003d \\"},{"line_number":209,"context_line":"            config_true_value(conf.get(\u0027concurrent_reads\u0027))"},{"line_number":210,"context_line":"        register_swift_info("},{"line_number":211,"context_line":"            version\u003dswift_version,"},{"line_number":212,"context_line":"            strict_cors_mode\u003dself.strict_cors_mode,"}],"source_content_type":"text/x-python","patch_set":5,"id":"fa98f980_5700fe33","line":209,"updated":"2014-09-11 08:03:14.000000000","message":"config_true_value returns False if the argument is None (and this is the default for conf.get())","commit_id":"f1b52b732221b5c58ff613b286c4a152f93aea16"},{"author":{"_account_id":5189,"name":"Yuan Zhou","email":"dunk007@gmail.com","username":"yuan-zhou"},"change_message_id":"4f292dc4dae143f1dd839dcba5594a747e75dedf","unresolved":false,"context_lines":[{"line_number":206,"context_line":"            conf.get(\u0027disallowed_sections\u0027))"},{"line_number":207,"context_line":"        self.admin_key \u003d conf.get(\u0027admin_key\u0027, None)"},{"line_number":208,"context_line":"        self.concurrent_reads \u003d \\"},{"line_number":209,"context_line":"            config_true_value(conf.get(\u0027concurrent_reads\u0027))"},{"line_number":210,"context_line":"        register_swift_info("},{"line_number":211,"context_line":"            version\u003dswift_version,"},{"line_number":212,"context_line":"            strict_cors_mode\u003dself.strict_cors_mode,"}],"source_content_type":"text/x-python","patch_set":5,"id":"fa98f980_b8aea8e5","line":209,"updated":"2014-09-10 08:57:50.000000000","message":"need some default value here, like:\nconfig_true_value(conf.get(\u0027concurrent_reads\u0027, \u0027false\u0027))","commit_id":"f1b52b732221b5c58ff613b286c4a152f93aea16"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"c5b993f958e95d988a83ec4235c755f5b8a9b15c","unresolved":false,"context_lines":[{"line_number":206,"context_line":"            conf.get(\u0027disallowed_sections\u0027))"},{"line_number":207,"context_line":"        self.admin_key \u003d conf.get(\u0027admin_key\u0027, None)"},{"line_number":208,"context_line":"        self.concurrent_reads \u003d \\"},{"line_number":209,"context_line":"            config_true_value(conf.get(\u0027concurrent_reads\u0027))"},{"line_number":210,"context_line":"        register_swift_info("},{"line_number":211,"context_line":"            version\u003dswift_version,"},{"line_number":212,"context_line":"            strict_cors_mode\u003dself.strict_cors_mode,"}],"source_content_type":"text/x-python","patch_set":5,"id":"fa98f980_a8eaaf0c","line":209,"in_reply_to":"fa98f980_b8aea8e5","updated":"2014-09-11 02:12:49.000000000","message":"config_true_value will always return a true or false. If it can\u0027t determine it as a true value (isn\u0027t True or in TRUE_VALUES) it will always return a False.\n\nSo by using config_true_value it already defaults to False.","commit_id":"f1b52b732221b5c58ff613b286c4a152f93aea16"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"ba6386d0405b3c0b0169ae2f02ea0c2ee5fea84f","unresolved":false,"context_lines":[{"line_number":150,"context_line":"        self.concurrent_gets \u003d \\"},{"line_number":151,"context_line":"            config_true_value(conf.get(\u0027concurrent_gets\u0027))"},{"line_number":152,"context_line":"        self.concurrency_timeout \u003d float(conf.get(\u0027concurrency_timeout\u0027,"},{"line_number":153,"context_line":"                                                  self.conn_timeout))"},{"line_number":154,"context_line":"        value \u003d conf.get(\u0027request_node_count\u0027, \u00272 * replicas\u0027).lower().split()"},{"line_number":155,"context_line":"        if len(value) \u003d\u003d 1:"},{"line_number":156,"context_line":"            rnc_value \u003d int(value[0])"}],"source_content_type":"text/x-python","patch_set":28,"id":"1af94dfe_27b89e74","line":153,"updated":"2016-03-18 22:20:43.000000000","message":"i think there\u0027s a case to be made that if node_timeout \u003e concurrency_timeout we could log a warning or something...","commit_id":"f595a7e70492c2751d8c6f5ab60b5512e63281cf"}],"test/functional/__init__.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"e65e55003164e7f4d81a56e8e21fe428a07ebf79","unresolved":false,"context_lines":[{"line_number":278,"context_line":"    def get_logger(name, *args, **kwargs):"},{"line_number":279,"context_line":"        return logger"},{"line_number":280,"context_line":""},{"line_number":281,"context_line":"    global app"},{"line_number":282,"context_line":"    with mock.patch(\u0027swift.common.utils.get_logger\u0027, get_logger):"},{"line_number":283,"context_line":"        with mock.patch(\u0027swift.common.middleware.memcache.MemcacheMiddleware\u0027,"},{"line_number":284,"context_line":"                        FakeMemcacheMiddleware):"}],"source_content_type":"text/x-python","patch_set":12,"id":"5a890539_5e391d40","line":281,"updated":"2014-11-21 01:08:36.000000000","message":"yay more global state!","commit_id":"17409a3546ce46c51d65befbc1756eed746784d7"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"3061ebb771cd2d1abdcaa8dd7a0bfdb392a85dda","unresolved":false,"context_lines":[{"line_number":278,"context_line":"    def get_logger(name, *args, **kwargs):"},{"line_number":279,"context_line":"        return logger"},{"line_number":280,"context_line":""},{"line_number":281,"context_line":"    global app"},{"line_number":282,"context_line":"    with mock.patch(\u0027swift.common.utils.get_logger\u0027, get_logger):"},{"line_number":283,"context_line":"        with mock.patch(\u0027swift.common.middleware.memcache.MemcacheMiddleware\u0027,"},{"line_number":284,"context_line":"                        FakeMemcacheMiddleware):"}],"source_content_type":"text/x-python","patch_set":12,"id":"5a890539_7d8efa28","line":281,"in_reply_to":"5a890539_5e391d40","updated":"2014-12-01 04:43:15.000000000","message":"Do I sense sarcasm :P","commit_id":"17409a3546ce46c51d65befbc1756eed746784d7"}],"test/functional/tests.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0f2a7eb45ba75757553119fc6748319c03170413","unresolved":false,"context_lines":[{"line_number":227,"context_line":""},{"line_number":228,"context_line":"        # Now test again using concurrent reads, if we have access to the"},{"line_number":229,"context_line":"        # proxy server (in-process servers)"},{"line_number":230,"context_line":"        if tf.in_process:"},{"line_number":231,"context_line":"            tf.app.concurrent_reads \u003d True"},{"line_number":232,"context_line":"            for format_type in [None, \u0027json\u0027, \u0027xml\u0027]:"},{"line_number":233,"context_line":"                b \u003d self.env.account.containers(parms\u003d{\u0027format\u0027: format_type})"}],"source_content_type":"text/x-python","patch_set":12,"id":"5a890539_c018b0d5","line":230,"updated":"2014-11-21 17:37:12.000000000","message":"Inclined to agree with Clay\u0027s comment below, but if we are to have skip tests then break them out to a separate test and raise a SkipTest so its not hidden.","commit_id":"17409a3546ce46c51d65befbc1756eed746784d7"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"e65e55003164e7f4d81a56e8e21fe428a07ebf79","unresolved":false,"context_lines":[{"line_number":562,"context_line":""},{"line_number":563,"context_line":"        # Test container file list again this time using concurrent reads, if"},{"line_number":564,"context_line":"        # we have access to the proxy (in-process servers)"},{"line_number":565,"context_line":"        if tf.in_process:"},{"line_number":566,"context_line":"            tf.app.concurrent_reads \u003d True"},{"line_number":567,"context_line":"            for format_type in [None, \u0027json\u0027, \u0027xml\u0027]:"},{"line_number":568,"context_line":"                files \u003d self.env.container.files(parms\u003d{\u0027format\u0027: format_type})"}],"source_content_type":"text/x-python","patch_set":12,"id":"5a890539_7868b1ba","line":565,"updated":"2014-11-21 01:08:36.000000000","message":"I really don\u0027t like having a bunch of skip tests when running functional tests.  I don\u0027t think using the in process mocks is a good functional test of this feature anyway.  much more interesting to turn the feature on a real dev/lab deployment and point the the entire functional test suite at it - even more interesting if you introduce some latencies on the backend servers.","commit_id":"17409a3546ce46c51d65befbc1756eed746784d7"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"e65e55003164e7f4d81a56e8e21fe428a07ebf79","unresolved":false,"context_lines":[{"line_number":872,"context_line":"            raise SkipTest(\"in_process servers must be used for \""},{"line_number":873,"context_line":"                           \"concurrent read tests\")"},{"line_number":874,"context_line":""},{"line_number":875,"context_line":"        tf.app.concurrent_reads \u003d True"},{"line_number":876,"context_line":""},{"line_number":877,"context_line":""},{"line_number":878,"context_line":"class TestFile(Base):"}],"source_content_type":"text/x-python","patch_set":12,"id":"5a890539_58805546","line":875,"updated":"2014-11-21 01:08:36.000000000","message":"I really don\u0027t like seeing a bunch of new skip tests when running functional tests.\n\nI don\u0027t think using the in process mocks is a good functional test of this feature anyway.\n\nMuch more interesting to turn the feature on a real dev/lab deployment and point the the entire functional test suite at it - even more interesting if you introduce some latencies on the backend servers.","commit_id":"17409a3546ce46c51d65befbc1756eed746784d7"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0f2a7eb45ba75757553119fc6748319c03170413","unresolved":false,"context_lines":[{"line_number":1990,"context_line":"    set_up \u003d False"},{"line_number":1991,"context_line":""},{"line_number":1992,"context_line":"    def setUp(self):"},{"line_number":1993,"context_line":"        super(TestDloConcurrentRead, self).setUp()"},{"line_number":1994,"context_line":"        if tf.in_process is False:"},{"line_number":1995,"context_line":"            raise SkipTest(\"in_process servers must be used for \""},{"line_number":1996,"context_line":"                           \"concurrent read tests\")"}],"source_content_type":"text/x-python","patch_set":12,"id":"5a890539_a04ba485","line":1993,"updated":"2014-11-21 17:37:12.000000000","message":"move skip before super.setUp - it does a ton of stuff\n\nditto in other places","commit_id":"17409a3546ce46c51d65befbc1756eed746784d7"}],"test/unit/common/test_utils.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d70f43c16de45b9f03d461614f6db091fd109319","unresolved":false,"context_lines":[{"line_number":4838,"context_line":"        pile.spawn(run_test, 0.1, \u0027first\u0027)"},{"line_number":4839,"context_line":"        pile.spawn(run_test, 0.1, \u0027second\u0027)"},{"line_number":4840,"context_line":"        pile.spawn(run_test, 0.1, \u0027third\u0027)"},{"line_number":4841,"context_line":"        self.assertEqual(pile.waitfirst(0.5), \u0027first\u0027)"},{"line_number":4842,"context_line":"        # 3 still completed, but only the first was returned."},{"line_number":4843,"context_line":"        self.assertEqual(completed[0], 3)"},{"line_number":4844,"context_line":""}],"source_content_type":"text/x-python","patch_set":26,"id":"5aef4532_704f486b","line":4841,"updated":"2016-03-09 16:09:31.000000000","message":"Is this guaranteed i.e. that the first job spawned will always be the first to complete?","commit_id":"4d6d54f228001cd835e3abf6d8fca82d1fae562d"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"c25fb967237a2b9740687f5c73dd45a902ce23ae","unresolved":false,"context_lines":[{"line_number":4838,"context_line":"        pile.spawn(run_test, 0.1, \u0027first\u0027)"},{"line_number":4839,"context_line":"        pile.spawn(run_test, 0.1, \u0027second\u0027)"},{"line_number":4840,"context_line":"        pile.spawn(run_test, 0.1, \u0027third\u0027)"},{"line_number":4841,"context_line":"        self.assertEqual(pile.waitfirst(0.5), \u0027first\u0027)"},{"line_number":4842,"context_line":"        # 3 still completed, but only the first was returned."},{"line_number":4843,"context_line":"        self.assertEqual(completed[0], 3)"},{"line_number":4844,"context_line":""}],"source_content_type":"text/x-python","patch_set":26,"id":"3afc51ec_a03d19bd","line":4841,"in_reply_to":"5aef4532_704f486b","updated":"2016-03-15 02:15:34.000000000","message":"Oh because of sleep.. yeah maybe not.\n\nEventlet\u0027s patched sleep means that a sleep even of sleep(0) will context switch between all other evenlet threads in the pile. So I can change these tests to loop of sleep(0)\u0027s (context switches between threads) rather then relying a certain time limit, and we should then always pass. and guarantee that a certain thread will always return in the right order.\n\nI\u0027ll push up a new patch with the new version of these tests, for you to take a look at, if you don\u0027t like them I\u0027m happy to revert them.","commit_id":"4d6d54f228001cd835e3abf6d8fca82d1fae562d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d70f43c16de45b9f03d461614f6db091fd109319","unresolved":false,"context_lines":[{"line_number":4854,"context_line":"            for i in range(10):"},{"line_number":4855,"context_line":"                pile.spawn(run_test, 0.1, i)"},{"line_number":4856,"context_line":"            result \u003d list(range(first_n if first_n else 10))"},{"line_number":4857,"context_line":"            self.assertEqual(pile._wait(1, first_n), result)"},{"line_number":4858,"context_line":""},{"line_number":4859,"context_line":"    def test_pending(self):"},{"line_number":4860,"context_line":"        pile \u003d utils.GreenAsyncPile(3)"}],"source_content_type":"text/x-python","patch_set":26,"id":"5aef4532_10b52430","line":4857,"updated":"2016-03-09 16:09:31.000000000","message":"similar question to above - is the order guaranteed or just a quirk of the test timings?","commit_id":"4d6d54f228001cd835e3abf6d8fca82d1fae562d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"7bd2ea47c3466b8c73849019cffa28243e546039","unresolved":false,"context_lines":[{"line_number":5000,"context_line":"        pile.spawn(run_test, 1, \u0027first\u0027)"},{"line_number":5001,"context_line":"        pile.spawn(run_test, 1, \u0027second\u0027)"},{"line_number":5002,"context_line":"        pile.spawn(run_test, 1, \u0027third\u0027)"},{"line_number":5003,"context_line":"        self.assertEqual(pile.waitfirst(0.5), \u0027first\u0027)"},{"line_number":5004,"context_line":"        # 3 still completed, but only the first was returned."},{"line_number":5005,"context_line":"        self.assertEqual(completed[0], 3)"},{"line_number":5006,"context_line":""}],"source_content_type":"text/x-python","patch_set":27,"id":"3afc51ec_cc7e9418","line":5003,"updated":"2016-03-15 15:44:10.000000000","message":"I have a script that repeats tests and counts failure vs success, this fails approx 1 in 22 times OMM\n\nhttp://paste.openstack.org/show/490474/","commit_id":"5a281d578b8dde346de049ec62d3b4a86d3651ed"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"7bd2ea47c3466b8c73849019cffa28243e546039","unresolved":false,"context_lines":[{"line_number":5017,"context_line":"            for i in range(10):"},{"line_number":5018,"context_line":"                pile.spawn(run_test, 1, i)"},{"line_number":5019,"context_line":"            result \u003d list(range(first_n if first_n else 10))"},{"line_number":5020,"context_line":"            self.assertEqual(pile._wait(1, first_n), result)"},{"line_number":5021,"context_line":""},{"line_number":5022,"context_line":"    def test_pending(self):"},{"line_number":5023,"context_line":"        pile \u003d utils.GreenAsyncPile(3)"}],"source_content_type":"text/x-python","patch_set":27,"id":"3afc51ec_4cc9e425","line":5020,"updated":"2016-03-15 15:44:10.000000000","message":"this fails about 1 in 5 times OMM","commit_id":"5a281d578b8dde346de049ec62d3b4a86d3651ed"}],"test/unit/proxy/controllers/test_base.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"e65e55003164e7f4d81a56e8e21fe428a07ebf79","unresolved":false,"context_lines":[{"line_number":221,"context_line":"            resp \u003d base.GETorHEAD_base(req, \u0027account\u0027, FakeRing(), \u0027part\u0027,"},{"line_number":222,"context_line":"                                       \u0027/a\u0027)"},{"line_number":223,"context_line":"        self.assertTrue(\u0027swift.account/a\u0027 in resp.environ)"},{"line_number":224,"context_line":"        self.assertEqual(resp.environ[\u0027swift.account/a\u0027][\u0027status\u0027], 200)"},{"line_number":225,"context_line":""},{"line_number":226,"context_line":"    def test_get_info(self):"},{"line_number":227,"context_line":"        app \u003d FakeApp()"}],"source_content_type":"text/x-python","patch_set":12,"id":"5a890539_ded6edf0","line":224,"updated":"2014-11-21 01:08:36.000000000","message":"ummm... I don\u0027t really think this good enough.  It\u0027s one thing to say stuff still works with the option turned on, it\u0027s another thing entirely to validate the turning on the option achieves a specific behavior.\n\nThis change needs to have an update to the FakeConn utility to setup a mock response that has some sort of latency and a test to show that when the concurrent  node_sort option is turned on the GET path responds more \"quickly\" [1] than without it.\n\n1. it\u0027s going to be a total PITA to write this test because we can\u0027t actually have a test that takes 3-5 seconds to run, or has some sort of weird race.  But we do need that unit test.","commit_id":"17409a3546ce46c51d65befbc1756eed746784d7"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"fb3b786e66a1369a0cff70b902d4d7c2182a10be","unresolved":false,"context_lines":[{"line_number":194,"context_line":"        self.assertEqual(resp.environ[\u0027swift.account/a\u0027][\u0027status\u0027], 200)"},{"line_number":195,"context_line":""},{"line_number":196,"context_line":"        # Run the above tests again, but this time with concurrent_reads"},{"line_number":197,"context_line":"        # turned on"},{"line_number":198,"context_line":"        self.app.concurrent_reads \u003d True"},{"line_number":199,"context_line":"        req \u003d Request.blank(\u0027/v1/a/c/o/with/slashes\u0027)"},{"line_number":200,"context_line":"        with patch(\u0027swift.proxy.controllers.base.\u0027"}],"source_content_type":"text/x-python","patch_set":17,"id":"1a4dcd0f_f49bda70","line":197,"updated":"2015-08-10 01:17:22.000000000","message":"splatter coverage is useful perhaps - but not sufficient.","commit_id":"0e7d36ef399b4b830af85dc10a804d0f5cd70431"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"423bb968be64608f85ac9e3b0547c4f1018a791e","unresolved":false,"context_lines":[{"line_number":215,"context_line":"                    req, \u0027object\u0027, iter(nodes), \u0027part\u0027, \u0027/a/c/o\u0027,"},{"line_number":216,"context_line":"                    concurrency\u003dconcurrent_get_threads)"},{"line_number":217,"context_line":"            self.assertTrue(\u0027swift.object/a/c/o\u0027 in resp.environ)"},{"line_number":218,"context_line":"            self.assertEqual(resp.environ[\u0027swift.object/a/c/o\u0027][\u0027status\u0027], 200)"},{"line_number":219,"context_line":"            req \u003d Request.blank(\u0027/v1/a/c\u0027)"},{"line_number":220,"context_line":"            with patch(\u0027swift.proxy.controllers.base.\u0027"},{"line_number":221,"context_line":"                       \u0027http_connect\u0027, fake_http_connect(200)):"}],"source_content_type":"text/x-python","patch_set":24,"id":"9a8ffd7b_50ab4675","line":218,"updated":"2015-11-27 01:04:03.000000000","message":"So this second request on the iteration when concurrency_timeout is 0 fails. And I can\u0027t determine why. I think Clay\u0027s waitfirst change is too fast for mock and/or greenpile. If I change the 0 to 0.001 is works however:\n\n  for concurreny_timeout in (0.001, 2):","commit_id":"f2a93a160e382751583fbba5370777ad2771a509"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"c89698fa5483e41933e23cfdac0492ac41063b7f","unresolved":false,"context_lines":[{"line_number":237,"context_line":"                    req, \u0027account\u0027, iter(nodes), \u0027part\u0027, \u0027/a\u0027,"},{"line_number":238,"context_line":"                    concurrency\u003dconcurrent_get_threads)"},{"line_number":239,"context_line":"            self.assertTrue(\u0027swift.account/a\u0027 in resp.environ)"},{"line_number":240,"context_line":"            self.assertEqual(resp.environ[\u0027swift.account/a\u0027][\u0027status\u0027], 200)"},{"line_number":241,"context_line":""},{"line_number":242,"context_line":"    def test_get_info(self):"},{"line_number":243,"context_line":"        app \u003d FakeApp()"}],"source_content_type":"text/x-python","patch_set":25,"id":"9aed3d3a_9b14834d","line":240,"updated":"2016-03-01 13:59:55.000000000","message":"wat?  are you just trying check resp.status?  The environ caching stuff always weirds me out - i\u0027d rather not add something new that relies on it (even a test) unless we absolutely have to.","commit_id":"bd67c1959fddd278ec9bae2752a59a8cdc42a5ff"}],"test/unit/proxy/test_server.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"fb3b786e66a1369a0cff70b902d4d7c2182a10be","unresolved":false,"context_lines":[{"line_number":912,"context_line":"                resp.getheaders.return_value \u003d {}"},{"line_number":913,"context_line":"                resp.reason \u003d \u0027\u0027"},{"line_number":914,"context_line":"                resp.status \u003d statuses[self.ip]"},{"line_number":915,"context_line":"                sleep(timings[self.ip])"},{"line_number":916,"context_line":"                return resp"},{"line_number":917,"context_line":""},{"line_number":918,"context_line":"        def myfake_http_connect_raw(ip, *args, **kargs):"}],"source_content_type":"text/x-python","patch_set":17,"id":"1a4dcd0f_34ce225b","line":915,"updated":"2015-08-10 01:17:22.000000000","message":"hrmm... don\u0027t love the real sleeps.  On a busy system it\u0027s possible that even with a second lag two responses could get picked up in the same reactor loop.\n\nStill this pretty good.","commit_id":"0e7d36ef399b4b830af85dc10a804d0f5cd70431"},{"author":{"_account_id":330,"name":"John Dickinson","email":"me@not.mn","username":"notmyname"},"change_message_id":"85f64230eca280c0c2c7907fffa80c6383caaf9e","unresolved":false,"context_lines":[{"line_number":1006,"context_line":"                resp \u003d baseapp.handle_request(req)"},{"line_number":1007,"context_line":""},{"line_number":1008,"context_line":"                # Should get 127.0.0.2 as this has a wait of 1 seconds."},{"line_number":1009,"context_line":"                self.assertEqual(resp.body, \u0027Response from 127.0.0.2\u0027)"},{"line_number":1010,"context_line":""},{"line_number":1011,"context_line":"    def test_info_defaults(self):"},{"line_number":1012,"context_line":"        app \u003d proxy_server.Application({}, FakeMemcache(),"}],"source_content_type":"text/x-python","patch_set":25,"id":"9aed3d3a_21a50504","line":1009,"updated":"2016-02-25 19:46:48.000000000","message":"doesn\u0027t .3 still have a wait of zero? so why isn\u0027t that returned?","commit_id":"bd67c1959fddd278ec9bae2752a59a8cdc42a5ff"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"0d6334ff57f4144b6960af9490de450863590996","unresolved":false,"context_lines":[{"line_number":1006,"context_line":"                resp \u003d baseapp.handle_request(req)"},{"line_number":1007,"context_line":""},{"line_number":1008,"context_line":"                # Should get 127.0.0.2 as this has a wait of 1 seconds."},{"line_number":1009,"context_line":"                self.assertEqual(resp.body, \u0027Response from 127.0.0.2\u0027)"},{"line_number":1010,"context_line":""},{"line_number":1011,"context_line":"    def test_info_defaults(self):"},{"line_number":1012,"context_line":"        app \u003d proxy_server.Application({}, FakeMemcache(),"}],"source_content_type":"text/x-python","patch_set":25,"id":"9aed3d3a_9a89cfcd","line":1009,"in_reply_to":"9aed3d3a_21a50504","updated":"2016-02-25 22:44:31.000000000","message":"Because we set the concurrency timeout to 2, so we are staggering the firing of requests:\n\n  t0              -\u003e .1 (500)\n  t1 (t0 + 2 sec) -\u003e .2 (200) -\u003e return\n\nSo we never get to .3. So this last part is testing that setting a concurrency_timeout changes the behaviour.","commit_id":"bd67c1959fddd278ec9bae2752a59a8cdc42a5ff"},{"author":{"_account_id":330,"name":"John Dickinson","email":"me@not.mn","username":"notmyname"},"change_message_id":"42b613b7955bfffae9e24153e07c4e3e097dd90b","unresolved":false,"context_lines":[{"line_number":1006,"context_line":"                resp \u003d baseapp.handle_request(req)"},{"line_number":1007,"context_line":""},{"line_number":1008,"context_line":"                # Should get 127.0.0.2 as this has a wait of 1 seconds."},{"line_number":1009,"context_line":"                self.assertEqual(resp.body, \u0027Response from 127.0.0.2\u0027)"},{"line_number":1010,"context_line":""},{"line_number":1011,"context_line":"    def test_info_defaults(self):"},{"line_number":1012,"context_line":"        app \u003d proxy_server.Application({}, FakeMemcache(),"}],"source_content_type":"text/x-python","patch_set":25,"id":"9aed3d3a_8520544b","line":1009,"in_reply_to":"9aed3d3a_9a89cfcd","updated":"2016-02-25 22:56:27.000000000","message":"ah, ok. It\u0027s the staggering of requests I was overlooking. I understand now. Thanks","commit_id":"bd67c1959fddd278ec9bae2752a59a8cdc42a5ff"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d70f43c16de45b9f03d461614f6db091fd109319","unresolved":false,"context_lines":[{"line_number":926,"context_line":"                          {\u0027region\u0027: 2, \u0027zone\u0027: 1, \u0027ip\u0027: \u0027127.0.0.1\u0027}]"},{"line_number":927,"context_line":"            self.assertEqual(exp_sorted, app_sorted)"},{"line_number":928,"context_line":""},{"line_number":929,"context_line":"    def test_node_concurrecy(self):"},{"line_number":930,"context_line":"        nodes \u003d [{\u0027region\u0027: 1, \u0027zone\u0027: 1, \u0027ip\u0027: \u0027127.0.0.1\u0027, \u0027port\u0027: 6010,"},{"line_number":931,"context_line":"                  \u0027device\u0027: \u0027sda\u0027},"},{"line_number":932,"context_line":"                 {\u0027region\u0027: 2, \u0027zone\u0027: 2, \u0027ip\u0027: \u0027127.0.0.2\u0027, \u0027port\u0027: 6010,"}],"source_content_type":"text/x-python","patch_set":26,"id":"5aef4532_c723ffa5","line":929,"updated":"2016-03-09 16:09:31.000000000","message":"nit s/concurrecy/concurrency/","commit_id":"4d6d54f228001cd835e3abf6d8fca82d1fae562d"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"c25fb967237a2b9740687f5c73dd45a902ce23ae","unresolved":false,"context_lines":[{"line_number":926,"context_line":"                          {\u0027region\u0027: 2, \u0027zone\u0027: 1, \u0027ip\u0027: \u0027127.0.0.1\u0027}]"},{"line_number":927,"context_line":"            self.assertEqual(exp_sorted, app_sorted)"},{"line_number":928,"context_line":""},{"line_number":929,"context_line":"    def test_node_concurrecy(self):"},{"line_number":930,"context_line":"        nodes \u003d [{\u0027region\u0027: 1, \u0027zone\u0027: 1, \u0027ip\u0027: \u0027127.0.0.1\u0027, \u0027port\u0027: 6010,"},{"line_number":931,"context_line":"                  \u0027device\u0027: \u0027sda\u0027},"},{"line_number":932,"context_line":"                 {\u0027region\u0027: 2, \u0027zone\u0027: 2, \u0027ip\u0027: \u0027127.0.0.2\u0027, \u0027port\u0027: 6010,"}],"source_content_type":"text/x-python","patch_set":26,"id":"3afc51ec_40837556","line":929,"in_reply_to":"5aef4532_c723ffa5","updated":"2016-03-15 02:15:34.000000000","message":"Done","commit_id":"4d6d54f228001cd835e3abf6d8fca82d1fae562d"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"c25fb967237a2b9740687f5c73dd45a902ce23ae","unresolved":false,"context_lines":[{"line_number":935,"context_line":"                  \u0027device\u0027: \u0027sda\u0027}]"},{"line_number":936,"context_line":"        timings \u003d {\u0027127.0.0.1\u0027: 2, \u0027127.0.0.2\u0027: 1, \u0027127.0.0.3\u0027: 0}"},{"line_number":937,"context_line":"        statuses \u003d {\u0027127.0.0.1\u0027: 200, \u0027127.0.0.2\u0027: 200, \u0027127.0.0.3\u0027: 200}"},{"line_number":938,"context_line":"        req \u003d Request.blank(\u0027/v1/account\u0027, environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027GET\u0027})"},{"line_number":939,"context_line":""},{"line_number":940,"context_line":"        def fake_iter_nodes(*arg, **karg):"},{"line_number":941,"context_line":"            return iter(nodes)"}],"source_content_type":"text/x-python","patch_set":26,"id":"3afc51ec_00bb2d28","line":938,"updated":"2016-03-15 02:15:34.000000000","message":"I have a patch to context swift (rather then time) this test too, but clay has a follow up patch to speed and fix this test.. so will leave this off for now.","commit_id":"4d6d54f228001cd835e3abf6d8fca82d1fae562d"}]}
