)]}'
{"nova/scheduler/client/report.py":[{"author":{"_account_id":25625,"name":"Tetsuro Nakamura","email":"tetsuro.nakamura.bc@hco.ntt.co.jp","username":"tetsuro0907"},"change_message_id":"5fb0445ebfa5a7fec1ba4b0af0fff9ce7be04ba9","unresolved":false,"context_lines":[{"line_number":1037,"context_line":"    def set_inventory_for_provider(self, rp_uuid, rp_name, inv_data,"},{"line_number":1038,"context_line":"                                   parent_provider_uuid\u003dNone):"},{"line_number":1039,"context_line":"        \"\"\"Given the UUID of a provider, set the inventory records for the"},{"line_number":1040,"context_line":"        provider to the supplied dict of resources."},{"line_number":1041,"context_line":""},{"line_number":1042,"context_line":"        :param rp_uuid: UUID of the resource provider to set inventory for"},{"line_number":1043,"context_line":"        :param rp_name: Name of the resource provider in case we need to create"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f93b717_bf03810d","line":1040,"updated":"2018-01-25 09:09:09.000000000","message":"good to add documents what happens if inv_data is empty.","commit_id":"89e1cdfbfee76cb9c894558f677e27cbf7c26967"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"dfd2f74187db7ef5b8c27d31fb07e71f5d26f5d2","unresolved":false,"context_lines":[{"line_number":1037,"context_line":"    def set_inventory_for_provider(self, rp_uuid, rp_name, inv_data,"},{"line_number":1038,"context_line":"                                   parent_provider_uuid\u003dNone):"},{"line_number":1039,"context_line":"        \"\"\"Given the UUID of a provider, set the inventory records for the"},{"line_number":1040,"context_line":"        provider to the supplied dict of resources."},{"line_number":1041,"context_line":""},{"line_number":1042,"context_line":"        :param rp_uuid: UUID of the resource provider to set inventory for"},{"line_number":1043,"context_line":"        :param rp_name: Name of the resource provider in case we need to create"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f93b717_fe8ed425","line":1040,"in_reply_to":"5f93b717_bf03810d","updated":"2018-01-25 19:55:40.000000000","message":"I\u0027m not touching this older method.  Ultimately I\u0027d like to get rid of it.","commit_id":"89e1cdfbfee76cb9c894558f677e27cbf7c26967"},{"author":{"_account_id":25625,"name":"Tetsuro Nakamura","email":"tetsuro.nakamura.bc@hco.ntt.co.jp","username":"tetsuro0907"},"change_message_id":"5fb0445ebfa5a7fec1ba4b0af0fff9ce7be04ba9","unresolved":false,"context_lines":[{"line_number":1067,"context_line":""},{"line_number":1068,"context_line":"    def _set_inventory_for_provider(self, rp_uuid, inv_data):"},{"line_number":1069,"context_line":"        \"\"\"Given the UUID of a provider, set the inventory records for the"},{"line_number":1070,"context_line":"        provider to the supplied dict of resources."},{"line_number":1071,"context_line":""},{"line_number":1072,"context_line":"        Compare and contrast with set_inventory_for_provider above.  This one"},{"line_number":1073,"context_line":"        is specially formulated for use by update_from_provider_tree, because"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f93b717_7f0df935","line":1070,"updated":"2018-01-25 09:09:09.000000000","message":"good to add documents what happens if inv_data is empty.","commit_id":"89e1cdfbfee76cb9c894558f677e27cbf7c26967"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"dfd2f74187db7ef5b8c27d31fb07e71f5d26f5d2","unresolved":false,"context_lines":[{"line_number":1067,"context_line":""},{"line_number":1068,"context_line":"    def _set_inventory_for_provider(self, rp_uuid, inv_data):"},{"line_number":1069,"context_line":"        \"\"\"Given the UUID of a provider, set the inventory records for the"},{"line_number":1070,"context_line":"        provider to the supplied dict of resources."},{"line_number":1071,"context_line":""},{"line_number":1072,"context_line":"        Compare and contrast with set_inventory_for_provider above.  This one"},{"line_number":1073,"context_line":"        is specially formulated for use by update_from_provider_tree, because"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f93b717_deb678da","line":1070,"in_reply_to":"5f93b717_7f0df935","updated":"2018-01-25 19:55:40.000000000","message":"Done","commit_id":"89e1cdfbfee76cb9c894558f677e27cbf7c26967"},{"author":{"_account_id":25625,"name":"Tetsuro Nakamura","email":"tetsuro.nakamura.bc@hco.ntt.co.jp","username":"tetsuro0907"},"change_message_id":"5fb0445ebfa5a7fec1ba4b0af0fff9ce7be04ba9","unresolved":false,"context_lines":[{"line_number":1071,"context_line":""},{"line_number":1072,"context_line":"        Compare and contrast with set_inventory_for_provider above.  This one"},{"line_number":1073,"context_line":"        is specially formulated for use by update_from_provider_tree, because"},{"line_number":1074,"context_line":"        from there, whereas we DO need to _ensure_resource_class(), we ALSO"},{"line_number":1075,"context_line":"        want to short out if inv_data matches what\u0027s already cached, but we"},{"line_number":1076,"context_line":"        DON\u0027T want to:"},{"line_number":1077,"context_line":"        - _ensure_resource_provider"},{"line_number":1078,"context_line":"        - refresh_and_get_inventory"},{"line_number":1079,"context_line":"        - DELETE if inventory is empty, else PUT"},{"line_number":1080,"context_line":"        - retry"},{"line_number":1081,"context_line":"        - invalidate the cache on failure"},{"line_number":1082,"context_line":""},{"line_number":1083,"context_line":"        This version is more in the spirit of set_traits_for_provider."},{"line_number":1084,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"5f93b717_ff3109ee","line":1081,"range":{"start_line":1074,"start_character":66,"end_line":1081,"end_character":41},"updated":"2018-01-25 09:09:09.000000000","message":"It might be just that I\u0027m not catching up with this. X(\nBut I believe a kindful document here would help us a lot, so would you mind if I ask to refactor this to something like;\n\n \"This method doesn\u0027t call _ensure_resource_provider() because...\n  This method doesn\u0027t retry *updating inventory in placement on failure* because ....\"?\n\n(Am I right that this \"retry\" is the 3 attempts in _update_inventory?)\n\nAnyway, it would be nice to make clear explicitly which process *can be* skipped here so skipped, and which process *should be* deleted here so deleted compared to existing set_inventory_for_provider. That would help us to \"consolidate/refactor to one set_inventory_for_provider.\"","commit_id":"89e1cdfbfee76cb9c894558f677e27cbf7c26967"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"dfd2f74187db7ef5b8c27d31fb07e71f5d26f5d2","unresolved":false,"context_lines":[{"line_number":1071,"context_line":""},{"line_number":1072,"context_line":"        Compare and contrast with set_inventory_for_provider above.  This one"},{"line_number":1073,"context_line":"        is specially formulated for use by update_from_provider_tree, because"},{"line_number":1074,"context_line":"        from there, whereas we DO need to _ensure_resource_class(), we ALSO"},{"line_number":1075,"context_line":"        want to short out if inv_data matches what\u0027s already cached, but we"},{"line_number":1076,"context_line":"        DON\u0027T want to:"},{"line_number":1077,"context_line":"        - _ensure_resource_provider"},{"line_number":1078,"context_line":"        - refresh_and_get_inventory"},{"line_number":1079,"context_line":"        - DELETE if inventory is empty, else PUT"},{"line_number":1080,"context_line":"        - retry"},{"line_number":1081,"context_line":"        - invalidate the cache on failure"},{"line_number":1082,"context_line":""},{"line_number":1083,"context_line":"        This version is more in the spirit of set_traits_for_provider."},{"line_number":1084,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"5f93b717_f9758e99","line":1081,"range":{"start_line":1074,"start_character":66,"end_line":1081,"end_character":41},"in_reply_to":"5f93b717_23f0b390","updated":"2018-01-25 19:55:40.000000000","message":"\u003e * DELETE if inventory is empty, else PUT ... not sure why we should\n \u003e always use PUT here.\n\nThat\u0027s explained briefly in the comment below (which I\u0027ve moved into the docstring).  The longer version: deleting the RP\u0027s inventory causes the server to increment the RP\u0027s generation.  Here on the client side, we need to know what that new generation marker is so we can update it in our cache.  The DELETE API a) doesn\u0027t allow us to *send* a generation marker, so if an intervening thread went and changed the inventory, we would blow away the change and blindly remove everything; and b) doesn\u0027t return a payload including a generation, so we would have to do a full refresh to make sure the provider and all its associations are up to date and consistent in our cache.  By always using the PUT API, even if inv_data is {}, we can guarantee cache consistency because a) we\u0027ll get a 409 if the modification we\u0027re sending is based on a stale version of the server data; and b) we\u0027ll receive the generation back in the response payload and know that it corresponds to the version of the provider with empty inv_data, which we can then put in the cache without further refreshes.","commit_id":"89e1cdfbfee76cb9c894558f677e27cbf7c26967"},{"author":{"_account_id":25625,"name":"Tetsuro Nakamura","email":"tetsuro.nakamura.bc@hco.ntt.co.jp","username":"tetsuro0907"},"change_message_id":"a99764aed5c76a83cb0bd824a91c2fbbe280ffe0","unresolved":false,"context_lines":[{"line_number":1071,"context_line":""},{"line_number":1072,"context_line":"        Compare and contrast with set_inventory_for_provider above.  This one"},{"line_number":1073,"context_line":"        is specially formulated for use by update_from_provider_tree, because"},{"line_number":1074,"context_line":"        from there, whereas we DO need to _ensure_resource_class(), we ALSO"},{"line_number":1075,"context_line":"        want to short out if inv_data matches what\u0027s already cached, but we"},{"line_number":1076,"context_line":"        DON\u0027T want to:"},{"line_number":1077,"context_line":"        - _ensure_resource_provider"},{"line_number":1078,"context_line":"        - refresh_and_get_inventory"},{"line_number":1079,"context_line":"        - DELETE if inventory is empty, else PUT"},{"line_number":1080,"context_line":"        - retry"},{"line_number":1081,"context_line":"        - invalidate the cache on failure"},{"line_number":1082,"context_line":""},{"line_number":1083,"context_line":"        This version is more in the spirit of set_traits_for_provider."},{"line_number":1084,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"5f93b717_1546fa7d","line":1081,"range":{"start_line":1074,"start_character":66,"end_line":1081,"end_character":41},"in_reply_to":"5f93b717_f9758e99","updated":"2018-01-26 00:24:38.000000000","message":"Ah, the crucial thing here is the generation for dealing with conflicts. Yup, I was missing that, sorry. That makes sense. I\u0027ll check it up. Thank you soooo much for your kindful explanation.","commit_id":"89e1cdfbfee76cb9c894558f677e27cbf7c26967"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"dfd2f74187db7ef5b8c27d31fb07e71f5d26f5d2","unresolved":false,"context_lines":[{"line_number":1071,"context_line":""},{"line_number":1072,"context_line":"        Compare and contrast with set_inventory_for_provider above.  This one"},{"line_number":1073,"context_line":"        is specially formulated for use by update_from_provider_tree, because"},{"line_number":1074,"context_line":"        from there, whereas we DO need to _ensure_resource_class(), we ALSO"},{"line_number":1075,"context_line":"        want to short out if inv_data matches what\u0027s already cached, but we"},{"line_number":1076,"context_line":"        DON\u0027T want to:"},{"line_number":1077,"context_line":"        - _ensure_resource_provider"},{"line_number":1078,"context_line":"        - refresh_and_get_inventory"},{"line_number":1079,"context_line":"        - DELETE if inventory is empty, else PUT"},{"line_number":1080,"context_line":"        - retry"},{"line_number":1081,"context_line":"        - invalidate the cache on failure"},{"line_number":1082,"context_line":""},{"line_number":1083,"context_line":"        This version is more in the spirit of set_traits_for_provider."},{"line_number":1084,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"5f93b717_79697ebc","line":1081,"range":{"start_line":1074,"start_character":66,"end_line":1081,"end_character":41},"in_reply_to":"5f93b717_ff3109ee","updated":"2018-01-25 19:55:40.000000000","message":"I\u0027ve enhanced the docstring according to your suggestions.  Please let me know if it helps clarify things.\n\n\u003e (Am I right that this \"retry\" is the 3 attempts in _update_inventory?)\n\nYes.","commit_id":"89e1cdfbfee76cb9c894558f677e27cbf7c26967"},{"author":{"_account_id":25625,"name":"Tetsuro Nakamura","email":"tetsuro.nakamura.bc@hco.ntt.co.jp","username":"tetsuro0907"},"change_message_id":"c8551ab2d5d0932ce0f2201b0ee2adb18d13201e","unresolved":false,"context_lines":[{"line_number":1071,"context_line":""},{"line_number":1072,"context_line":"        Compare and contrast with set_inventory_for_provider above.  This one"},{"line_number":1073,"context_line":"        is specially formulated for use by update_from_provider_tree, because"},{"line_number":1074,"context_line":"        from there, whereas we DO need to _ensure_resource_class(), we ALSO"},{"line_number":1075,"context_line":"        want to short out if inv_data matches what\u0027s already cached, but we"},{"line_number":1076,"context_line":"        DON\u0027T want to:"},{"line_number":1077,"context_line":"        - _ensure_resource_provider"},{"line_number":1078,"context_line":"        - refresh_and_get_inventory"},{"line_number":1079,"context_line":"        - DELETE if inventory is empty, else PUT"},{"line_number":1080,"context_line":"        - retry"},{"line_number":1081,"context_line":"        - invalidate the cache on failure"},{"line_number":1082,"context_line":""},{"line_number":1083,"context_line":"        This version is more in the spirit of set_traits_for_provider."},{"line_number":1084,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"5f93b717_23f0b390","line":1081,"range":{"start_line":1074,"start_character":66,"end_line":1081,"end_character":41},"in_reply_to":"5f93b717_ff3109ee","updated":"2018-01-25 10:35:56.000000000","message":"My understanding is this... but not sure.\n* _ensure_resource_provider ... can be skipped so skipped here\n* refresh_and_get_inventory ... can be skipped so skipped here\n* DELETE if inventory is empty, else PUT ... not sure why we should always use PUT here.\n*  retry, invalidate the cache on failure ... shouldn\u0027t be used here, since we should raise errors to upper function and this is the most important point?","commit_id":"89e1cdfbfee76cb9c894558f677e27cbf7c26967"},{"author":{"_account_id":25625,"name":"Tetsuro Nakamura","email":"tetsuro.nakamura.bc@hco.ntt.co.jp","username":"tetsuro0907"},"change_message_id":"5fb0445ebfa5a7fec1ba4b0af0fff9ce7be04ba9","unresolved":false,"context_lines":[{"line_number":1103,"context_line":"        # @safe_connect, so we don\u0027t want to decorate this whole method with it"},{"line_number":1104,"context_line":"        @safe_connect"},{"line_number":1105,"context_line":"        def do_put(url, payload):"},{"line_number":1106,"context_line":"            # NOTE(efried): Don\u0027t use the DELETE API when traits is empty,"},{"line_number":1107,"context_line":"            # because that guy doesn\u0027t return content, and we need to update"},{"line_number":1108,"context_line":"            # the cached provider tree with the new generation."},{"line_number":1109,"context_line":"            return self.put(url, payload)"},{"line_number":1110,"context_line":""},{"line_number":1111,"context_line":"        # If not different from what we\u0027ve got, short out"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f93b717_459f0c50","line":1108,"range":{"start_line":1106,"start_character":0,"end_line":1108,"end_character":63},"updated":"2018-01-25 09:09:09.000000000","message":"Shoud this be really here?","commit_id":"89e1cdfbfee76cb9c894558f677e27cbf7c26967"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"e90417a3915b39d68bf185241a5c88c1f3480be9","unresolved":false,"context_lines":[{"line_number":1103,"context_line":"        # @safe_connect, so we don\u0027t want to decorate this whole method with it"},{"line_number":1104,"context_line":"        @safe_connect"},{"line_number":1105,"context_line":"        def do_put(url, payload):"},{"line_number":1106,"context_line":"            # NOTE(efried): Don\u0027t use the DELETE API when traits is empty,"},{"line_number":1107,"context_line":"            # because that guy doesn\u0027t return content, and we need to update"},{"line_number":1108,"context_line":"            # the cached provider tree with the new generation."},{"line_number":1109,"context_line":"            return self.put(url, payload)"},{"line_number":1110,"context_line":""},{"line_number":1111,"context_line":"        # If not different from what we\u0027ve got, short out"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f93b717_62b999e7","line":1108,"range":{"start_line":1106,"start_character":0,"end_line":1108,"end_character":63},"in_reply_to":"5f93b717_38468b25","updated":"2018-01-27 19:51:25.000000000","message":"Done","commit_id":"89e1cdfbfee76cb9c894558f677e27cbf7c26967"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"dfd2f74187db7ef5b8c27d31fb07e71f5d26f5d2","unresolved":false,"context_lines":[{"line_number":1103,"context_line":"        # @safe_connect, so we don\u0027t want to decorate this whole method with it"},{"line_number":1104,"context_line":"        @safe_connect"},{"line_number":1105,"context_line":"        def do_put(url, payload):"},{"line_number":1106,"context_line":"            # NOTE(efried): Don\u0027t use the DELETE API when traits is empty,"},{"line_number":1107,"context_line":"            # because that guy doesn\u0027t return content, and we need to update"},{"line_number":1108,"context_line":"            # the cached provider tree with the new generation."},{"line_number":1109,"context_line":"            return self.put(url, payload)"},{"line_number":1110,"context_line":""},{"line_number":1111,"context_line":"        # If not different from what we\u0027ve got, short out"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f93b717_a7c84a55","line":1108,"range":{"start_line":1106,"start_character":0,"end_line":1108,"end_character":63},"in_reply_to":"5f93b717_459f0c50","updated":"2018-01-25 19:55:40.000000000","message":"The comment itself describes why we\u0027re NOT doing what\u0027s on L1063-6.  I thought this was as good a spot for it as any.  But per your suggestions above, I can slot it into the docstring instead.","commit_id":"89e1cdfbfee76cb9c894558f677e27cbf7c26967"},{"author":{"_account_id":25625,"name":"Tetsuro Nakamura","email":"tetsuro.nakamura.bc@hco.ntt.co.jp","username":"tetsuro0907"},"change_message_id":"a99764aed5c76a83cb0bd824a91c2fbbe280ffe0","unresolved":false,"context_lines":[{"line_number":1103,"context_line":"        # @safe_connect, so we don\u0027t want to decorate this whole method with it"},{"line_number":1104,"context_line":"        @safe_connect"},{"line_number":1105,"context_line":"        def do_put(url, payload):"},{"line_number":1106,"context_line":"            # NOTE(efried): Don\u0027t use the DELETE API when traits is empty,"},{"line_number":1107,"context_line":"            # because that guy doesn\u0027t return content, and we need to update"},{"line_number":1108,"context_line":"            # the cached provider tree with the new generation."},{"line_number":1109,"context_line":"            return self.put(url, payload)"},{"line_number":1110,"context_line":""},{"line_number":1111,"context_line":"        # If not different from what we\u0027ve got, short out"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f93b717_d50df23e","line":1108,"range":{"start_line":1106,"start_character":0,"end_line":1108,"end_character":63},"in_reply_to":"5f93b717_a7c84a55","updated":"2018-01-26 00:24:38.000000000","message":"Ah, I was misreading this because it says when *traits* is empty.","commit_id":"89e1cdfbfee76cb9c894558f677e27cbf7c26967"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"d751e745021fbd7d08b632f3afc7840f92138242","unresolved":false,"context_lines":[{"line_number":1103,"context_line":"        # @safe_connect, so we don\u0027t want to decorate this whole method with it"},{"line_number":1104,"context_line":"        @safe_connect"},{"line_number":1105,"context_line":"        def do_put(url, payload):"},{"line_number":1106,"context_line":"            # NOTE(efried): Don\u0027t use the DELETE API when traits is empty,"},{"line_number":1107,"context_line":"            # because that guy doesn\u0027t return content, and we need to update"},{"line_number":1108,"context_line":"            # the cached provider tree with the new generation."},{"line_number":1109,"context_line":"            return self.put(url, payload)"},{"line_number":1110,"context_line":""},{"line_number":1111,"context_line":"        # If not different from what we\u0027ve got, short out"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f93b717_38468b25","line":1108,"range":{"start_line":1106,"start_character":0,"end_line":1108,"end_character":63},"in_reply_to":"5f93b717_d50df23e","updated":"2018-01-26 00:38:57.000000000","message":"D\u0027oh!  Bad copy/paste.  You\u0027re reading it better than I did :)  Will fix.","commit_id":"89e1cdfbfee76cb9c894558f677e27cbf7c26967"},{"author":{"_account_id":25625,"name":"Tetsuro Nakamura","email":"tetsuro.nakamura.bc@hco.ntt.co.jp","username":"tetsuro0907"},"change_message_id":"d928bb8904b27a3474196eab7b4f08626b2bc624","unresolved":false,"context_lines":[{"line_number":1159,"context_line":"        if resp.status_code \u003d\u003d 409:"},{"line_number":1160,"context_line":"            # If a conflict attempting to remove inventory in a resource class"},{"line_number":1161,"context_line":"            # with active allocations, raise InventoryInUse"},{"line_number":1162,"context_line":"            match \u003d _RE_INV_IN_USE.search(resp.text)"},{"line_number":1163,"context_line":"            if match:"},{"line_number":1164,"context_line":"                rc \u003d match.group(1)"},{"line_number":1165,"context_line":"                raise exception.InventoryInUse("},{"line_number":1166,"context_line":"                    resource_classes\u003drc,"},{"line_number":1167,"context_line":"                    resource_provider\u003drp_uuid,"}],"source_content_type":"text/x-python","patch_set":7,"id":"5f93b717_ac6d4233","line":1164,"range":{"start_line":1162,"start_character":0,"end_line":1164,"end_character":35},"updated":"2018-01-29 11:02:24.000000000","message":"FYI: _extract_inventory_in_use() function is @L240.","commit_id":"7213b0f3708bf25b747d52071ce574b4620b9778"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"276a5d8610095eaaa042b152493303b30b5cd126","unresolved":false,"context_lines":[{"line_number":1159,"context_line":"        if resp.status_code \u003d\u003d 409:"},{"line_number":1160,"context_line":"            # If a conflict attempting to remove inventory in a resource class"},{"line_number":1161,"context_line":"            # with active allocations, raise InventoryInUse"},{"line_number":1162,"context_line":"            match \u003d _RE_INV_IN_USE.search(resp.text)"},{"line_number":1163,"context_line":"            if match:"},{"line_number":1164,"context_line":"                rc \u003d match.group(1)"},{"line_number":1165,"context_line":"                raise exception.InventoryInUse("},{"line_number":1166,"context_line":"                    resource_classes\u003drc,"},{"line_number":1167,"context_line":"                    resource_provider\u003drp_uuid,"}],"source_content_type":"text/x-python","patch_set":7,"id":"5f93b717_558995c7","line":1164,"range":{"start_line":1162,"start_character":0,"end_line":1164,"end_character":35},"in_reply_to":"5f93b717_8acce56a","updated":"2018-01-30 00:15:23.000000000","message":"Done in https://review.openstack.org/#/c/531260/","commit_id":"7213b0f3708bf25b747d52071ce574b4620b9778"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"8833528cd72099f45d707da3e7062094f67947c4","unresolved":false,"context_lines":[{"line_number":1159,"context_line":"        if resp.status_code \u003d\u003d 409:"},{"line_number":1160,"context_line":"            # If a conflict attempting to remove inventory in a resource class"},{"line_number":1161,"context_line":"            # with active allocations, raise InventoryInUse"},{"line_number":1162,"context_line":"            match \u003d _RE_INV_IN_USE.search(resp.text)"},{"line_number":1163,"context_line":"            if match:"},{"line_number":1164,"context_line":"                rc \u003d match.group(1)"},{"line_number":1165,"context_line":"                raise exception.InventoryInUse("},{"line_number":1166,"context_line":"                    resource_classes\u003drc,"},{"line_number":1167,"context_line":"                    resource_provider\u003drp_uuid,"}],"source_content_type":"text/x-python","patch_set":7,"id":"5f93b717_8acce56a","line":1164,"range":{"start_line":1162,"start_character":0,"end_line":1164,"end_character":35},"in_reply_to":"5f93b717_ac6d4233","updated":"2018-01-29 14:02:33.000000000","message":"Oh, nice. I copied this from L851, which could be consolidated as well.  I think I\u0027ll do that in a followon, though, since I\u0027ll have to reconcile the None-vs-exception thing one way or another.","commit_id":"7213b0f3708bf25b747d52071ce574b4620b9778"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"c9cca6bbe049d2a95008f01c160140156180f539","unresolved":false,"context_lines":[{"line_number":1079,"context_line":"        other method, we DO need to _ensure_resource_class - i.e. automatically"},{"line_number":1080,"context_line":"        create new resource classes specified in the inv_data.  However, UNLIKE"},{"line_number":1081,"context_line":"        the other method:"},{"line_number":1082,"context_line":"        - We don\u0027t use the DELETE API when inventory is empty, because that guy"},{"line_number":1083,"context_line":"          doesn\u0027t return content, and we need to update the cached provider"},{"line_number":1084,"context_line":"          tree with the new generation."},{"line_number":1085,"context_line":"        - We raise exceptions (rather than returning a boolean) which are"},{"line_number":1086,"context_line":"          handled in a consistent fashion by update_from_provider_tree."},{"line_number":1087,"context_line":"        - We don\u0027t invalidate the cache on failure.  That\u0027s controlled at a"}],"source_content_type":"text/x-python","patch_set":11,"id":"3fa0c359_09359cda","line":1084,"range":{"start_line":1082,"start_character":9,"end_line":1084,"end_character":39},"updated":"2018-02-05 19:48:58.000000000","message":"this can be removed once https://review.openstack.org/#/c/539712/ merges.","commit_id":"b6c262b6a8b17e3e6d59c6673ffb5af0970b7369"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"4fab74ddc6f8cbee64c364e37720fbfddbdc0934","unresolved":false,"context_lines":[{"line_number":1079,"context_line":"        other method, we DO need to _ensure_resource_class - i.e. automatically"},{"line_number":1080,"context_line":"        create new resource classes specified in the inv_data.  However, UNLIKE"},{"line_number":1081,"context_line":"        the other method:"},{"line_number":1082,"context_line":"        - We don\u0027t use the DELETE API when inventory is empty, because that guy"},{"line_number":1083,"context_line":"          doesn\u0027t return content, and we need to update the cached provider"},{"line_number":1084,"context_line":"          tree with the new generation."},{"line_number":1085,"context_line":"        - We raise exceptions (rather than returning a boolean) which are"},{"line_number":1086,"context_line":"          handled in a consistent fashion by update_from_provider_tree."},{"line_number":1087,"context_line":"        - We don\u0027t invalidate the cache on failure.  That\u0027s controlled at a"}],"source_content_type":"text/x-python","patch_set":11,"id":"3fa0c359_9f88fa1f","line":1084,"range":{"start_line":1082,"start_character":9,"end_line":1084,"end_character":39},"in_reply_to":"3fa0c359_09359cda","updated":"2018-02-05 20:28:52.000000000","message":"Well, since we\u0027re not actually removing the DELETE API, I\u0027d like to leave this here so some intrepid future developer doesn\u0027t come along and try to \"improve\" things by swapping it out.","commit_id":"b6c262b6a8b17e3e6d59c6673ffb5af0970b7369"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"c9cca6bbe049d2a95008f01c160140156180f539","unresolved":false,"context_lines":[{"line_number":1127,"context_line":"        if not self._provider_tree.has_inventory_changed(rp_uuid, inv_data):"},{"line_number":1128,"context_line":"            return"},{"line_number":1129,"context_line":""},{"line_number":1130,"context_line":"        # TODO(efried): Don\u0027t rely on local idea of \"standard\" resource classes"},{"line_number":1131,"context_line":"        list(map(self._ensure_resource_class,"},{"line_number":1132,"context_line":"                 (rc_name for rc_name in inv_data"},{"line_number":1133,"context_line":"                  if rc_name not in fields.ResourceClass.STANDARD)))"},{"line_number":1134,"context_line":""},{"line_number":1135,"context_line":"        url \u003d \u0027/resource_providers/%s/inventories\u0027 % rp_uuid"},{"line_number":1136,"context_line":"        inv_data \u003d inv_data or {}"}],"source_content_type":"text/x-python","patch_set":11,"id":"3fa0c359_e4c09553","line":1133,"range":{"start_line":1130,"start_character":0,"end_line":1133,"end_character":68},"updated":"2018-02-05 19:48:58.000000000","message":"this won\u0027t be necessary when https://review.openstack.org/#/c/539738/ merges, though, right? I think it makes sense to make this dependent on that and rework this accordingly.\n\nYou can then decorate _ensure_resource_classes() with @safe_connect and remove lines 1120-1124","commit_id":"b6c262b6a8b17e3e6d59c6673ffb5af0970b7369"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"1d275f2e048471959bff938c0c1a93622ea35c0f","unresolved":false,"context_lines":[{"line_number":1127,"context_line":"        if not self._provider_tree.has_inventory_changed(rp_uuid, inv_data):"},{"line_number":1128,"context_line":"            return"},{"line_number":1129,"context_line":""},{"line_number":1130,"context_line":"        # TODO(efried): Don\u0027t rely on local idea of \"standard\" resource classes"},{"line_number":1131,"context_line":"        list(map(self._ensure_resource_class,"},{"line_number":1132,"context_line":"                 (rc_name for rc_name in inv_data"},{"line_number":1133,"context_line":"                  if rc_name not in fields.ResourceClass.STANDARD)))"},{"line_number":1134,"context_line":""},{"line_number":1135,"context_line":"        url \u003d \u0027/resource_providers/%s/inventories\u0027 % rp_uuid"},{"line_number":1136,"context_line":"        inv_data \u003d inv_data or {}"}],"source_content_type":"text/x-python","patch_set":11,"id":"3fa0c359_89cbe551","line":1133,"range":{"start_line":1130,"start_character":0,"end_line":1133,"end_character":68},"in_reply_to":"3fa0c359_46f38a9f","updated":"2018-02-05 23:48:01.000000000","message":"Done","commit_id":"b6c262b6a8b17e3e6d59c6673ffb5af0970b7369"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"83dd422bb0a8737d57f8f1e31ab8d58c6a74e349","unresolved":false,"context_lines":[{"line_number":1127,"context_line":"        if not self._provider_tree.has_inventory_changed(rp_uuid, inv_data):"},{"line_number":1128,"context_line":"            return"},{"line_number":1129,"context_line":""},{"line_number":1130,"context_line":"        # TODO(efried): Don\u0027t rely on local idea of \"standard\" resource classes"},{"line_number":1131,"context_line":"        list(map(self._ensure_resource_class,"},{"line_number":1132,"context_line":"                 (rc_name for rc_name in inv_data"},{"line_number":1133,"context_line":"                  if rc_name not in fields.ResourceClass.STANDARD)))"},{"line_number":1134,"context_line":""},{"line_number":1135,"context_line":"        url \u003d \u0027/resource_providers/%s/inventories\u0027 % rp_uuid"},{"line_number":1136,"context_line":"        inv_data \u003d inv_data or {}"}],"source_content_type":"text/x-python","patch_set":11,"id":"3fa0c359_46f38a9f","line":1133,"range":{"start_line":1130,"start_character":0,"end_line":1133,"end_character":68},"in_reply_to":"3fa0c359_5f9fd24f","updated":"2018-02-05 23:02:22.000000000","message":"\u0027cept I still need the @safe_connect split, because _ensure_resource_classes is @safe_connect\u0027d, and I need the PUT call to be @safe_connect\u0027d too.","commit_id":"b6c262b6a8b17e3e6d59c6673ffb5af0970b7369"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"4fab74ddc6f8cbee64c364e37720fbfddbdc0934","unresolved":false,"context_lines":[{"line_number":1127,"context_line":"        if not self._provider_tree.has_inventory_changed(rp_uuid, inv_data):"},{"line_number":1128,"context_line":"            return"},{"line_number":1129,"context_line":""},{"line_number":1130,"context_line":"        # TODO(efried): Don\u0027t rely on local idea of \"standard\" resource classes"},{"line_number":1131,"context_line":"        list(map(self._ensure_resource_class,"},{"line_number":1132,"context_line":"                 (rc_name for rc_name in inv_data"},{"line_number":1133,"context_line":"                  if rc_name not in fields.ResourceClass.STANDARD)))"},{"line_number":1134,"context_line":""},{"line_number":1135,"context_line":"        url \u003d \u0027/resource_providers/%s/inventories\u0027 % rp_uuid"},{"line_number":1136,"context_line":"        inv_data \u003d inv_data or {}"}],"source_content_type":"text/x-python","patch_set":11,"id":"3fa0c359_5f9fd24f","line":1133,"range":{"start_line":1130,"start_character":0,"end_line":1133,"end_character":68},"in_reply_to":"3fa0c359_e4c09553","updated":"2018-02-05 20:28:52.000000000","message":"Agree, this will actually break once that patch merges (because _ensure_resource_class goes away).  I can rebase as you suggest.","commit_id":"b6c262b6a8b17e3e6d59c6673ffb5af0970b7369"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"2a4948431fadf5e8362702f048883348c3142789","unresolved":false,"context_lines":[{"line_number":1051,"context_line":"                 redrive this operation."},{"line_number":1052,"context_line":"        :raises: ResourceProviderUpdateFailed on any other placement API"},{"line_number":1053,"context_line":"                 failure."},{"line_number":1054,"context_line":"        \"\"\""},{"line_number":1055,"context_line":"        # TODO(efried): Consolidate/refactor to one set_inventory_for_provider."},{"line_number":1056,"context_line":""},{"line_number":1057,"context_line":"        # NOTE(efried): This is here because _ensure_resource_class already has"}],"source_content_type":"text/x-python","patch_set":15,"id":"df7087c5_d8173b45","line":1054,"updated":"2018-03-09 23:39:34.000000000","message":"excellent docstring.","commit_id":"e509ec53377b772e65d5d32e9841d46549cfa8d8"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"33a95b9ebf1126d4181d6a334fc8634f96bbfceb","unresolved":false,"context_lines":[{"line_number":1054,"context_line":"        \"\"\""},{"line_number":1055,"context_line":"        # TODO(efried): Consolidate/refactor to one set_inventory_for_provider."},{"line_number":1056,"context_line":""},{"line_number":1057,"context_line":"        # NOTE(efried): This is here because _ensure_resource_class already has"},{"line_number":1058,"context_line":"        # @safe_connect, so we don\u0027t want to decorate this whole method with it"},{"line_number":1059,"context_line":"        @safe_connect"},{"line_number":1060,"context_line":"        def do_put(url, payload):"}],"source_content_type":"text/x-python","patch_set":15,"id":"3fa0c359_1f2ee042","line":1057,"range":{"start_line":1057,"start_character":62,"end_line":1057,"end_character":67},"updated":"2018-02-19 19:53:57.000000000","message":"classes","commit_id":"e509ec53377b772e65d5d32e9841d46549cfa8d8"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"6e2bea4636ae458f516cb69782780d12cabd27c5","unresolved":false,"context_lines":[{"line_number":1058,"context_line":"        # @safe_connect, so we don\u0027t want to decorate this whole method with it"},{"line_number":1059,"context_line":"        @safe_connect"},{"line_number":1060,"context_line":"        def do_put(url, payload):"},{"line_number":1061,"context_line":"            return self.put(url, payload, global_request_id\u003dcontext.global_id)"},{"line_number":1062,"context_line":""},{"line_number":1063,"context_line":"        # If not different from what we\u0027ve got, short out"},{"line_number":1064,"context_line":"        if not self._provider_tree.has_inventory_changed(rp_uuid, inv_data):"}],"source_content_type":"text/x-python","patch_set":15,"id":"3fa0c359_d2015708","line":1061,"updated":"2018-02-19 13:37:25.000000000","message":"That\u0027s one way do it, but why not make another private method that this one calls? Seems like that would be somewhat more readable, but that might be because I tend to be a fan of lots of tiny methods. Certainly not gonna say \"er mer gawd, don\u0027t do this!\". Merely a preference.","commit_id":"e509ec53377b772e65d5d32e9841d46549cfa8d8"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"2a4948431fadf5e8362702f048883348c3142789","unresolved":false,"context_lines":[{"line_number":1058,"context_line":"        # @safe_connect, so we don\u0027t want to decorate this whole method with it"},{"line_number":1059,"context_line":"        @safe_connect"},{"line_number":1060,"context_line":"        def do_put(url, payload):"},{"line_number":1061,"context_line":"            return self.put(url, payload, global_request_id\u003dcontext.global_id)"},{"line_number":1062,"context_line":""},{"line_number":1063,"context_line":"        # If not different from what we\u0027ve got, short out"},{"line_number":1064,"context_line":"        if not self._provider_tree.has_inventory_changed(rp_uuid, inv_data):"}],"source_content_type":"text/x-python","patch_set":15,"id":"df7087c5_9850e30c","line":1061,"in_reply_to":"3fa0c359_1f14a09f","updated":"2018-03-09 23:39:34.000000000","message":"@safe_connect was built to allow the placement API to \"come available\" *after* existing nova-compute service workers were upgraded and not have the nova-compute service worker crash upon not being able to immediately communicate with the placement API.\n\nEric, without a little more information on what specific problems you ran into (rabbit holed), I\u0027m afraid I have to agree with Chris that decorating an inner function like this is a little odd.","commit_id":"e509ec53377b772e65d5d32e9841d46549cfa8d8"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"33a95b9ebf1126d4181d6a334fc8634f96bbfceb","unresolved":false,"context_lines":[{"line_number":1058,"context_line":"        # @safe_connect, so we don\u0027t want to decorate this whole method with it"},{"line_number":1059,"context_line":"        @safe_connect"},{"line_number":1060,"context_line":"        def do_put(url, payload):"},{"line_number":1061,"context_line":"            return self.put(url, payload, global_request_id\u003dcontext.global_id)"},{"line_number":1062,"context_line":""},{"line_number":1063,"context_line":"        # If not different from what we\u0027ve got, short out"},{"line_number":1064,"context_line":"        if not self._provider_tree.has_inventory_changed(rp_uuid, inv_data):"}],"source_content_type":"text/x-python","patch_set":15,"id":"3fa0c359_1f14a09f","line":1061,"in_reply_to":"3fa0c359_d2015708","updated":"2018-02-19 19:53:57.000000000","message":"Mm.  Until/unless we need a safe_connect_put somewhere else, I have a pretty strong preference for this way.\n\n(Looking at the safe_connect decorator sent me down a rabbit hole.  It doesn\u0027t do at all what I expected.  I started wondering why we\u0027re not just decorating get/put/post/delete with it.  It\u0027s swallowing ksa errors and rebuilding the adapter client, so \"compound\" operations could get really weird results involving blithely *skipping* a step anywhere in the process.  Considering how it\u0027s written, we should be decorating the outermost scope of any given process.  Or it should be rewritten to retry and/or raise when something goes wrong.  In either case, we have no real protection over multiple nested instances of the decorator, which could have even weirder results.  We should maybe consider building in such protections.\n\nIs it only supposed to be protecting against misconfigurations at startup?  Is it \"impossible\" for the errors it catches (and swallows) to crop up in mid-stream, after we\u0027ve been running happily for a while?)","commit_id":"e509ec53377b772e65d5d32e9841d46549cfa8d8"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"2a4948431fadf5e8362702f048883348c3142789","unresolved":false,"context_lines":[{"line_number":1105,"context_line":"                raise exception.InventoryInUse("},{"line_number":1106,"context_line":"                    resource_classes\u003drc,"},{"line_number":1107,"context_line":"                    resource_provider\u003drp_uuid,"},{"line_number":1108,"context_line":"                )"},{"line_number":1109,"context_line":"            # Other conflicts are generation mismatch: raise conflict exception"},{"line_number":1110,"context_line":"            raise exception.ResourceProviderUpdateConflict("},{"line_number":1111,"context_line":"                uuid\u003drp_uuid, generation\u003dgeneration, error\u003dresp.text)"}],"source_content_type":"text/x-python","patch_set":15,"id":"df7087c5_b84a8752","line":1108,"range":{"start_line":1108,"start_character":15,"end_line":1108,"end_character":17},"updated":"2018-03-09 23:39:34.000000000","message":"I\u0027m surprised the comma and paren-on-own-line patrol hasn\u0027t flagged this egregious violation.","commit_id":"e509ec53377b772e65d5d32e9841d46549cfa8d8"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"108cd994f0ad8e899ae8127e21bb90721ffb8ba0","unresolved":false,"context_lines":[{"line_number":1047,"context_line":"        - We don\u0027t invalidate the cache on failure.  That\u0027s controlled at a"},{"line_number":1048,"context_line":"          broader scope (based on errors from ANY of the set_*_for_provider"},{"line_number":1049,"context_line":"          methods, etc.) by update_from_provider_tree."},{"line_number":1050,"context_line":"        - We don\u0027t retry.  In this code path, retries happen at the level of"},{"line_number":1051,"context_line":"          the resource tracker on the next iteration."},{"line_number":1052,"context_line":"        - We take advantage of the cache and no-op if inv_data isn\u0027t different"},{"line_number":1053,"context_line":"          from what we have locally.  This is an optimization, not essential."},{"line_number":1054,"context_line":"        - We don\u0027t _ensure_resource_provider or refresh_and_get_inventory,"}],"source_content_type":"text/x-python","patch_set":16,"id":"df7087c5_13baff6c","line":1051,"range":{"start_line":1050,"start_character":4,"end_line":1051,"end_character":53},"updated":"2018-03-15 08:03:52.000000000","message":"Does that mean a variety of the whole update_available_resource? I thought it should be only a try of the update of this provider\u0027s inventory","commit_id":"3921cbc9ecd29d75a6186a206076bf7b67122b5f"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"d621194124c4ffa2d51c8fe4852a81811c84c587","unresolved":false,"context_lines":[{"line_number":1047,"context_line":"        - We don\u0027t invalidate the cache on failure.  That\u0027s controlled at a"},{"line_number":1048,"context_line":"          broader scope (based on errors from ANY of the set_*_for_provider"},{"line_number":1049,"context_line":"          methods, etc.) by update_from_provider_tree."},{"line_number":1050,"context_line":"        - We don\u0027t retry.  In this code path, retries happen at the level of"},{"line_number":1051,"context_line":"          the resource tracker on the next iteration."},{"line_number":1052,"context_line":"        - We take advantage of the cache and no-op if inv_data isn\u0027t different"},{"line_number":1053,"context_line":"          from what we have locally.  This is an optimization, not essential."},{"line_number":1054,"context_line":"        - We don\u0027t _ensure_resource_provider or refresh_and_get_inventory,"}],"source_content_type":"text/x-python","patch_set":16,"id":"df7087c5_8f7b20f3","line":1051,"range":{"start_line":1050,"start_character":4,"end_line":1051,"end_character":53},"in_reply_to":"df7087c5_0b795692","updated":"2018-03-16 05:52:59.000000000","message":"ok, thanks for the explain, I like the simple of this method.","commit_id":"3921cbc9ecd29d75a6186a206076bf7b67122b5f"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"5f5fea2ead255bc188ac77d72d67e0e23b3fb369","unresolved":false,"context_lines":[{"line_number":1047,"context_line":"        - We don\u0027t invalidate the cache on failure.  That\u0027s controlled at a"},{"line_number":1048,"context_line":"          broader scope (based on errors from ANY of the set_*_for_provider"},{"line_number":1049,"context_line":"          methods, etc.) by update_from_provider_tree."},{"line_number":1050,"context_line":"        - We don\u0027t retry.  In this code path, retries happen at the level of"},{"line_number":1051,"context_line":"          the resource tracker on the next iteration."},{"line_number":1052,"context_line":"        - We take advantage of the cache and no-op if inv_data isn\u0027t different"},{"line_number":1053,"context_line":"          from what we have locally.  This is an optimization, not essential."},{"line_number":1054,"context_line":"        - We don\u0027t _ensure_resource_provider or refresh_and_get_inventory,"}],"source_content_type":"text/x-python","patch_set":16,"id":"df7087c5_0b795692","line":1051,"range":{"start_line":1050,"start_character":4,"end_line":1051,"end_character":53},"in_reply_to":"df7087c5_13baff6c","updated":"2018-03-15 14:30:27.000000000","message":"That\u0027s correct: if any individual update fails (not just on inventory, but also on traits, aggregates, etc.) we punt the whole thing until the next iteration.\n\n- If the failure is a generation conflict, we really need to retry the whole operation so we get the updated state of the world.\n- We could conceivably retry non-generation-conflict failures locally; but would still need to consider the case where they fail all retries and we end up in the same situation as if we didn\u0027t retry at all.\n\nWe could revisit this philosophy in the future, but for now, keeping it simple seems like the right choice.","commit_id":"3921cbc9ecd29d75a6186a206076bf7b67122b5f"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"108cd994f0ad8e899ae8127e21bb90721ffb8ba0","unresolved":false,"context_lines":[{"line_number":1118,"context_line":"            \u0027status_code\u0027: resp.status_code,"},{"line_number":1119,"context_line":"            \u0027err_text\u0027: resp.text,"},{"line_number":1120,"context_line":"        }"},{"line_number":1121,"context_line":"        LOG.error(msg, args)"},{"line_number":1122,"context_line":""},{"line_number":1123,"context_line":"        if resp.status_code \u003d\u003d 409:"},{"line_number":1124,"context_line":"            # If a conflict attempting to remove inventory in a resource class"}],"source_content_type":"text/x-python","patch_set":16,"id":"df7087c5_8ed90223","line":1121,"range":{"start_line":1121,"start_character":8,"end_line":1121,"end_character":28},"updated":"2018-03-15 08:03:52.000000000","message":"I feel it isn\u0027t worth a error message when the return code is 409","commit_id":"3921cbc9ecd29d75a6186a206076bf7b67122b5f"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"5f5fea2ead255bc188ac77d72d67e0e23b3fb369","unresolved":false,"context_lines":[{"line_number":1118,"context_line":"            \u0027status_code\u0027: resp.status_code,"},{"line_number":1119,"context_line":"            \u0027err_text\u0027: resp.text,"},{"line_number":1120,"context_line":"        }"},{"line_number":1121,"context_line":"        LOG.error(msg, args)"},{"line_number":1122,"context_line":""},{"line_number":1123,"context_line":"        if resp.status_code \u003d\u003d 409:"},{"line_number":1124,"context_line":"            # If a conflict attempting to remove inventory in a resource class"}],"source_content_type":"text/x-python","patch_set":16,"id":"df7087c5_0b871664","line":1121,"range":{"start_line":1121,"start_character":8,"end_line":1121,"end_character":28},"in_reply_to":"df7087c5_8ed90223","updated":"2018-03-15 14:30:27.000000000","message":"Yeah, I could be convinced to go with a warning for 409.  But not lower than that, since we\u0027re going to wind up in what\u0027s effectively an inconsistent state until the next iteration.","commit_id":"3921cbc9ecd29d75a6186a206076bf7b67122b5f"}],"nova/tests/functional/api/openstack/placement/test_report_client.py":[{"author":{"_account_id":25625,"name":"Tetsuro Nakamura","email":"tetsuro.nakamura.bc@hco.ntt.co.jp","username":"tetsuro0907"},"change_message_id":"d928bb8904b27a3474196eab7b4f08626b2bc624","unresolved":false,"context_lines":[{"line_number":511,"context_line":"                    \u0027allocation_ratio\u0027: 8.0,"},{"line_number":512,"context_line":"                },"},{"line_number":513,"context_line":"            }"},{"line_number":514,"context_line":"            # Cached generation is of, so this will bounce with a conflict."},{"line_number":515,"context_line":"            self.assertRaises("},{"line_number":516,"context_line":"                exception.ResourceProviderUpdateConflict,"},{"line_number":517,"context_line":"                self.client._set_inventory_for_provider, uuids.cn, inv)"}],"source_content_type":"text/x-python","patch_set":7,"id":"5f93b717_4c091edb","line":514,"range":{"start_line":514,"start_character":14,"end_line":514,"end_character":37},"updated":"2018-01-29 11:02:24.000000000","message":"Is this proper English?","commit_id":"7213b0f3708bf25b747d52071ce574b4620b9778"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"ce7df2abde904240095e86bf7e0d0050420b47a1","unresolved":false,"context_lines":[{"line_number":511,"context_line":"                    \u0027allocation_ratio\u0027: 8.0,"},{"line_number":512,"context_line":"                },"},{"line_number":513,"context_line":"            }"},{"line_number":514,"context_line":"            # Cached generation is of, so this will bounce with a conflict."},{"line_number":515,"context_line":"            self.assertRaises("},{"line_number":516,"context_line":"                exception.ResourceProviderUpdateConflict,"},{"line_number":517,"context_line":"                self.client._set_inventory_for_provider, uuids.cn, inv)"}],"source_content_type":"text/x-python","patch_set":7,"id":"5f93b717_70faa775","line":514,"range":{"start_line":514,"start_character":14,"end_line":514,"end_character":37},"in_reply_to":"5f93b717_2ae111d1","updated":"2018-01-30 00:11:54.000000000","message":"Done","commit_id":"7213b0f3708bf25b747d52071ce574b4620b9778"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"8833528cd72099f45d707da3e7062094f67947c4","unresolved":false,"context_lines":[{"line_number":511,"context_line":"                    \u0027allocation_ratio\u0027: 8.0,"},{"line_number":512,"context_line":"                },"},{"line_number":513,"context_line":"            }"},{"line_number":514,"context_line":"            # Cached generation is of, so this will bounce with a conflict."},{"line_number":515,"context_line":"            self.assertRaises("},{"line_number":516,"context_line":"                exception.ResourceProviderUpdateConflict,"},{"line_number":517,"context_line":"                self.client._set_inventory_for_provider, uuids.cn, inv)"}],"source_content_type":"text/x-python","patch_set":7,"id":"5f93b717_2ae111d1","line":514,"range":{"start_line":514,"start_character":14,"end_line":514,"end_character":37},"in_reply_to":"5f93b717_4c091edb","updated":"2018-01-29 14:02:33.000000000","message":"Not remotely.  I think I meant \"off\", as in \"mismatched\".  Will fix.","commit_id":"7213b0f3708bf25b747d52071ce574b4620b9778"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"2a4948431fadf5e8362702f048883348c3142789","unresolved":false,"context_lines":[{"line_number":685,"context_line":"            self.assertEqual("},{"line_number":686,"context_line":"                inv,"},{"line_number":687,"context_line":"                self.client._get_inventory("},{"line_number":688,"context_line":"                    self.context, uuids.cn)[\u0027inventories\u0027])"}],"source_content_type":"text/x-python","patch_set":15,"id":"df7087c5_58732bb2","line":688,"updated":"2018-03-09 23:39:34.000000000","message":"awesome tests here, Eric.","commit_id":"e509ec53377b772e65d5d32e9841d46549cfa8d8"}]}
