)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"20796967f9a925481999a56e09add337ff576603","unresolved":false,"context_lines":[{"line_number":31,"context_line":"requested as an additional return value. Then, we move the database"},{"line_number":32,"context_line":"transaction to cover only util.update_consumers() and"},{"line_number":33,"context_line":"AllocationList.replace_all() so that if replace_all() fails due to a"},{"line_number":34,"context_line":"generation conflict, the consumer updates will also be rolled back."},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"This approach was chosen in an effort to introduce the least amount of"},{"line_number":37,"context_line":"change to the existing understood code."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"7efe76b0_f81279ca","line":34,"updated":"2021-09-02 10:14:09.000000000","message":"+1 Agree, this sounds like a good approach","commit_id":"133fca1e9b0f5d5b8690bf00e918f11234206065"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"715d3a1998cd523c9e86f1889f4ef4d888d5c48a","unresolved":true,"context_lines":[{"line_number":37,"context_line":"change to the existing understood code."},{"line_number":38,"context_line":""},{"line_number":39,"context_line":"Story: 2005473"},{"line_number":40,"context_line":"Task: 36421"},{"line_number":41,"context_line":""},{"line_number":42,"context_line":"[1] I24c2315093e07dbf25c4fb53152e6a4de7477a51"},{"line_number":43,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"b1cb0312_3ac718cf","line":40,"updated":"2021-09-02 11:20:56.000000000","message":"I don\u0027t know how to link a patch to multiple storyboard stories the bug is tracked in \nStory: 2009159","commit_id":"133fca1e9b0f5d5b8690bf00e918f11234206065"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"eb58436ced81535a7c2e09caa52c0d30afae6eaa","unresolved":true,"context_lines":[{"line_number":37,"context_line":"change to the existing understood code."},{"line_number":38,"context_line":""},{"line_number":39,"context_line":"Story: 2005473"},{"line_number":40,"context_line":"Task: 36421"},{"line_number":41,"context_line":""},{"line_number":42,"context_line":"[1] I24c2315093e07dbf25c4fb53152e6a4de7477a51"},{"line_number":43,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"3cbd60b1_ecfe2a0c","line":40,"in_reply_to":"b1cb0312_3ac718cf","updated":"2021-09-02 15:54:12.000000000","message":"Sorry, this was an accident. I actually have no idea how I did it :/","commit_id":"133fca1e9b0f5d5b8690bf00e918f11234206065"}],"placement/handlers/allocation.py":[{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"449dfd5f5b49a86f8dd417f706e21e19e1a25b85","unresolved":true,"context_lines":[{"line_number":379,"context_line":"    \"\"\""},{"line_number":380,"context_line":"    for consumer in consumers:"},{"line_number":381,"context_line":"        try:"},{"line_number":382,"context_line":"            LOG.debug(\u0027deleting consumer\u0027)"},{"line_number":383,"context_line":"            consumer.delete()"},{"line_number":384,"context_line":"            LOG.debug(\"Deleted auto-created consumer with consumer UUID \""},{"line_number":385,"context_line":"                      \"%s after failed allocation\", consumer.uuid)"}],"source_content_type":"text/x-python","patch_set":1,"id":"376ca6b5_a3fe5d30","line":382,"updated":"2021-09-02 02:55:25.000000000","message":"Dangit.","commit_id":"7c9aaf3eecf76d8e575ebdcf5b59bf123e67ac82"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"20796967f9a925481999a56e09add337ff576603","unresolved":true,"context_lines":[{"line_number":219,"context_line":"    :param data: A dictionary of multiple allocations by consumer uuid."},{"line_number":220,"context_line":"    :param want_version: the microversion matcher."},{"line_number":221,"context_line":"    :return: A tuple of a dict of all consumer objects (by consumer uuid)"},{"line_number":222,"context_line":"             and a list of those consumer objects which are new."},{"line_number":223,"context_line":"    \"\"\""},{"line_number":224,"context_line":"    # First, ensure that all consumers referenced in the payload actually"},{"line_number":225,"context_line":"    # exist. And if not, create them. Keep a record of auto-created consumers"}],"source_content_type":"text/x-python","patch_set":2,"id":"630967c7_e4beba3f","line":222,"updated":"2021-09-02 10:14:09.000000000","message":"please update the doc with the 3rd return value","commit_id":"133fca1e9b0f5d5b8690bf00e918f11234206065"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"eb58436ced81535a7c2e09caa52c0d30afae6eaa","unresolved":true,"context_lines":[{"line_number":219,"context_line":"    :param data: A dictionary of multiple allocations by consumer uuid."},{"line_number":220,"context_line":"    :param want_version: the microversion matcher."},{"line_number":221,"context_line":"    :return: A tuple of a dict of all consumer objects (by consumer uuid)"},{"line_number":222,"context_line":"             and a list of those consumer objects which are new."},{"line_number":223,"context_line":"    \"\"\""},{"line_number":224,"context_line":"    # First, ensure that all consumers referenced in the payload actually"},{"line_number":225,"context_line":"    # exist. And if not, create them. Keep a record of auto-created consumers"}],"source_content_type":"text/x-python","patch_set":2,"id":"744932f8_ffb55ac3","line":222,"in_reply_to":"630967c7_e4beba3f","updated":"2021-09-02 15:54:12.000000000","message":"Will do.","commit_id":"133fca1e9b0f5d5b8690bf00e918f11234206065"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"1c654cfcf5cc466e013281e42804bb106ceef64d","unresolved":false,"context_lines":[{"line_number":219,"context_line":"    :param data: A dictionary of multiple allocations by consumer uuid."},{"line_number":220,"context_line":"    :param want_version: the microversion matcher."},{"line_number":221,"context_line":"    :return: A tuple of a dict of all consumer objects (by consumer uuid)"},{"line_number":222,"context_line":"             and a list of those consumer objects which are new."},{"line_number":223,"context_line":"    \"\"\""},{"line_number":224,"context_line":"    # First, ensure that all consumers referenced in the payload actually"},{"line_number":225,"context_line":"    # exist. And if not, create them. Keep a record of auto-created consumers"}],"source_content_type":"text/x-python","patch_set":2,"id":"74f2f434_430dae23","line":222,"in_reply_to":"744932f8_ffb55ac3","updated":"2021-09-03 08:01:47.000000000","message":"Ack","commit_id":"133fca1e9b0f5d5b8690bf00e918f11234206065"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"20796967f9a925481999a56e09add337ff576603","unresolved":false,"context_lines":[{"line_number":451,"context_line":"            data_util.ensure_consumer("},{"line_number":452,"context_line":"                context, consumer_uuid, data.get(\u0027project_id\u0027),"},{"line_number":453,"context_line":"                data.get(\u0027user_id\u0027), data.get(\u0027consumer_generation\u0027),"},{"line_number":454,"context_line":"                data.get(\u0027consumer_type\u0027), want_version))"},{"line_number":455,"context_line":""},{"line_number":456,"context_line":"        for resource_provider_uuid, allocation in allocation_data.items():"},{"line_number":457,"context_line":"            resource_provider \u003d rp_objs[resource_provider_uuid]"}],"source_content_type":"text/x-python","patch_set":2,"id":"48477590_f726f318","line":454,"updated":"2021-09-02 10:14:09.000000000","message":"nit: this is duplicate code from the if branch. But it was duplicate before this patch so let\u0027s keep it.","commit_id":"133fca1e9b0f5d5b8690bf00e918f11234206065"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"cb28ae5fbdb21c1e724c01cc393a633e832c7d45","unresolved":false,"context_lines":[{"line_number":451,"context_line":"            data_util.ensure_consumer("},{"line_number":452,"context_line":"                context, consumer_uuid, data.get(\u0027project_id\u0027),"},{"line_number":453,"context_line":"                data.get(\u0027user_id\u0027), data.get(\u0027consumer_generation\u0027),"},{"line_number":454,"context_line":"                data.get(\u0027consumer_type\u0027), want_version))"},{"line_number":455,"context_line":""},{"line_number":456,"context_line":"        for resource_provider_uuid, allocation in allocation_data.items():"},{"line_number":457,"context_line":"            resource_provider \u003d rp_objs[resource_provider_uuid]"}],"source_content_type":"text/x-python","patch_set":2,"id":"0d3a5de8_33e5b69c","line":454,"in_reply_to":"3327118b_0351c65c","updated":"2021-09-02 20:34:12.000000000","message":"I went ahead and moved this duplication before the if branch.","commit_id":"133fca1e9b0f5d5b8690bf00e918f11234206065"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"eb58436ced81535a7c2e09caa52c0d30afae6eaa","unresolved":false,"context_lines":[{"line_number":451,"context_line":"            data_util.ensure_consumer("},{"line_number":452,"context_line":"                context, consumer_uuid, data.get(\u0027project_id\u0027),"},{"line_number":453,"context_line":"                data.get(\u0027user_id\u0027), data.get(\u0027consumer_generation\u0027),"},{"line_number":454,"context_line":"                data.get(\u0027consumer_type\u0027), want_version))"},{"line_number":455,"context_line":""},{"line_number":456,"context_line":"        for resource_provider_uuid, allocation in allocation_data.items():"},{"line_number":457,"context_line":"            resource_provider \u003d rp_objs[resource_provider_uuid]"}],"source_content_type":"text/x-python","patch_set":2,"id":"3327118b_0351c65c","line":454,"in_reply_to":"48477590_f726f318","updated":"2021-09-02 15:54:12.000000000","message":"Yeah, agree this looks even more duplicated with the new change.","commit_id":"133fca1e9b0f5d5b8690bf00e918f11234206065"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"20796967f9a925481999a56e09add337ff576603","unresolved":false,"context_lines":[{"line_number":464,"context_line":"    @db_api.placement_context_manager.writer"},{"line_number":465,"context_line":"    def _update_consumers_and_create_allocations(ctx, consumers):"},{"line_number":466,"context_line":"        # Update consumer attributes if requested attributes are different."},{"line_number":467,"context_line":"        # NOTE(melwitt): This will not raise ConcurrentUpdateDetected, that"},{"line_number":468,"context_line":"        # happens later in AllocationList.replace_all()"},{"line_number":469,"context_line":"        data_util.update_consumers(consumers, {consumer_uuid: request_attr})"},{"line_number":470,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"627c47e7_5eb4a3b5","line":467,"range":{"start_line":467,"start_character":35,"end_line":467,"end_character":69},"updated":"2021-09-02 10:14:09.000000000","message":"and that is OK as when the replace_all() detects the conflict we still get the whole transaction rolled back including the consumer update. ✔","commit_id":"133fca1e9b0f5d5b8690bf00e918f11234206065"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"20796967f9a925481999a56e09add337ff576603","unresolved":true,"context_lines":[{"line_number":576,"context_line":"        # alloc_obj.replace_all() call, which will mean all the changes"},{"line_number":577,"context_line":"        # happen within a single transaction and with resource provider"},{"line_number":578,"context_line":"        # and consumer generations (if applicable) check all in one go."},{"line_number":579,"context_line":"        allocations \u003d create_allocation_list(ctx, data, consumers)"},{"line_number":580,"context_line":""},{"line_number":581,"context_line":"        alloc_obj.replace_all(ctx, allocations)"},{"line_number":582,"context_line":"        LOG.debug(\"Successfully wrote allocations %s\", allocations)"}],"source_content_type":"text/x-python","patch_set":2,"id":"9c3f2318_c5415bd2","line":579,"updated":"2021-09-02 10:14:09.000000000","message":"It was outside of the transaction but now this is part of it. It is not wrong, but I think it might be unnecessary as the create_allocation_list only creates objects in memory only the replace_all() call will persist them in the db.","commit_id":"133fca1e9b0f5d5b8690bf00e918f11234206065"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"eb58436ced81535a7c2e09caa52c0d30afae6eaa","unresolved":true,"context_lines":[{"line_number":576,"context_line":"        # alloc_obj.replace_all() call, which will mean all the changes"},{"line_number":577,"context_line":"        # happen within a single transaction and with resource provider"},{"line_number":578,"context_line":"        # and consumer generations (if applicable) check all in one go."},{"line_number":579,"context_line":"        allocations \u003d create_allocation_list(ctx, data, consumers)"},{"line_number":580,"context_line":""},{"line_number":581,"context_line":"        alloc_obj.replace_all(ctx, allocations)"},{"line_number":582,"context_line":"        LOG.debug(\"Successfully wrote allocations %s\", allocations)"}],"source_content_type":"text/x-python","patch_set":2,"id":"ddba28d4_d5a8c714","line":579,"in_reply_to":"9c3f2318_c5415bd2","updated":"2021-09-02 15:54:12.000000000","message":"Yes I think it is unnecessary to be inside the transaction, I think you are right that it only prepares the Allocation objects. I was a bit wary of passing in the consumers before updating them but it would probably be OK.","commit_id":"133fca1e9b0f5d5b8690bf00e918f11234206065"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"10775d43d3fc5aead092b9031718f04f475a02f3","unresolved":true,"context_lines":[{"line_number":458,"context_line":"        # happens later in AllocationList.replace_all()"},{"line_number":459,"context_line":"        data_util.update_consumers(consumers, {consumer_uuid: request_attr})"},{"line_number":460,"context_line":""},{"line_number":461,"context_line":"        alloc_obj.replace_all(context, allocation_objects)"},{"line_number":462,"context_line":"        LOG.debug(\"Successfully wrote allocations %s\", allocation_objects)"},{"line_number":463,"context_line":""},{"line_number":464,"context_line":"    def _create_allocations():"}],"source_content_type":"text/x-python","patch_set":3,"id":"934fc211_77a0720f","line":461,"range":{"start_line":461,"start_character":30,"end_line":461,"end_character":37},"updated":"2021-09-02 22:10:20.000000000","message":"ctx","commit_id":"bee5b4a8ae7acb0c5b43f20bef6a60a95bc85df0"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"1948dd50b0c3b27f059574861c8a0711a37dda37","unresolved":true,"context_lines":[{"line_number":451,"context_line":"                                               allocation[\u0027resources\u0027])"},{"line_number":452,"context_line":"            allocation_objects.extend(new_allocations)"},{"line_number":453,"context_line":""},{"line_number":454,"context_line":"    @db_api.placement_context_manager.writer"},{"line_number":455,"context_line":"    def _update_consumers_and_create_allocations(ctx):"},{"line_number":456,"context_line":"        # Update consumer attributes if requested attributes are different."},{"line_number":457,"context_line":"        # NOTE(melwitt): This will not raise ConcurrentUpdateDetected, that"}],"source_content_type":"text/x-python","patch_set":4,"id":"5c3c1e68_c65dad69","line":454,"updated":"2021-09-03 10:58:26.000000000","message":"I just found another issue with even this limited transaction scope widening. \n\nBefore consumer_types, the call graph was like\n_set_allocations_for_consumer() -\u003e _create_allocations() -\u003e alloc_obj.replace_all() -\u003e [retry-loop] -\u003e _set_allocations() [starting transaction]\n\nSo before consumer_types the retry-loop in replace_all called _set_allocations() in separate transactions. Now that the transaction is started here around _create_allocation() that retry loop will call _set_allocation() within the same transaction.\n\nWe have the retry-loop to handle resource provider generation conflict. (In contrast a consumer generation conflict has no retry and raised back the the client) This could happen even if two separate consumers are created / update / deleted in parallel affecting the same resource provider (or an allocation update can race with an inventory update). This type of conflict during allocation update can be retried server side, by re-reading the rp inventory/usage and RP generation to see the result of the parallel update, and re-applying the allocation change against the new inventory. If it fits the new inventory then we are OK without asking the client to retry. \n\nNow with the wider transaction scope we made this retry-loop useless. The re-reading of the RP inventory happens in the same transaction in every retry attempt and due to proper transaction isolation it re-reads the old RP inventory with the old RP generation. Then if fails with the same RP generation conflict as the first time.\n\nHere is an example of the result:\n\nTwo parallel test:\nA) resize confirm -\u003e req-dcbdd92b-c388-4a4a-b24a-216fb0d4a0fb deleting migration alloc 1582409f-6a32-457d-bfe6-26ae3b2b80b6 (instance b2d7104b-5020-4ab1-9146-0a52cd0f70a2)\nB) instance boot -\u003e req-448bea03-25a6-4d6a-a930-2f6acd7d7443 creating instance alloc ad20cf43-efa8-418b-b66b-8e0ac5655ce6\n\nYou can follow the sequence from the placement log[2]:\n\n1) A reads alloc (inc both consumer and rp generation)\n2) B creates alloc (creates an independent consumer with gen 0 but bumps the rp generation by that)\n3) A tries to delete alloc -\u003e rp generation conflict \n\n\nIf we cannot start an independent transaction for the RP re-read in the retry-loop then I think we have to move the consumer update down to the retry-loop to allow the retry-loop to use separate transactions for each retry attempt.\n\n\n[1] https://zuul.opendev.org/t/openstack/build/c0f131d357ee42d08e33b48501c88af4/log/controller/logs/screen-placement-api.txt#3897-3920\n[2] https://zuul.opendev.org/t/openstack/build/c0f131d357ee42d08e33b48501c88af4/log/controller/logs/screen-n-cpu.txt#41767","commit_id":"61957566adb49aa6c65271f699df72a4dc398d36"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"a2f48c449cd0763fb78ad4b8a5a73ecb854d1bcb","unresolved":true,"context_lines":[{"line_number":451,"context_line":"                                               allocation[\u0027resources\u0027])"},{"line_number":452,"context_line":"            allocation_objects.extend(new_allocations)"},{"line_number":453,"context_line":""},{"line_number":454,"context_line":"    @db_api.placement_context_manager.writer"},{"line_number":455,"context_line":"    def _update_consumers_and_create_allocations(ctx):"},{"line_number":456,"context_line":"        # Update consumer attributes if requested attributes are different."},{"line_number":457,"context_line":"        # NOTE(melwitt): This will not raise ConcurrentUpdateDetected, that"}],"source_content_type":"text/x-python","patch_set":4,"id":"ed3b4bae_281cb928","line":454,"in_reply_to":"5c3c1e68_c65dad69","updated":"2021-09-03 11:34:45.000000000","message":"another example:\nhttps://zuul.opendev.org/t/openstack/build/07b56894dee540698a53128ed5b363df/log/controller/logs/screen-placement-api.txt#809-824","commit_id":"61957566adb49aa6c65271f699df72a4dc398d36"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"dab5b56f0afdb90c83a4476002649f3c4439ca93","unresolved":true,"context_lines":[{"line_number":443,"context_line":"        # If the body includes an allocation for a resource provider"},{"line_number":444,"context_line":"        # that does not exist, raise a 400."},{"line_number":445,"context_line":"        rp_objs \u003d _resource_providers_by_uuid(context, allocation_data.keys())"},{"line_number":446,"context_line":"        consumer, created_new_consumer \u003d data_util.ensure_consumer("},{"line_number":447,"context_line":"            context, consumer_uuid, data.get(\u0027project_id\u0027),"},{"line_number":448,"context_line":"            data.get(\u0027user_id\u0027), data.get(\u0027consumer_generation\u0027),"},{"line_number":449,"context_line":"            data.get(\u0027consumer_type\u0027), want_version)"}],"source_content_type":"text/x-python","patch_set":6,"id":"acf352f7_3eda46bc","side":"PARENT","line":446,"updated":"2021-09-10 10:43:47.000000000","message":"and then you removed the third call.","commit_id":"8b000867ca50ca99877fe8819785918aa6f58764"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"dab5b56f0afdb90c83a4476002649f3c4439ca93","unresolved":true,"context_lines":[{"line_number":205,"context_line":"    return allocation_objects"},{"line_number":206,"context_line":""},{"line_number":207,"context_line":""},{"line_number":208,"context_line":"def inspect_consumers(context, data, want_version):"},{"line_number":209,"context_line":"    \"\"\"Look at consumer data in allocations and create consumers as needed."},{"line_number":210,"context_line":""},{"line_number":211,"context_line":"    Keep a record of the consumers that are created in case they need"}],"source_content_type":"text/x-python","patch_set":6,"id":"06fd7304_e4d1f0fc","line":208,"updated":"2021-09-10 10:43:47.000000000","message":"just checked and inspect_consumers() is only used in two calls which are changed.","commit_id":"5ace386efe0026edd4bdddedfafc5c89c5aca969"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"dab5b56f0afdb90c83a4476002649f3c4439ca93","unresolved":true,"context_lines":[{"line_number":241,"context_line":"        consumer_type \u003d data[consumer_uuid].get(\u0027consumer_type\u0027)"},{"line_number":242,"context_line":"        try:"},{"line_number":243,"context_line":"            consumer, new_consumer_created, request_attr \u003d ("},{"line_number":244,"context_line":"                data_util.ensure_consumer("},{"line_number":245,"context_line":"                    context, consumer_uuid, project_id,"},{"line_number":246,"context_line":"                    user_id, consumer_generation, consumer_type, want_version))"},{"line_number":247,"context_line":"            if new_consumer_created:"}],"source_content_type":"text/x-python","patch_set":6,"id":"8b077b24_134cb694","line":244,"updated":"2021-09-10 10:43:47.000000000","message":"first change for the new returned tuple","commit_id":"5ace386efe0026edd4bdddedfafc5c89c5aca969"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"dab5b56f0afdb90c83a4476002649f3c4439ca93","unresolved":true,"context_lines":[{"line_number":422,"context_line":"    # This needs to be done in separate database transactions so that the"},{"line_number":423,"context_line":"    # records can be read after a create collision due to a racing request."},{"line_number":424,"context_line":"    consumer, created_new_consumer, request_attr \u003d ("},{"line_number":425,"context_line":"        data_util.ensure_consumer("},{"line_number":426,"context_line":"            context, consumer_uuid, data.get(\u0027project_id\u0027),"},{"line_number":427,"context_line":"            data.get(\u0027user_id\u0027), data.get(\u0027consumer_generation\u0027),"},{"line_number":428,"context_line":"            data.get(\u0027consumer_type\u0027), want_version))"}],"source_content_type":"text/x-python","patch_set":6,"id":"2dc5e754_7c3644c3","line":425,"updated":"2021-09-10 10:43:47.000000000","message":"second change for the new returned tuple","commit_id":"5ace386efe0026edd4bdddedfafc5c89c5aca969"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"bd95cd6f3398e8ff7b1ce5a5fe1141c8afa46005","unresolved":true,"context_lines":[{"line_number":466,"context_line":"            # NOTE(melwitt): Group the consumer and allocation database updates"},{"line_number":467,"context_line":"            # in a single transaction so that updates get rolled back"},{"line_number":468,"context_line":"            # automatically in the event of a consumer generation conflict."},{"line_number":469,"context_line":"            _update_consumers_and_create_allocations(context)"},{"line_number":470,"context_line":"        except Exception:"},{"line_number":471,"context_line":"            with excutils.save_and_reraise_exception():"},{"line_number":472,"context_line":"                if created_new_consumer:"}],"source_content_type":"text/x-python","patch_set":6,"id":"f463e5d8_18dec24e","line":469,"range":{"start_line":469,"start_character":53,"end_line":469,"end_character":60},"updated":"2021-09-10 13:49:21.000000000","message":"warning, you\u0027re creating a closure given you\u0027re referencing the context object in the enclosing method, but it looks good eventually.","commit_id":"5ace386efe0026edd4bdddedfafc5c89c5aca969"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"dab5b56f0afdb90c83a4476002649f3c4439ca93","unresolved":true,"context_lines":[{"line_number":553,"context_line":"        want_schema \u003d schema.POST_ALLOCATIONS_V1_38"},{"line_number":554,"context_line":"    data \u003d util.extract_json(req.body, want_schema)"},{"line_number":555,"context_line":""},{"line_number":556,"context_line":"    consumers, new_consumers_created, requested_attrs \u003d inspect_consumers("},{"line_number":557,"context_line":"        context, data, want_version)"},{"line_number":558,"context_line":"    # Create a sequence of allocation objects to be used in one"},{"line_number":559,"context_line":"    # alloc_obj.replace_all() call, which will mean all the changes happen"}],"source_content_type":"text/x-python","patch_set":6,"id":"fb7780cf_a0e2944d","line":556,"updated":"2021-09-10 10:43:47.000000000","message":"first call of inspect_consumers() which returns a new tuple","commit_id":"5ace386efe0026edd4bdddedfafc5c89c5aca969"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"bd95cd6f3398e8ff7b1ce5a5fe1141c8afa46005","unresolved":true,"context_lines":[{"line_number":580,"context_line":"        except Exception:"},{"line_number":581,"context_line":"            with excutils.save_and_reraise_exception():"},{"line_number":582,"context_line":"                delete_consumers(new_consumers_created)"},{"line_number":583,"context_line":""},{"line_number":584,"context_line":"    try:"},{"line_number":585,"context_line":"        _create_allocations()"},{"line_number":586,"context_line":"    except exception.NotFound as exc:"}],"source_content_type":"text/x-python","patch_set":6,"id":"7f71d65e_f1e3088b","line":583,"updated":"2021-09-10 13:49:21.000000000","message":"the two above mthods seem to be identical to L455 and below, we could have factorized those instead of using nested functions.","commit_id":"5ace386efe0026edd4bdddedfafc5c89c5aca969"}],"placement/handlers/reshaper.py":[{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"20796967f9a925481999a56e09add337ff576603","unresolved":true,"context_lines":[{"line_number":122,"context_line":"            with excutils.save_and_reraise_exception():"},{"line_number":123,"context_line":"                allocation.delete_consumers(new_consumers_created)"},{"line_number":124,"context_line":""},{"line_number":125,"context_line":"    # Nest exception handling so that any exception results in new consumer"},{"line_number":126,"context_line":"    # objects being deleted, then reraise for translating to HTTP"},{"line_number":127,"context_line":"    # exceptions."},{"line_number":128,"context_line":"    try:"}],"source_content_type":"text/x-python","patch_set":2,"id":"1f481ebb_18f00534","line":125,"range":{"start_line":125,"start_character":6,"end_line":125,"end_character":29},"updated":"2021-09-02 10:14:09.000000000","message":"nit: you actually resolve this ugliness by pulling the creation out to a separate method that handles the cleanup too. So I think this code comment can be dropped","commit_id":"133fca1e9b0f5d5b8690bf00e918f11234206065"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"eb58436ced81535a7c2e09caa52c0d30afae6eaa","unresolved":true,"context_lines":[{"line_number":122,"context_line":"            with excutils.save_and_reraise_exception():"},{"line_number":123,"context_line":"                allocation.delete_consumers(new_consumers_created)"},{"line_number":124,"context_line":""},{"line_number":125,"context_line":"    # Nest exception handling so that any exception results in new consumer"},{"line_number":126,"context_line":"    # objects being deleted, then reraise for translating to HTTP"},{"line_number":127,"context_line":"    # exceptions."},{"line_number":128,"context_line":"    try:"}],"source_content_type":"text/x-python","patch_set":2,"id":"cfcacbef_8e96f4f3","line":125,"range":{"start_line":125,"start_character":6,"end_line":125,"end_character":29},"in_reply_to":"1f481ebb_18f00534","updated":"2021-09-02 15:54:12.000000000","message":"Oh you are right, I missed that. Will drop.","commit_id":"133fca1e9b0f5d5b8690bf00e918f11234206065"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"1c654cfcf5cc466e013281e42804bb106ceef64d","unresolved":false,"context_lines":[{"line_number":122,"context_line":"            with excutils.save_and_reraise_exception():"},{"line_number":123,"context_line":"                allocation.delete_consumers(new_consumers_created)"},{"line_number":124,"context_line":""},{"line_number":125,"context_line":"    # Nest exception handling so that any exception results in new consumer"},{"line_number":126,"context_line":"    # objects being deleted, then reraise for translating to HTTP"},{"line_number":127,"context_line":"    # exceptions."},{"line_number":128,"context_line":"    try:"}],"source_content_type":"text/x-python","patch_set":2,"id":"3ce0d0de_87b08a97","line":125,"range":{"start_line":125,"start_character":6,"end_line":125,"end_character":29},"in_reply_to":"cfcacbef_8e96f4f3","updated":"2021-09-03 08:01:47.000000000","message":"Ack","commit_id":"133fca1e9b0f5d5b8690bf00e918f11234206065"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"878a09c7abe2bd037220b6389832f269e44f025f","unresolved":true,"context_lines":[{"line_number":126,"context_line":"    # objects being deleted, then reraise for translating to HTTP"},{"line_number":127,"context_line":"    # exceptions."},{"line_number":128,"context_line":"    try:"},{"line_number":129,"context_line":"        _create_allocations()"},{"line_number":130,"context_line":"    # Generation conflict is a (rare) possibility in a few different"},{"line_number":131,"context_line":"    # places in reshape()."},{"line_number":132,"context_line":"    except exception.ConcurrentUpdateDetected as exc:"}],"source_content_type":"text/x-python","patch_set":2,"id":"53a80856_e6c1d4c4","line":129,"updated":"2021-09-02 08:53:52.000000000","message":"Noting that this code needs test coverage similar to set_allocations*.","commit_id":"133fca1e9b0f5d5b8690bf00e918f11234206065"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"10775d43d3fc5aead092b9031718f04f475a02f3","unresolved":true,"context_lines":[{"line_number":102,"context_line":"        # happens later in AllocationList.replace_all()"},{"line_number":103,"context_line":"        data_util.update_consumers(consumers.values(), requested_attrs)"},{"line_number":104,"context_line":""},{"line_number":105,"context_line":"        # When these allocations are created they get resource provider objects"},{"line_number":106,"context_line":"        # which are different instances (usually with the same data) from those"},{"line_number":107,"context_line":"        # loaded above when creating inventory objects.  The reshape method"},{"line_number":108,"context_line":"        # below is responsible for ensuring that the resource providers and"},{"line_number":109,"context_line":"        # their generations do not conflict."},{"line_number":110,"context_line":"        allocation_objects \u003d allocation.create_allocation_list("},{"line_number":111,"context_line":"            ctx, allocations, consumers)"},{"line_number":112,"context_line":""},{"line_number":113,"context_line":"        reshaper.reshape(ctx, inventory_by_rp, allocation_objects)"},{"line_number":114,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"943decc4_d33894e6","line":111,"range":{"start_line":105,"start_character":0,"end_line":111,"end_character":40},"updated":"2021-09-02 22:10:20.000000000","message":"Just noticed this can go outside the nested method too, similar to placement/handlers/allocation.py","commit_id":"bee5b4a8ae7acb0c5b43f20bef6a60a95bc85df0"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"dab5b56f0afdb90c83a4476002649f3c4439ca93","unresolved":true,"context_lines":[{"line_number":93,"context_line":""},{"line_number":94,"context_line":"    # Make the consumer objects associated with the allocations."},{"line_number":95,"context_line":"    consumers, new_consumers_created, requested_attrs \u003d ("},{"line_number":96,"context_line":"        allocation.inspect_consumers(context, allocations, want_version))"},{"line_number":97,"context_line":""},{"line_number":98,"context_line":"    # When these allocations are created they get resource provider objects"},{"line_number":99,"context_line":"    # which are different instances (usually with the same data) from those"}],"source_content_type":"text/x-python","patch_set":6,"id":"a25da6c6_2c218de2","line":96,"updated":"2021-09-10 10:43:47.000000000","message":"second call of inspect_consumers() which changes the returned tuple","commit_id":"5ace386efe0026edd4bdddedfafc5c89c5aca969"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"bd95cd6f3398e8ff7b1ce5a5fe1141c8afa46005","unresolved":true,"context_lines":[{"line_number":120,"context_line":"            _update_consumers_and_create_allocations(context)"},{"line_number":121,"context_line":"        except Exception:"},{"line_number":122,"context_line":"            with excutils.save_and_reraise_exception():"},{"line_number":123,"context_line":"                allocation.delete_consumers(new_consumers_created)"},{"line_number":124,"context_line":""},{"line_number":125,"context_line":"    try:"},{"line_number":126,"context_line":"        _create_allocations()"}],"source_content_type":"text/x-python","patch_set":6,"id":"0226d170_18e77ecc","line":123,"updated":"2021-09-10 13:49:21.000000000","message":"again, same logic from allocation.py \nMaybe making those nested functions be first-citizens would have reduced the duplicity.","commit_id":"5ace386efe0026edd4bdddedfafc5c89c5aca969"}],"placement/handlers/util.py":[{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"20796967f9a925481999a56e09add337ff576603","unresolved":true,"context_lines":[{"line_number":105,"context_line":"    \"\"\"Ensures there are records in the consumers, projects and users table for"},{"line_number":106,"context_line":"    the supplied external identifiers."},{"line_number":107,"context_line":""},{"line_number":108,"context_line":"    Returns a tuple containing the populated Consumer object containing Project"},{"line_number":109,"context_line":"    and User sub-objects and a boolean indicating whether a new Consumer object"},{"line_number":110,"context_line":"    was created (as opposed to an existing consumer record retrieved)"},{"line_number":111,"context_line":""},{"line_number":112,"context_line":"    :note: If the supplied project or user external identifiers do not match an"},{"line_number":113,"context_line":"           existing consumer\u0027s project and user identifiers, the existing"}],"source_content_type":"text/x-python","patch_set":2,"id":"a6985aaa_e68fc277","line":110,"range":{"start_line":108,"start_character":4,"end_line":110,"end_character":69},"updated":"2021-09-02 10:14:09.000000000","message":"this needs to be updated with the additional return value","commit_id":"133fca1e9b0f5d5b8690bf00e918f11234206065"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"eb58436ced81535a7c2e09caa52c0d30afae6eaa","unresolved":true,"context_lines":[{"line_number":105,"context_line":"    \"\"\"Ensures there are records in the consumers, projects and users table for"},{"line_number":106,"context_line":"    the supplied external identifiers."},{"line_number":107,"context_line":""},{"line_number":108,"context_line":"    Returns a tuple containing the populated Consumer object containing Project"},{"line_number":109,"context_line":"    and User sub-objects and a boolean indicating whether a new Consumer object"},{"line_number":110,"context_line":"    was created (as opposed to an existing consumer record retrieved)"},{"line_number":111,"context_line":""},{"line_number":112,"context_line":"    :note: If the supplied project or user external identifiers do not match an"},{"line_number":113,"context_line":"           existing consumer\u0027s project and user identifiers, the existing"}],"source_content_type":"text/x-python","patch_set":2,"id":"eb9dffe9_be149363","line":110,"range":{"start_line":108,"start_character":4,"end_line":110,"end_character":69},"in_reply_to":"a6985aaa_e68fc277","updated":"2021-09-02 15:54:12.000000000","message":"Ack","commit_id":"133fca1e9b0f5d5b8690bf00e918f11234206065"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"1c654cfcf5cc466e013281e42804bb106ceef64d","unresolved":false,"context_lines":[{"line_number":105,"context_line":"    \"\"\"Ensures there are records in the consumers, projects and users table for"},{"line_number":106,"context_line":"    the supplied external identifiers."},{"line_number":107,"context_line":""},{"line_number":108,"context_line":"    Returns a tuple containing the populated Consumer object containing Project"},{"line_number":109,"context_line":"    and User sub-objects and a boolean indicating whether a new Consumer object"},{"line_number":110,"context_line":"    was created (as opposed to an existing consumer record retrieved)"},{"line_number":111,"context_line":""},{"line_number":112,"context_line":"    :note: If the supplied project or user external identifiers do not match an"},{"line_number":113,"context_line":"           existing consumer\u0027s project and user identifiers, the existing"}],"source_content_type":"text/x-python","patch_set":2,"id":"bfabd4f6_0f1c93fa","line":110,"range":{"start_line":108,"start_character":4,"end_line":110,"end_character":69},"in_reply_to":"eb9dffe9_be149363","updated":"2021-09-03 08:01:47.000000000","message":"Ack","commit_id":"133fca1e9b0f5d5b8690bf00e918f11234206065"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"20796967f9a925481999a56e09add337ff576603","unresolved":true,"context_lines":[{"line_number":109,"context_line":"    and User sub-objects and a boolean indicating whether a new Consumer object"},{"line_number":110,"context_line":"    was created (as opposed to an existing consumer record retrieved)"},{"line_number":111,"context_line":""},{"line_number":112,"context_line":"    :note: If the supplied project or user external identifiers do not match an"},{"line_number":113,"context_line":"           existing consumer\u0027s project and user identifiers, the existing"},{"line_number":114,"context_line":"           consumer\u0027s project and user IDs are updated to reflect the supplied"},{"line_number":115,"context_line":"           ones."},{"line_number":116,"context_line":""},{"line_number":117,"context_line":"    :param ctx: The request context."},{"line_number":118,"context_line":"    :param consumer_uuid: The uuid of the consumer of the resources."}],"source_content_type":"text/x-python","patch_set":2,"id":"9f5a6665_c4dd2865","line":115,"range":{"start_line":112,"start_character":4,"end_line":115,"end_character":16},"updated":"2021-09-02 10:14:09.000000000","message":"I think this logic is moved to update_consumers() now","commit_id":"133fca1e9b0f5d5b8690bf00e918f11234206065"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"1c654cfcf5cc466e013281e42804bb106ceef64d","unresolved":false,"context_lines":[{"line_number":109,"context_line":"    and User sub-objects and a boolean indicating whether a new Consumer object"},{"line_number":110,"context_line":"    was created (as opposed to an existing consumer record retrieved)"},{"line_number":111,"context_line":""},{"line_number":112,"context_line":"    :note: If the supplied project or user external identifiers do not match an"},{"line_number":113,"context_line":"           existing consumer\u0027s project and user identifiers, the existing"},{"line_number":114,"context_line":"           consumer\u0027s project and user IDs are updated to reflect the supplied"},{"line_number":115,"context_line":"           ones."},{"line_number":116,"context_line":""},{"line_number":117,"context_line":"    :param ctx: The request context."},{"line_number":118,"context_line":"    :param consumer_uuid: The uuid of the consumer of the resources."}],"source_content_type":"text/x-python","patch_set":2,"id":"9fd376c9_35f0a0bd","line":115,"range":{"start_line":112,"start_character":4,"end_line":115,"end_character":16},"in_reply_to":"2b863ef2_070a90db","updated":"2021-09-03 08:01:47.000000000","message":"Ack","commit_id":"133fca1e9b0f5d5b8690bf00e918f11234206065"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"eb58436ced81535a7c2e09caa52c0d30afae6eaa","unresolved":true,"context_lines":[{"line_number":109,"context_line":"    and User sub-objects and a boolean indicating whether a new Consumer object"},{"line_number":110,"context_line":"    was created (as opposed to an existing consumer record retrieved)"},{"line_number":111,"context_line":""},{"line_number":112,"context_line":"    :note: If the supplied project or user external identifiers do not match an"},{"line_number":113,"context_line":"           existing consumer\u0027s project and user identifiers, the existing"},{"line_number":114,"context_line":"           consumer\u0027s project and user IDs are updated to reflect the supplied"},{"line_number":115,"context_line":"           ones."},{"line_number":116,"context_line":""},{"line_number":117,"context_line":"    :param ctx: The request context."},{"line_number":118,"context_line":"    :param consumer_uuid: The uuid of the consumer of the resources."}],"source_content_type":"text/x-python","patch_set":2,"id":"2b863ef2_070a90db","line":115,"range":{"start_line":112,"start_character":4,"end_line":115,"end_character":16},"in_reply_to":"9f5a6665_c4dd2865","updated":"2021-09-02 15:54:12.000000000","message":"True, need to fix.","commit_id":"133fca1e9b0f5d5b8690bf00e918f11234206065"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"20796967f9a925481999a56e09add337ff576603","unresolved":false,"context_lines":[{"line_number":167,"context_line":"            cons_type_id \u003d get_or_create_consumer_type_id(ctx, consumer_type)"},{"line_number":168,"context_line":"        # No such consumer. This is common for new allocations. Create the"},{"line_number":169,"context_line":"        # consumer record"},{"line_number":170,"context_line":"        consumer, created_new_consumer \u003d _create_consumer("},{"line_number":171,"context_line":"            ctx, consumer_uuid, proj, user, cons_type_id)"},{"line_number":172,"context_line":""},{"line_number":173,"context_line":"    # Also return the project, user, and consumer type from the request to use"}],"source_content_type":"text/x-python","patch_set":2,"id":"380b2222_859e11e5","line":170,"range":{"start_line":170,"start_character":41,"end_line":170,"end_character":57},"updated":"2021-09-02 10:14:09.000000000","message":"this is OK to be outside the big transaction as there is a separate logic that deletes the consumer if the allocation update fails","commit_id":"133fca1e9b0f5d5b8690bf00e918f11234206065"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"dab5b56f0afdb90c83a4476002649f3c4439ca93","unresolved":true,"context_lines":[{"line_number":100,"context_line":"    return consumer, created_new_consumer"},{"line_number":101,"context_line":""},{"line_number":102,"context_line":""},{"line_number":103,"context_line":"def ensure_consumer(ctx, consumer_uuid, project_id, user_id,"},{"line_number":104,"context_line":"                    consumer_generation, consumer_type, want_version):"},{"line_number":105,"context_line":"    \"\"\"Ensures there are records in the consumers, projects and users table for"},{"line_number":106,"context_line":"    the supplied external identifiers."}],"source_content_type":"text/x-python","patch_set":6,"id":"e4180f7a_fa3761fc","line":103,"updated":"2021-09-10 10:43:47.000000000","message":"verified by ensure_consumer is only called three times in allocation.py which are both changed.","commit_id":"5ace386efe0026edd4bdddedfafc5c89c5aca969"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"dab5b56f0afdb90c83a4476002649f3c4439ca93","unresolved":true,"context_lines":[{"line_number":148,"context_line":"                    },"},{"line_number":149,"context_line":"                    comment\u003derrors.CONCURRENT_UPDATE)"},{"line_number":150,"context_line":"        if requires_consumer_type:"},{"line_number":151,"context_line":"            cons_type_id \u003d get_or_create_consumer_type_id(ctx, consumer_type)"},{"line_number":152,"context_line":"    except exception.NotFound:"},{"line_number":153,"context_line":"        # If we are attempting to modify or create allocations after 1.26, we"},{"line_number":154,"context_line":"        # need a consumer generation specified. The user must have specified"}],"source_content_type":"text/x-python","patch_set":6,"id":"aad20842_5b38083a","line":151,"updated":"2021-09-10 10:43:47.000000000","message":"we ensure here that the consumer type is created.","commit_id":"5ace386efe0026edd4bdddedfafc5c89c5aca969"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"dab5b56f0afdb90c83a4476002649f3c4439ca93","unresolved":true,"context_lines":[{"line_number":154,"context_line":"        # need a consumer generation specified. The user must have specified"},{"line_number":155,"context_line":"        # None for the consumer generation if we get here, since there was no"},{"line_number":156,"context_line":"        # existing consumer with this UUID and therefore the user should be"},{"line_number":157,"context_line":"        # indicating that they expect the consumer did not exist."},{"line_number":158,"context_line":"        if requires_consumer_generation:"},{"line_number":159,"context_line":"            if consumer_generation is not None:"},{"line_number":160,"context_line":"                raise webob.exc.HTTPConflict("}],"source_content_type":"text/x-python","patch_set":6,"id":"ff73e465_61338808","line":157,"updated":"2021-09-10 10:43:47.000000000","message":"excellent catch","commit_id":"5ace386efe0026edd4bdddedfafc5c89c5aca969"}],"placement/tests/functional/test_allocation.py":[{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"bd95cd6f3398e8ff7b1ce5a5fe1141c8afa46005","unresolved":true,"context_lines":[{"line_number":106,"context_line":"            # https://storyboard.openstack.org/#!/story/2009159 The expected"},{"line_number":107,"context_line":"            # behavior would be that the allocation update succeeds as the"},{"line_number":108,"context_line":"            # transaction can fetch the Project created by a racing transaction"},{"line_number":109,"context_line":"            self.assertEqual(204, resp.status_code)"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"    def test_set_allocations(self):"},{"line_number":112,"context_line":"        alloc_data \u003d jsonutils.dump_as_bytes({"}],"source_content_type":"text/x-python","patch_set":6,"id":"7460241f_d9b61f18","line":109,"updated":"2021-09-10 13:49:21.000000000","message":"huzzah","commit_id":"5ace386efe0026edd4bdddedfafc5c89c5aca969"}]}
