)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":6968,"name":"Christian Schwede","email":"cschwede@nvidia.com","username":"cschwede"},"change_message_id":"577d76fe54b89537125c9043f192f9c80f228676","unresolved":false,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Write-affinity aware object deletion"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"When deleting objects in multi-region swift delpoyment with write"},{"line_number":10,"context_line":"affinity configured, users always get 404 when deleting object before"},{"line_number":11,"context_line":"it\u0027s replcated to approriate nodes."},{"line_number":12,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":12,"id":"3f1d235d_2d2a6c8f","line":9,"updated":"2017-07-04 09:49:28.000000000","message":"nit: delpoyment -\u003e deployment","commit_id":"831eb6e3ce317d8209178dd7e4dee509edd179cf"}],"doc/source/deployment_guide.rst":[{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"bbb5480f40ec6f5b55ef49f907b96e1c9214e3c9","unresolved":false,"context_lines":[{"line_number":1908,"context_line":"    read_affinity \u003d r2\u003d1"},{"line_number":1909,"context_line":"    write_affinity \u003d r2"},{"line_number":1910,"context_line":"    write_affinity_node_count \u003d 1 * replicas"},{"line_number":1911,"context_line":"    write_affinity_handoff_delete_count \u003d 2"},{"line_number":1912,"context_line":""},{"line_number":1913,"context_line":".. note::"},{"line_number":1914,"context_line":""}],"source_content_type":"text/x-rst","patch_set":12,"id":"3f1d235d_9284a2d4","line":1911,"updated":"2017-07-06 12:24:11.000000000","message":"I\u0027d probably default this to auto but I guess its still an example","commit_id":"831eb6e3ce317d8209178dd7e4dee509edd179cf"}],"etc/proxy-server.conf-sample":[{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"588c810e3bc975cf6b194ff28f12491d8e18ca02","unresolved":false,"context_lines":[{"line_number":246,"context_line":"# request when deleting object could help make correct decision for the"},{"line_number":247,"context_line":"# response."},{"line_number":248,"context_line":"# This option may be overridden in a per-policy configuration section."},{"line_number":249,"context_line":"# write_affinity_handoff_delete_count \u003d 2"},{"line_number":250,"context_line":"#"},{"line_number":251,"context_line":"# These are the headers whose values will only be shown to swift_owners. The"},{"line_number":252,"context_line":"# exact definition of a swift_owner is up to the auth system in use, but"}],"source_content_type":"application/octet-stream","patch_set":5,"id":"7f231b9d_5ba469b9","line":249,"updated":"2017-06-13 12:04:29.000000000","message":"Is 2, the right default here?\n\nI guess I\u0027m wondering, why have 2 options? if someone has write affinity on.. maybe we should have write affinity for deletes on as well? Do we really need 2 options.\n\nIs there a real problem if the delete affinity is also 2 * replicas by default?, ok do it might check 6 nodes on a 3 replica policy, but is that so bad.\n\nIf we do have it as another option why is the default 2 and not something that would be replica dependant, that is grows with the replica count like write affinity (* replica)","commit_id":"65c91cb1844565f54742ccd002ee57a6de7cb459"},{"author":{"_account_id":6732,"name":"Lingxian Kong","email":"anlin.kong@gmail.com","username":"kong"},"change_message_id":"45208711798b210972055d4f638ac2b0ea88dfe0","unresolved":false,"context_lines":[{"line_number":246,"context_line":"# request when deleting object could help make correct decision for the"},{"line_number":247,"context_line":"# response."},{"line_number":248,"context_line":"# This option may be overridden in a per-policy configuration section."},{"line_number":249,"context_line":"# write_affinity_handoff_delete_count \u003d 2"},{"line_number":250,"context_line":"#"},{"line_number":251,"context_line":"# These are the headers whose values will only be shown to swift_owners. The"},{"line_number":252,"context_line":"# exact definition of a swift_owner is up to the auth system in use, but"}],"source_content_type":"application/octet-stream","patch_set":5,"id":"7f231b9d_b056de5b","line":249,"in_reply_to":"7f231b9d_5ba469b9","updated":"2017-06-14 03:28:14.000000000","message":"Hmm...valid question, Matthew.\n\nThink again, I think I will remove this option, and get the max handoff delete count \u003d replica - 1, what do you think?","commit_id":"65c91cb1844565f54742ccd002ee57a6de7cb459"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"86d660ff095474877b632e656cac0261a44b9257","unresolved":false,"context_lines":[{"line_number":246,"context_line":"# request when deleting object could help make correct decision for the"},{"line_number":247,"context_line":"# response."},{"line_number":248,"context_line":"# This option may be overridden in a per-policy configuration section."},{"line_number":249,"context_line":"# write_affinity_handoff_delete_count \u003d 2"},{"line_number":250,"context_line":"#"},{"line_number":251,"context_line":"# These are the headers whose values will only be shown to swift_owners. The"},{"line_number":252,"context_line":"# exact definition of a swift_owner is up to the auth system in use, but"}],"source_content_type":"application/octet-stream","patch_set":5,"id":"7f231b9d_f928c134","line":249,"in_reply_to":"7f231b9d_931d2c11","updated":"2017-06-14 05:56:00.000000000","message":"If we decide its better to have another option for Ops to tune, then cool. Based on what your saying this number could really be deployment specific.\n\nI\u0027d assume if you set write affinity then you\u0027d also want write (delete) affinity. How about if the default is whatever the write affinity is (default \u003d write_affinity_node_count)? That way in most cases operators only need 1 value to set.. if however they need override this and we decide it is it\u0027s own tunable.. then it can be overridden.\n\nStill not 100% convinced it needs to be another tunable setting, but not against it. I just want to make the default expected and easy to understand.","commit_id":"65c91cb1844565f54742ccd002ee57a6de7cb459"},{"author":{"_account_id":6732,"name":"Lingxian Kong","email":"anlin.kong@gmail.com","username":"kong"},"change_message_id":"b5908ba1e8338c0183932c3bfb5695feb0a7f9aa","unresolved":false,"context_lines":[{"line_number":246,"context_line":"# request when deleting object could help make correct decision for the"},{"line_number":247,"context_line":"# response."},{"line_number":248,"context_line":"# This option may be overridden in a per-policy configuration section."},{"line_number":249,"context_line":"# write_affinity_handoff_delete_count \u003d 2"},{"line_number":250,"context_line":"#"},{"line_number":251,"context_line":"# These are the headers whose values will only be shown to swift_owners. The"},{"line_number":252,"context_line":"# exact definition of a swift_owner is up to the auth system in use, but"}],"source_content_type":"application/octet-stream","patch_set":5,"id":"7f231b9d_931d2c11","line":249,"in_reply_to":"7f231b9d_b056de5b","updated":"2017-06-14 03:54:47.000000000","message":"Hi, Matthew, on second thoughts, I still have some concerns if we remove this option or make the number vary with replica number.\n\nreplica -1 is not always correct. The nodes are chosen according to many factors in different deployment, the region number, replica number, node weight, etc. E.g in a 2 regions deployment with 5 replicas, if there are 2 primary nodes in region 1 and 3 primary nodes in region 2, the actual preferred write_affinity_handoff_delete_count should be 3 instead of 4(5-1), but in a 3 regions deployment with 5 replicas, there may be 2 primaries in both region1 and region2, 1 primary in region3, the preferred  write_affinity_handoff_delete_count should be 2.\n\nSo, it\u0027s up to operators to decide what number they want to config and   if the number is equal for different regions as well.\n\nI will not try to change it until we have a better solution.","commit_id":"65c91cb1844565f54742ccd002ee57a6de7cb459"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"9fc8e9b65a02c005fdcfef3bc6c9ad08aaea7cc3","unresolved":false,"context_lines":[{"line_number":246,"context_line":"# request when deleting object could help make correct decision for the"},{"line_number":247,"context_line":"# response."},{"line_number":248,"context_line":"# This option may be overridden in a per-policy configuration section."},{"line_number":249,"context_line":"# write_affinity_handoff_delete_count \u003d 2"},{"line_number":250,"context_line":"#"},{"line_number":251,"context_line":"# These are the headers whose values will only be shown to swift_owners. The"},{"line_number":252,"context_line":"# exact definition of a swift_owner is up to the auth system in use, but"}],"source_content_type":"application/octet-stream","patch_set":7,"id":"7f231b9d_599a156e","line":249,"updated":"2017-06-14 05:58:28.000000000","message":"As to be sure to continue the discussions and now one else misses (in case their interested) this is the last comment I made (from patchset 5):\n\nIf we decide its better to have another option for Ops to tune, then cool. Based on what your saying this number could really be deployment specific.\n\nI\u0027d assume if you set write affinity then you\u0027d also want write (delete) affinity. How about if the default is whatever the write affinity is (default \u003d write_affinity_node_count)? That way in most cases operators only need 1 value to set.. if however they need override this and we decide it is it\u0027s own tunable.. then it can be overridden.\n\nStill not 100% convinced it needs to be another tunable setting, but not against it. I just want to make the default expected and easy to understand.","commit_id":"59c9babf4ea2ea8700a8b4f1b38c4ca7498806dd"},{"author":{"_account_id":6732,"name":"Lingxian Kong","email":"anlin.kong@gmail.com","username":"kong"},"change_message_id":"e7794ceededda85b8c4020d8b3cd66268bd12e78","unresolved":false,"context_lines":[{"line_number":246,"context_line":"# request when deleting object could help make correct decision for the"},{"line_number":247,"context_line":"# response."},{"line_number":248,"context_line":"# This option may be overridden in a per-policy configuration section."},{"line_number":249,"context_line":"# write_affinity_handoff_delete_count \u003d 2"},{"line_number":250,"context_line":"#"},{"line_number":251,"context_line":"# These are the headers whose values will only be shown to swift_owners. The"},{"line_number":252,"context_line":"# exact definition of a swift_owner is up to the auth system in use, but"}],"source_content_type":"application/octet-stream","patch_set":7,"id":"7f231b9d_ee11f15e","line":249,"in_reply_to":"7f231b9d_599a156e","updated":"2017-06-15 03:17:32.000000000","message":"Hi, Matthew,\n\nI made a change according to our discussion. The write_affinity_handoff_delete_count option is still there but is given a default value 0, which means it depends on swift to calculate the handoffs number for object deletion. Please see the option description for more details.\n\nIn this way, the default value makes sense for most of the deployments and can also be tweaked as required.","commit_id":"59c9babf4ea2ea8700a8b4f1b38c4ca7498806dd"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"24267e6359887310f93ac203c7ae2f10ee8f4ee5","unresolved":false,"context_lines":[{"line_number":247,"context_line":"# response. The default value 0 means Swift will calculate the number"},{"line_number":248,"context_line":"# automatically, the default value is (replicas - len(local_primary_nodes))."},{"line_number":249,"context_line":"# This option may be overridden in a per-policy configuration section."},{"line_number":250,"context_line":"# write_affinity_handoff_delete_count \u003d 0"},{"line_number":251,"context_line":"#"},{"line_number":252,"context_line":"# These are the headers whose values will only be shown to swift_owners. The"},{"line_number":253,"context_line":"# exact definition of a swift_owner is up to the auth system in use, but"}],"source_content_type":"application/octet-stream","patch_set":10,"id":"5f201791_88318ca5","line":250,"updated":"2017-06-22 23:53:06.000000000","message":"oh, i ment to say this was missing form the per-policy config section below","commit_id":"d7a365f705fd9a80b1abdf7e88bb27fb249ec1f2"}],"swift/proxy/controllers/base.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"a2a88daf4b963d2e3e1a4aca03cfee45189b5158","unresolved":false,"context_lines":[{"line_number":1623,"context_line":"        )"},{"line_number":1624,"context_line":""},{"line_number":1625,"context_line":"        primary_nodes \u003d ring.get_part_nodes(part)"},{"line_number":1626,"context_line":"        node_count \u003d node_count or len(primary_nodes)"},{"line_number":1627,"context_line":"        pile \u003d GreenAsyncPile(node_count)"},{"line_number":1628,"context_line":""},{"line_number":1629,"context_line":"        for head in headers:"}],"source_content_type":"text/x-python","patch_set":1,"id":"df140735_ff6ab317","line":1626,"updated":"2017-06-02 17:12:06.000000000","message":"i find this more clear:\n\n    node_count \u003d node_count or len(ring.get_part_nodes(part))\n\nThe existence of both the nodes/node_iterator *and* primary_nodes in the locals() of this function feels unsettling - like a bug waiting to happen.\n\n    node_iter \u003d passed_in or make_one\n    node_count \u003d passed_in or make_one\n\nas long as the \"make_one\" part doesn\u0027t exist beyond these statements any attempt to use it else where would require a diff to touch these lines.","commit_id":"072895e9888088f2b51468a8675094a9fd91ef47"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"5f1676fc75c1946bcdfc548e9ceb2d44083a73a7","unresolved":false,"context_lines":[{"line_number":1615,"context_line":"        :param overrides: optional return status override map used to override"},{"line_number":1616,"context_line":"                          the returned status of a request."},{"line_number":1617,"context_line":"        :param node_count: optional number of nodes to send request to."},{"line_number":1618,"context_line":"        :param node_iterator: optional node iterator."},{"line_number":1619,"context_line":"        :returns: a swob.Response object"},{"line_number":1620,"context_line":"        \"\"\""},{"line_number":1621,"context_line":"        nodes \u003d GreenthreadSafeIterator("}],"source_content_type":"text/x-python","patch_set":5,"id":"bf091321_ffd81080","line":1618,"updated":"2017-06-07 23:46:05.000000000","message":"I love this change - I think it\u0027s a sensible and effective extension of this method - kudos","commit_id":"65c91cb1844565f54742ccd002ee57a6de7cb459"},{"author":{"_account_id":6732,"name":"Lingxian Kong","email":"anlin.kong@gmail.com","username":"kong"},"change_message_id":"fc448bf5eccdb31a92ac14b61bdc20513822c258","unresolved":false,"context_lines":[{"line_number":1615,"context_line":"        :param overrides: optional return status override map used to override"},{"line_number":1616,"context_line":"                          the returned status of a request."},{"line_number":1617,"context_line":"        :param node_count: optional number of nodes to send request to."},{"line_number":1618,"context_line":"        :param node_iterator: optional node iterator."},{"line_number":1619,"context_line":"        :returns: a swob.Response object"},{"line_number":1620,"context_line":"        \"\"\""},{"line_number":1621,"context_line":"        nodes \u003d GreenthreadSafeIterator("}],"source_content_type":"text/x-python","patch_set":5,"id":"7f231b9d_dfe89e17","line":1618,"in_reply_to":"bf091321_ffd81080","updated":"2017-06-12 03:51:54.000000000","message":"thanks!","commit_id":"65c91cb1844565f54742ccd002ee57a6de7cb459"}],"swift/proxy/controllers/obj.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"a2a88daf4b963d2e3e1a4aca03cfee45189b5158","unresolved":false,"context_lines":[{"line_number":167,"context_line":"        return self.app.iter_nodes("},{"line_number":168,"context_line":"            ring, partition, node_iter\u003dlocal_first_node_iter, policy\u003dpolicy)"},{"line_number":169,"context_line":""},{"line_number":170,"context_line":"    def iter_nodes_handoff_local(self, ring, partition, policy\u003dNone):"},{"line_number":171,"context_line":"        \"\"\""},{"line_number":172,"context_line":"        Yields nodes for a ring partition."},{"line_number":173,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"df140735_1f056746","line":170,"updated":"2017-06-02 17:12:06.000000000","message":"I would much prefer to see iter_nodes_local_first grow a \"num_locals\" param/kwarg than nearly it\u0027s entire body duplicated here.","commit_id":"072895e9888088f2b51468a8675094a9fd91ef47"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"a2a88daf4b963d2e3e1a4aca03cfee45189b5158","unresolved":false,"context_lines":[{"line_number":961,"context_line":""},{"line_number":962,"context_line":"            node_iterator \u003d self.iter_nodes_handoff_local("},{"line_number":963,"context_line":"                obj_ring, partition, policy\u003dpolicy"},{"line_number":964,"context_line":"            )"},{"line_number":965,"context_line":""},{"line_number":966,"context_line":"        status_overrides \u003d {404: 204}"},{"line_number":967,"context_line":"        resp \u003d self.make_requests(req, obj_ring,"}],"source_content_type":"text/x-python","patch_set":1,"id":"df140735_ff74f3d0","line":964,"updated":"2017-06-02 17:12:06.000000000","message":"IMHO there is currently no difference between the DELETE methods of EC and Replicated policies nor does there need to be.  These changes are benign when write_affinity is not configured for the policy and their value/reasoning apply equally to any policy using write affinity.  Can you please just move these changes to the _delete_object method in the BaseObjectController","commit_id":"072895e9888088f2b51468a8675094a9fd91ef47"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"5f1676fc75c1946bcdfc548e9ceb2d44083a73a7","unresolved":false,"context_lines":[{"line_number":145,"context_line":"        :param policy: optional, an instance of :class:`BaseStoragePolicy"},{"line_number":146,"context_line":"        :param handoff_only: optional, if True only get local handoff nodes"},{"line_number":147,"context_line":"            and all primary nodes, otherwise get local nodes from all primary"},{"line_number":148,"context_line":"            and handoff nodes."},{"line_number":149,"context_line":"        \"\"\""},{"line_number":150,"context_line":"        policy_options \u003d self.app.get_policy_options(policy)"},{"line_number":151,"context_line":"        is_local \u003d policy_options.write_affinity_is_local_fn"}],"source_content_type":"text/x-python","patch_set":5,"id":"bf091321_9f36b4b4","line":148,"updated":"2017-06-07 23:46:05.000000000","message":"so it\u0027s more like... skip_primary_already_local","commit_id":"65c91cb1844565f54742ccd002ee57a6de7cb459"},{"author":{"_account_id":6732,"name":"Lingxian Kong","email":"anlin.kong@gmail.com","username":"kong"},"change_message_id":"45208711798b210972055d4f638ac2b0ea88dfe0","unresolved":false,"context_lines":[{"line_number":145,"context_line":"        :param policy: optional, an instance of :class:`BaseStoragePolicy"},{"line_number":146,"context_line":"        :param handoff_only: optional, if True only get local handoff nodes"},{"line_number":147,"context_line":"            and all primary nodes, otherwise get local nodes from all primary"},{"line_number":148,"context_line":"            and handoff nodes."},{"line_number":149,"context_line":"        \"\"\""},{"line_number":150,"context_line":"        policy_options \u003d self.app.get_policy_options(policy)"},{"line_number":151,"context_line":"        is_local \u003d policy_options.write_affinity_is_local_fn"}],"source_content_type":"text/x-python","patch_set":5,"id":"7f231b9d_30c88e20","line":148,"in_reply_to":"7f231b9d_804ccc9e","updated":"2017-06-14 03:28:14.000000000","message":"thanks for the suggestion, will make a change :)","commit_id":"65c91cb1844565f54742ccd002ee57a6de7cb459"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"588c810e3bc975cf6b194ff28f12491d8e18ca02","unresolved":false,"context_lines":[{"line_number":145,"context_line":"        :param policy: optional, an instance of :class:`BaseStoragePolicy"},{"line_number":146,"context_line":"        :param handoff_only: optional, if True only get local handoff nodes"},{"line_number":147,"context_line":"            and all primary nodes, otherwise get local nodes from all primary"},{"line_number":148,"context_line":"            and handoff nodes."},{"line_number":149,"context_line":"        \"\"\""},{"line_number":150,"context_line":"        policy_options \u003d self.app.get_policy_options(policy)"},{"line_number":151,"context_line":"        is_local \u003d policy_options.write_affinity_is_local_fn"}],"source_content_type":"text/x-python","patch_set":5,"id":"7f231b9d_804ccc9e","line":148,"in_reply_to":"7f231b9d_df5f7ee3","updated":"2017-06-13 12:04:29.000000000","message":"Maybe something like local_handoffs_first as this is what it says and does. Get primaries and local handoffs then everything else.\n\n  :param local_handoffs_first: optional, if True prefer\n      primaries and local handoff nodes first before looking \n      elsewhere.","commit_id":"65c91cb1844565f54742ccd002ee57a6de7cb459"},{"author":{"_account_id":6732,"name":"Lingxian Kong","email":"anlin.kong@gmail.com","username":"kong"},"change_message_id":"fc448bf5eccdb31a92ac14b61bdc20513822c258","unresolved":false,"context_lines":[{"line_number":145,"context_line":"        :param policy: optional, an instance of :class:`BaseStoragePolicy"},{"line_number":146,"context_line":"        :param handoff_only: optional, if True only get local handoff nodes"},{"line_number":147,"context_line":"            and all primary nodes, otherwise get local nodes from all primary"},{"line_number":148,"context_line":"            and handoff nodes."},{"line_number":149,"context_line":"        \"\"\""},{"line_number":150,"context_line":"        policy_options \u003d self.app.get_policy_options(policy)"},{"line_number":151,"context_line":"        is_local \u003d policy_options.write_affinity_is_local_fn"}],"source_content_type":"text/x-python","patch_set":5,"id":"7f231b9d_df5f7ee3","line":148,"in_reply_to":"bf091321_9f36b4b4","updated":"2017-06-12 03:51:54.000000000","message":"Actually, I have been trying to give a proper name to this flag, denoting that it will get all primary nodes and local handoff nodes. any other suggestion for the name?","commit_id":"65c91cb1844565f54742ccd002ee57a6de7cb459"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"5f1676fc75c1946bcdfc548e9ceb2d44083a73a7","unresolved":false,"context_lines":[{"line_number":161,"context_line":"            first_local_handoffs \u003d list(itertools.islice("},{"line_number":162,"context_line":"                (node for node in handoff_nodes if is_local(node)), num_locals)"},{"line_number":163,"context_line":"            )"},{"line_number":164,"context_line":"            preferred_nodes \u003d primary_nodes + first_local_handoffs"},{"line_number":165,"context_line":"        else:"},{"line_number":166,"context_line":"            num_locals \u003d policy_options.write_affinity_node_count_fn("},{"line_number":167,"context_line":"                len(primary_nodes)"}],"source_content_type":"text/x-python","patch_set":5,"id":"bf091321_7f09a0db","line":164,"updated":"2017-06-07 23:46:05.000000000","message":"is it *that* important that the order work this way?\n\n    [local_primary1, remote_primary2, remote_primary3, local_handoff1, local_handoff2]\n\nvs.\n\n    [local_primary1, local_handoff1, local_handoff2, remote_primary2, remote_primary3]\n\n???\n\nperhaps I\u0027m mis-understanding this implementation vs. what\u0027s there already?","commit_id":"65c91cb1844565f54742ccd002ee57a6de7cb459"},{"author":{"_account_id":6732,"name":"Lingxian Kong","email":"anlin.kong@gmail.com","username":"kong"},"change_message_id":"fc448bf5eccdb31a92ac14b61bdc20513822c258","unresolved":false,"context_lines":[{"line_number":161,"context_line":"            first_local_handoffs \u003d list(itertools.islice("},{"line_number":162,"context_line":"                (node for node in handoff_nodes if is_local(node)), num_locals)"},{"line_number":163,"context_line":"            )"},{"line_number":164,"context_line":"            preferred_nodes \u003d primary_nodes + first_local_handoffs"},{"line_number":165,"context_line":"        else:"},{"line_number":166,"context_line":"            num_locals \u003d policy_options.write_affinity_node_count_fn("},{"line_number":167,"context_line":"                len(primary_nodes)"}],"source_content_type":"text/x-python","patch_set":5,"id":"7f231b9d_8471b9e3","line":164,"in_reply_to":"bf091321_7f09a0db","updated":"2017-06-12 03:51:54.000000000","message":"I don\u0027t know if the order here is important. Before replication, it\u0027s better we send request to local nodes first, but after replication, sending to primary nodes is preferred.\n\nNot sure if what I understand is correct.","commit_id":"65c91cb1844565f54742ccd002ee57a6de7cb459"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"5f1676fc75c1946bcdfc548e9ceb2d44083a73a7","unresolved":false,"context_lines":[{"line_number":766,"context_line":"        policy_options \u003d self.app.get_policy_options(policy)"},{"line_number":767,"context_line":"        is_local \u003d policy_options.write_affinity_is_local_fn"},{"line_number":768,"context_line":"        if is_local is not None:"},{"line_number":769,"context_line":"            node_count +\u003d policy_options.write_affinity_handoff_delete_count"},{"line_number":770,"context_line":""},{"line_number":771,"context_line":"        headers \u003d self._backend_requests("},{"line_number":772,"context_line":"            req, node_count, container_partition, container_nodes)"}],"source_content_type":"text/x-python","patch_set":5,"id":"bf091321_dfb78c3a","line":769,"updated":"2017-06-07 23:46:05.000000000","message":"I\u0027m uncertain about this option being neutered if you don\u0027t also have write_affinity turned on...\n\nwhat happens if this +\u003d is not conditional","commit_id":"65c91cb1844565f54742ccd002ee57a6de7cb459"},{"author":{"_account_id":6732,"name":"Lingxian Kong","email":"anlin.kong@gmail.com","username":"kong"},"change_message_id":"fc448bf5eccdb31a92ac14b61bdc20513822c258","unresolved":false,"context_lines":[{"line_number":766,"context_line":"        policy_options \u003d self.app.get_policy_options(policy)"},{"line_number":767,"context_line":"        is_local \u003d policy_options.write_affinity_is_local_fn"},{"line_number":768,"context_line":"        if is_local is not None:"},{"line_number":769,"context_line":"            node_count +\u003d policy_options.write_affinity_handoff_delete_count"},{"line_number":770,"context_line":""},{"line_number":771,"context_line":"        headers \u003d self._backend_requests("},{"line_number":772,"context_line":"            req, node_count, container_partition, container_nodes)"}],"source_content_type":"text/x-python","patch_set":5,"id":"7f231b9d_9fa4660a","line":769,"in_reply_to":"bf091321_dfb78c3a","updated":"2017-06-12 03:51:54.000000000","message":"Hmm...you are right. This option only make sense only if \u0027write-affinity\u0027 is enabled, just like \u0027write_affinity_node_count\u0027 option. If \u0027write-affinity\u0027 is disabled, we don\u0027t want to take local handoff nodes into consideration.","commit_id":"65c91cb1844565f54742ccd002ee57a6de7cb459"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"018a701659578455eca3ca022a65dd1bd9fa194c","unresolved":false,"context_lines":[{"line_number":157,"context_line":""},{"line_number":158,"context_line":"        if local_handoffs_first:"},{"line_number":159,"context_line":"            num_locals \u003d policy_options.write_affinity_handoff_delete_count"},{"line_number":160,"context_line":"            if num_locals \u003d\u003d 0:"},{"line_number":161,"context_line":"                local_primaries \u003d [node for node in primary_nodes"},{"line_number":162,"context_line":"                                   if is_local(node)]"},{"line_number":163,"context_line":"                num_locals \u003d len(primary_nodes) - len(local_primaries)"},{"line_number":164,"context_line":""},{"line_number":165,"context_line":"            first_local_handoffs \u003d list(itertools.islice("},{"line_number":166,"context_line":"                (node for node in handoff_nodes if is_local(node)), num_locals)"}],"source_content_type":"text/x-python","patch_set":10,"id":"5f201791_9c8ce0d7","line":163,"range":{"start_line":160,"start_character":12,"end_line":163,"end_character":70},"updated":"2017-06-27 00:38:22.000000000","message":"clay: it looks like Lingxian is already doing that on a delete_count of 0.\n\nIf it\u0027s zero the num_locals becomes the len(primary_nodes) - len(local_primaries). So on a 0, num locals ins\u0027t in fact.. well 0.\n\nI think this is actually what we want the default to be. However, I think this means the default of 0 is misleading, it really should be a default of nothing (or again auto). Then a:\n\n  if policy_options.write_affinity_handoff_delete_count is None:\n    \u003cdo the awesome\u003e\n\nCurrently as a user, I\u0027d think if I set delete affinity count to 0, it shouldn\u0027t contact any locals, but in fact it is hitting len(primaries) + (number of non local primaries).. which isn\u0027t 0. So a default of zero is wrong. it seems a default of None or auto would be better... but other then that I think all the hard work has already been done!","commit_id":"d7a365f705fd9a80b1abdf7e88bb27fb249ec1f2"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"674dd69bcbf8c785869582a36ac547394874b9a0","unresolved":false,"context_lines":[{"line_number":631,"context_line":"        is_local \u003d policy_options.write_affinity_is_local_fn"},{"line_number":632,"context_line":"        if is_local is not None:"},{"line_number":633,"context_line":"            node_count \u003d len(obj_ring.get_part_nodes(partition))"},{"line_number":634,"context_line":"            node_count +\u003d policy_options.write_affinity_handoff_delete_count"},{"line_number":635,"context_line":""},{"line_number":636,"context_line":"            node_iterator \u003d self.iter_nodes_local_first("},{"line_number":637,"context_line":"                obj_ring, partition, policy\u003dpolicy, local_handoffs_first\u003dTrue"}],"source_content_type":"text/x-python","patch_set":10,"id":"5f201791_d7da3376","line":634,"range":{"start_line":634,"start_character":12,"end_line":634,"end_character":22},"updated":"2017-06-27 01:04:50.000000000","message":"and this needs to not incremented with the delete_count (0) or non, but with (len(primary_nodes) - (len(non local primary nodes))","commit_id":"d7a365f705fd9a80b1abdf7e88bb27fb249ec1f2"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"c2e8f7721dd17c7120293db7b75d64a48de67468","unresolved":false,"context_lines":[{"line_number":631,"context_line":"        is_local \u003d policy_options.write_affinity_is_local_fn"},{"line_number":632,"context_line":"        if is_local is not None:"},{"line_number":633,"context_line":"            node_count \u003d len(obj_ring.get_part_nodes(partition))"},{"line_number":634,"context_line":"            node_count +\u003d policy_options.write_affinity_handoff_delete_count"},{"line_number":635,"context_line":""},{"line_number":636,"context_line":"            node_iterator \u003d self.iter_nodes_local_first("},{"line_number":637,"context_line":"                obj_ring, partition, policy\u003dpolicy, local_handoffs_first\u003dTrue"}],"source_content_type":"text/x-python","patch_set":10,"id":"5f201791_974efb35","line":634,"range":{"start_line":634,"start_character":12,"end_line":634,"end_character":22},"in_reply_to":"5f201791_d7da3376","updated":"2017-06-27 01:11:31.000000000","message":"I mean:\n\n  len(primary) - len(local primaries)\n\nApparently not working has made my maths skill atrophy :P","commit_id":"d7a365f705fd9a80b1abdf7e88bb27fb249ec1f2"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"bbb5480f40ec6f5b55ef49f907b96e1c9214e3c9","unresolved":false,"context_lines":[{"line_number":781,"context_line":"            local_handoffs \u003d policy_options.write_affinity_handoff_delete_count"},{"line_number":782,"context_line":"            if local_handoffs is None:"},{"line_number":783,"context_line":"                local_primaries \u003d [node for node in nodes if is_local(node)]"},{"line_number":784,"context_line":"                local_handoffs \u003d len(nodes) - len(local_primaries)"},{"line_number":785,"context_line":"            node_count +\u003d local_handoffs"},{"line_number":786,"context_line":""},{"line_number":787,"context_line":"        headers \u003d self._backend_requests("}],"source_content_type":"text/x-python","patch_set":12,"id":"3f1d235d_327f0eac","line":784,"updated":"2017-07-06 12:24:11.000000000","message":"this could almost be a helper function as it\u0027s repeated.. but only twice and it\u0027s only really a few lines... so not a blocker","commit_id":"831eb6e3ce317d8209178dd7e4dee509edd179cf"}],"swift/proxy/server.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"5f1676fc75c1946bcdfc548e9ceb2d44083a73a7","unresolved":false,"context_lines":[{"line_number":151,"context_line":"            \u0027read_affinity\u0027,"},{"line_number":152,"context_line":"            \u0027write_affinity\u0027,"},{"line_number":153,"context_line":"            \u0027write_affinity_node_count\u0027,"},{"line_number":154,"context_line":"            \u0027write_affinity_handoff_delete_count\u0027))"},{"line_number":155,"context_line":""},{"line_number":156,"context_line":""},{"line_number":157,"context_line":"class Application(object):"}],"source_content_type":"text/x-python","patch_set":5,"id":"bf091321_bf46184f","line":154,"updated":"2017-06-07 23:46:05.000000000","message":"UNRELATED: we have *got* to figure out a sane way to dig ourselves out of the hole of updating this every-time we want to add a new per-policy config option?\n\n   self.set_option(\u0027name_of_attr\u0027, massage_value_from_conf(get(\u0027name_of_attr\u0027))\n\nmaybe a helper to track some state?","commit_id":"65c91cb1844565f54742ccd002ee57a6de7cb459"},{"author":{"_account_id":6732,"name":"Lingxian Kong","email":"anlin.kong@gmail.com","username":"kong"},"change_message_id":"fc448bf5eccdb31a92ac14b61bdc20513822c258","unresolved":false,"context_lines":[{"line_number":151,"context_line":"            \u0027read_affinity\u0027,"},{"line_number":152,"context_line":"            \u0027write_affinity\u0027,"},{"line_number":153,"context_line":"            \u0027write_affinity_node_count\u0027,"},{"line_number":154,"context_line":"            \u0027write_affinity_handoff_delete_count\u0027))"},{"line_number":155,"context_line":""},{"line_number":156,"context_line":""},{"line_number":157,"context_line":"class Application(object):"}],"source_content_type":"text/x-python","patch_set":5,"id":"7f231b9d_7ab638dc","line":154,"in_reply_to":"bf091321_bf46184f","updated":"2017-06-12 03:51:54.000000000","message":"I totally agree with you. I was disappointed when I found I need to touch many places when I was adding one new option.","commit_id":"65c91cb1844565f54742ccd002ee57a6de7cb459"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"b51c97796434f910fbf1296d87f249cb004eb3a2","unresolved":false,"context_lines":[{"line_number":131,"context_line":"                (\u0027 \u0027.join(value)))"},{"line_number":132,"context_line":""},{"line_number":133,"context_line":"        handoff_delete \u003d get("},{"line_number":134,"context_line":"            \u0027write_affinity_handoff_delete_count\u0027, \u0027auto\u0027).lower()"},{"line_number":135,"context_line":"        if handoff_delete \u003d\u003d \u0027auto\u0027:"},{"line_number":136,"context_line":"            self.write_affinity_handoff_delete_count \u003d None"},{"line_number":137,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":11,"id":"5f201791_4bcd5764","line":134,"updated":"2017-06-27 05:56:44.000000000","message":"We have a helper method for this in utils.\n\nSo you do something like:\n\n  from swift.common.utils import config_auto_int_value\n  ...\n  self.write_affinity_handoff_delete_count \u003d \\\n      config_auto_int_value(\n          get(\u0027write_affinity_handoff_delete_count\u0027, \u0027auto\u0027),\n None)","commit_id":"1aeac30d9302b92cf07559fec6c518e64b2292f1"},{"author":{"_account_id":6732,"name":"Lingxian Kong","email":"anlin.kong@gmail.com","username":"kong"},"change_message_id":"25314d15b0c6b3f4a3ca9bac7493c6d8bcb652bd","unresolved":false,"context_lines":[{"line_number":131,"context_line":"                (\u0027 \u0027.join(value)))"},{"line_number":132,"context_line":""},{"line_number":133,"context_line":"        handoff_delete \u003d get("},{"line_number":134,"context_line":"            \u0027write_affinity_handoff_delete_count\u0027, \u0027auto\u0027).lower()"},{"line_number":135,"context_line":"        if handoff_delete \u003d\u003d \u0027auto\u0027:"},{"line_number":136,"context_line":"            self.write_affinity_handoff_delete_count \u003d None"},{"line_number":137,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":11,"id":"5f201791_4a59c832","line":134,"in_reply_to":"5f201791_4bcd5764","updated":"2017-06-27 10:41:56.000000000","message":"Thanks! That\u0027s convenient!","commit_id":"1aeac30d9302b92cf07559fec6c518e64b2292f1"}],"test/unit/proxy/controllers/test_obj.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"24267e6359887310f93ac203c7ae2f10ee8f4ee5","unresolved":false,"context_lines":[{"line_number":477,"context_line":"        with set_http_connect(*codes):"},{"line_number":478,"context_line":"            resp \u003d req.get_response(self.app)"},{"line_number":479,"context_line":""},{"line_number":480,"context_line":"        self.assertEqual(resp.status_int, 204)"},{"line_number":481,"context_line":""},{"line_number":482,"context_line":"    def test_POST_non_int_delete_after(self):"},{"line_number":483,"context_line":"        t \u003d str(int(time.time() + 100)) + \u0027.1\u0027"}],"source_content_type":"text/x-python","patch_set":10,"id":"5f201791_88d62c27","line":480,"updated":"2017-06-22 23:53:06.000000000","message":"these tests are acctually *pretty* good...","commit_id":"d7a365f705fd9a80b1abdf7e88bb27fb249ec1f2"}],"test/unit/proxy/test_server.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"5f1676fc75c1946bcdfc548e9ceb2d44083a73a7","unresolved":false,"context_lines":[{"line_number":1365,"context_line":"        read_affinity \u003d r1\u003d100"},{"line_number":1366,"context_line":"        write_affinity \u003d r1"},{"line_number":1367,"context_line":"        write_affinity_node_count \u003d 1 * replicas"},{"line_number":1368,"context_line":"        write_affinity_handoff_delete_count \u003d 4"},{"line_number":1369,"context_line":"        \"\"\""},{"line_number":1370,"context_line":"        expected_default \u003d {\"read_affinity\": \"\","},{"line_number":1371,"context_line":"                            \"sorting_method\": \"shuffle\","}],"source_content_type":"text/x-python","patch_set":5,"id":"bf091321_3f132810","line":1368,"updated":"2017-06-07 23:46:05.000000000","message":"noice\n\nthese tests are good","commit_id":"65c91cb1844565f54742ccd002ee57a6de7cb459"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"bbb5480f40ec6f5b55ef49f907b96e1c9214e3c9","unresolved":false,"context_lines":[{"line_number":1561,"context_line":"                          \"sorting_method\": \"affinity\","},{"line_number":1562,"context_line":"                          \"write_affinity\": \"r0\","},{"line_number":1563,"context_line":"                          \"write_affinity_node_count_fn\": 6,"},{"line_number":1564,"context_line":"                          \"write_affinity_handoff_delete_count\": None}}"},{"line_number":1565,"context_line":"        exp_is_local \u003d {"},{"line_number":1566,"context_line":"            # default write_affinity is r0, dictated by DEFAULT section"},{"line_number":1567,"context_line":"            None: [({\u0027region\u0027: 0, \u0027zone\u0027: 2}, True),"}],"source_content_type":"text/x-python","patch_set":12,"id":"3f1d235d_ada3c3ff","line":1564,"updated":"2017-07-06 12:24:11.000000000","message":"we should have a test with \u0027auto\u0027 maybe? but really that becomes None, so really we\u0027d be testing get_auto_int_config so meh.. not a blocker.","commit_id":"831eb6e3ce317d8209178dd7e4dee509edd179cf"}]}
