)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":6198,"name":"Peter Portante","email":"peter.a.portante@gmail.com","username":"peter-a-portante"},"change_message_id":"8e1118d28fc70903325dd2d74bc3ee50afdaa998","unresolved":false,"context_lines":[{"line_number":22,"context_line":"other verbs ends up making concurrent requests to *all* the primary"},{"line_number":23,"context_line":"nodes, so ordering is irrelevant."},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"blueprint proxy-affinity"},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"Change-Id: Iea4cd367ed37fe5ee69b63234541d358d29963a4"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"AAAAPX%2F%2F3pY%3D","line":25,"updated":"2013-06-07 02:03:14.000000000","message":"Should this end up as a valid blue-print link in Gerrit?","commit_id":"6a21ff049a31f55f36be55a557450abd9767607a"},{"author":{"_account_id":2622,"name":"Samuel Merritt","email":"spam+launchpad@andcheese.org","username":"torgomatic"},"change_message_id":"e1371dcc47e0352fb484524986041183324d434c","unresolved":false,"context_lines":[{"line_number":22,"context_line":"other verbs ends up making concurrent requests to *all* the primary"},{"line_number":23,"context_line":"nodes, so ordering is irrelevant."},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"blueprint proxy-affinity"},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"Change-Id: Iea4cd367ed37fe5ee69b63234541d358d29963a4"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"AAAAPX%2F%2F3ic%3D","line":25,"in_reply_to":"AAAAPX%2F%2F3pY%3D","updated":"2013-06-07 03:38:44.000000000","message":"It should... I guess it doesn\u0027t, though. I\u0027ll just remove that.","commit_id":"6a21ff049a31f55f36be55a557450abd9767607a"}],"etc/proxy-server.conf-sample":[{"author":{"_account_id":6198,"name":"Peter Portante","email":"peter.a.portante@gmail.com","username":"peter-a-portante"},"change_message_id":"005f50766632356e49bfe4e4bbf3d6da4195538b","unresolved":false,"context_lines":[{"line_number":93,"context_line":"# Once segment rate-limiting kicks in for an object, limit segments served"},{"line_number":94,"context_line":"# to N per second."},{"line_number":95,"context_line":"# rate_limit_segments_per_sec \u003d 1"},{"line_number":96,"context_line":"# Storage nodes can be chosen at random (shuffle), by using timing"},{"line_number":97,"context_line":"# measurements (timing), or by using an explicit match (affinity)."},{"line_number":98,"context_line":"# Using timing measurements may allow for lower overall latency,"},{"line_number":99,"context_line":"# while using affinity allows for finer control."}],"source_content_type":"application/octet-stream","patch_set":3,"id":"AAAAPX%2F%2Fytg%3D","line":96,"updated":"2013-06-10 15:37:30.000000000","message":"The code appears to always shuffle, and then apply timing or affinity. Perhaps we should document it that way?","commit_id":"e1338894193c59cd9ac0fec79678c5e56cde44bf"},{"author":{"_account_id":2696,"name":"Darrell Bishop","email":"dbishop@nvidia.com","username":"darrellb"},"change_message_id":"64b55a49711eef38b5d872d72eef56c0addb5102","unresolved":false,"context_lines":[{"line_number":93,"context_line":"# Once segment rate-limiting kicks in for an object, limit segments served"},{"line_number":94,"context_line":"# to N per second."},{"line_number":95,"context_line":"# rate_limit_segments_per_sec \u003d 1"},{"line_number":96,"context_line":"# Storage nodes can be chosen at random (shuffle), by using timing"},{"line_number":97,"context_line":"# measurements (timing), or by using an explicit match (affinity)."},{"line_number":98,"context_line":"# Using timing measurements may allow for lower overall latency,"},{"line_number":99,"context_line":"# while using affinity allows for finer control."}],"source_content_type":"application/octet-stream","patch_set":3,"id":"AAAAPX%2F%2Fx1o%3D","line":96,"in_reply_to":"AAAAPX%2F%2Fytg%3D","updated":"2013-06-10 22:48:16.000000000","message":"This makes sense... the always-shuffle business (in combination with Python\u0027s stable sort) ensures that equally-sorting timing or read_affinity nodes will still have load distributed across them.\n\nI bring that up to mostly say that if we change the copy here, let\u0027s phrase it with respect to the (useful) effect it has, not the implementation detail that a shuffle is always applied prior to sorting for \"timing\" and \"affinity\".  Something like:\n\n  Storage nodes can be chosen at random (shuffle), by using timing\n  measurements (timing), or by using an explicit match (affinity).\n  Using timing measurements may allow for lower overall latency,\n  while using affinity allows for finer control.  In both the timing and\n  affinity cases, equally-sorting nodes are still randomly chosen to\n  spread load.","commit_id":"e1338894193c59cd9ac0fec79678c5e56cde44bf"}],"swift/common/utils.py":[{"author":{"_account_id":330,"name":"John Dickinson","email":"me@not.mn","username":"notmyname"},"change_message_id":"a988cb4f6557ac62acf84e68606f6ded4492b84b","unresolved":false,"context_lines":[{"line_number":1524,"context_line":"    return None"},{"line_number":1525,"context_line":""},{"line_number":1526,"context_line":""},{"line_number":1527,"context_line":"def affinity_key_function(affinity_str):"},{"line_number":1528,"context_line":"    if not affinity_str:"},{"line_number":1529,"context_line":"        return lambda x: 0"},{"line_number":1530,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAAPX%2F%2F1a0%3D","line":1527,"updated":"2013-06-08 00:08:50.000000000","message":"can you give a docstring here with an overview and explanation of the regex","commit_id":"ebac4011a318463988c3b20c39c4d0dbe74a49ec"}],"swift/proxy/server.py":[{"author":{"_account_id":6198,"name":"Peter Portante","email":"peter.a.portante@gmail.com","username":"peter-a-portante"},"change_message_id":"005f50766632356e49bfe4e4bbf3d6da4195538b","unresolved":false,"context_lines":[{"line_number":126,"context_line":"        else:"},{"line_number":127,"context_line":"            raise ValueError("},{"line_number":128,"context_line":"                \u0027Invalid request_node_count value: %r\u0027 % \u0027\u0027.join(value))"},{"line_number":129,"context_line":"        self.read_affinity_sort_key \u003d affinity_key_function("},{"line_number":130,"context_line":"            conf.get(\u0027read_affinity\u0027, \u0027\u0027))"},{"line_number":131,"context_line":"        if not self.read_affinity_sort_key:"},{"line_number":132,"context_line":"            raise ValueError(\"Invalid read_affinity setting: %r\" %"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAPX%2F%2Fywg%3D","line":129,"updated":"2013-06-10 15:37:30.000000000","message":"This is niggly, but to avoid test and take action patterns, how \u0027bout have affinity_key_function raise a ValueError instead of returning None, and then doing:\n\n read_affinity_str \u003d conf.get(\u0027read_affinity\u0027, \u0027\u0027)\n try:\n     self.read_affinity_sort_key \u003d affinity_key_function(read_affinity_str)\n except ValueError:\n     raise ValueError(\"Invalid read affinity setting: %r\" % read_affinity_str)","commit_id":"e1338894193c59cd9ac0fec79678c5e56cde44bf"},{"author":{"_account_id":2622,"name":"Samuel Merritt","email":"spam+launchpad@andcheese.org","username":"torgomatic"},"change_message_id":"3ea43274af87323d039da8889b66a650033ce088","unresolved":false,"context_lines":[{"line_number":126,"context_line":"        else:"},{"line_number":127,"context_line":"            raise ValueError("},{"line_number":128,"context_line":"                \u0027Invalid request_node_count value: %r\u0027 % \u0027\u0027.join(value))"},{"line_number":129,"context_line":"        self.read_affinity_sort_key \u003d affinity_key_function("},{"line_number":130,"context_line":"            conf.get(\u0027read_affinity\u0027, \u0027\u0027))"},{"line_number":131,"context_line":"        if not self.read_affinity_sort_key:"},{"line_number":132,"context_line":"            raise ValueError(\"Invalid read_affinity setting: %r\" %"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAPX%2F%2FyT0%3D","line":129,"in_reply_to":"AAAAPX%2F%2Fywg%3D","updated":"2013-06-10 18:03:29.000000000","message":"Sure, I can do that.","commit_id":"e1338894193c59cd9ac0fec79678c5e56cde44bf"},{"author":{"_account_id":6198,"name":"Peter Portante","email":"peter.a.portante@gmail.com","username":"peter-a-portante"},"change_message_id":"005f50766632356e49bfe4e4bbf3d6da4195538b","unresolved":false,"context_lines":[{"line_number":284,"context_line":"                return timing if expires \u003e now else -1.0"},{"line_number":285,"context_line":"            nodes.sort(key\u003dkey_func)"},{"line_number":286,"context_line":"        elif self.sorting_method \u003d\u003d \u0027affinity\u0027:"},{"line_number":287,"context_line":"            nodes.sort(key\u003dself.read_affinity_sort_key)"},{"line_number":288,"context_line":"        return nodes"},{"line_number":289,"context_line":""},{"line_number":290,"context_line":"    def set_node_timing(self, node, timing):"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAPX%2F%2Fyvc%3D","line":287,"updated":"2013-06-10 15:37:30.000000000","message":"Is it worth folding in the node timings as a sub-sort?","commit_id":"e1338894193c59cd9ac0fec79678c5e56cde44bf"},{"author":{"_account_id":2622,"name":"Samuel Merritt","email":"spam+launchpad@andcheese.org","username":"torgomatic"},"change_message_id":"3ea43274af87323d039da8889b66a650033ce088","unresolved":false,"context_lines":[{"line_number":284,"context_line":"                return timing if expires \u003e now else -1.0"},{"line_number":285,"context_line":"            nodes.sort(key\u003dkey_func)"},{"line_number":286,"context_line":"        elif self.sorting_method \u003d\u003d \u0027affinity\u0027:"},{"line_number":287,"context_line":"            nodes.sort(key\u003dself.read_affinity_sort_key)"},{"line_number":288,"context_line":"        return nodes"},{"line_number":289,"context_line":""},{"line_number":290,"context_line":"    def set_node_timing(self, node, timing):"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAAPX%2F%2FyTk%3D","line":287,"in_reply_to":"AAAAPX%2F%2Fyvc%3D","updated":"2013-06-10 18:03:29.000000000","message":"I feel like that\u0027d be a different setting in the config, and I\u0027m not sure what it would look like.","commit_id":"e1338894193c59cd9ac0fec79678c5e56cde44bf"}]}
