)]}'
{"nova/conductor/tasks/migrate.py":[{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"6b9a8e12026ef5f2e3fcbd49a385f4073fb401cd","unresolved":false,"context_lines":[{"line_number":98,"context_line":"    # allocations against the sharing provider during migration."},{"line_number":99,"context_line":"    success \u003d reportclient.move_allocations(context, migration.uuid,"},{"line_number":100,"context_line":"                                            instance.uuid,"},{"line_number":101,"context_line":"                                            target_is_new\u003dFalse)"},{"line_number":102,"context_line":"    if not success:"},{"line_number":103,"context_line":"        LOG.error(\u0027Unable to replace resource claim on source \u0027"},{"line_number":104,"context_line":"                  \u0027host %(host)s node %(node)s for instance\u0027,"}],"source_content_type":"text/x-python","patch_set":3,"id":"3fa7e38b_2b1c2b12","line":101,"updated":"2019-10-18 15:41:15.000000000","message":"ConsumerGenerationConflictTest.test_migrate_claim_on_dest_fails is failing because in that test, we move the instance allocations on the source node to the migration record and then fail to PUT allocations for the instance on the dest host during scheduling which triggers a NoValidHost and we rollback and revert here. At this point the source node allocations are held by the migration record and the target instance consumer doesn\u0027t have allocations (because scheduling failed) so when we call move_allocations here it deletes the source node allocations held by the migration record rather than putting them back on the instance consumer, so this target_is_new logic isn\u0027t sufficient. move_allocations doesn\u0027t have the context to know if the target consumer doesn\u0027t have allocations because (1) we failed to PUT the allocations during scheduling or (2) the target consumer was deleted out of band.\n\nSo that means we likely have to push that context into the caller (here) and determine if the instance still exists...and if it doesn\u0027t we probably shouldn\u0027t even call move_allocations but instead just call DELETE /allocations/{migration.uuid).","commit_id":"bb48d0a8060dd777df248983d891d484f4188adf"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"aac8ef5bbb30f318a909e659f5eda306c9eb4820","unresolved":false,"context_lines":[{"line_number":98,"context_line":"    # allocations against the sharing provider during migration."},{"line_number":99,"context_line":"    success \u003d reportclient.move_allocations(context, migration.uuid,"},{"line_number":100,"context_line":"                                            instance.uuid,"},{"line_number":101,"context_line":"                                            target_is_new\u003dFalse)"},{"line_number":102,"context_line":"    if not success:"},{"line_number":103,"context_line":"        LOG.error(\u0027Unable to replace resource claim on source \u0027"},{"line_number":104,"context_line":"                  \u0027host %(host)s node %(node)s for instance\u0027,"}],"source_content_type":"text/x-python","patch_set":3,"id":"3fa7e38b_4b0ba77c","line":101,"in_reply_to":"3fa7e38b_0ba04f91","updated":"2019-10-18 15:58:15.000000000","message":"efried correctly pointed out that the instance.refresh() approach still suffers from a race because by the time we get the allocations for the instance from placement and POST /allocations back the instance could be gone and we\u0027re re-create and leak the allocations.\n\nProbably need to do something like before calling move_allocations, get the allocations for the target consumer (the instance in this case) and if they don\u0027t exist, we delete the source node migration consumer allocations (like in the paste) but if the instance allocations *do* exist then we definitely want to pass the generation through to POST /allocations and if we lose the race we\u0027ll get a 409 from placement because the target consumer would be gone and we\u0027re asserting that it should exist (based on the generation).\n\nWhat would happen then though? Would move_allocations raise AllocationMoveFailed and we\u0027d handle that here and re-drive by getting the instance allocations and if they are gone delete the source node migration consumer allocations?","commit_id":"bb48d0a8060dd777df248983d891d484f4188adf"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"9669909235d82c4afe683e67a4ef4668eec67a8e","unresolved":false,"context_lines":[{"line_number":98,"context_line":"    # allocations against the sharing provider during migration."},{"line_number":99,"context_line":"    success \u003d reportclient.move_allocations(context, migration.uuid,"},{"line_number":100,"context_line":"                                            instance.uuid,"},{"line_number":101,"context_line":"                                            target_is_new\u003dFalse)"},{"line_number":102,"context_line":"    if not success:"},{"line_number":103,"context_line":"        LOG.error(\u0027Unable to replace resource claim on source \u0027"},{"line_number":104,"context_line":"                  \u0027host %(host)s node %(node)s for instance\u0027,"}],"source_content_type":"text/x-python","patch_set":3,"id":"3fa7e38b_2003cc75","line":101,"in_reply_to":"3fa7e38b_1329619a","updated":"2019-10-21 21:11:39.000000000","message":"I don\u0027t think the retry is the issue. For the bug I\u0027m trying to fix where allocations are leaked, during revert on a failed migration the migration allocations on the source node are moved to the instance with consumer_generation\u003dNone so they are created for the now-deleted instance.\n\nWhat I\u0027ve been thinking about is doing what you\u0027re saying we would *eventually* do, but I think is what we should probably do now for sanity. What I\u0027m thinking is writing a new SchedulerReportClient method that essentially wraps move_allocations for a specific case, e.g. move_allocations_ensure_target_consumer, and would do something like this:\n\n1. Get the allocations for the target consumer.\n\n2. If there are no target consumer allocs, check to see if the target exists based on type (e.g. Instance.refresh) - we have to do that somewhere to distinguish between:\n\n(a) reverting allocations on failure because the instance is gone and already deleted its allocations and\n\n(b) scheduling failed and never created any allocations but the instance still exists.\n\nIf (a) then just remove the source allocations.\nIf (b) then call move_allocations as normal.\n\n3. If there are target consumer allocs, pass them to move_allocations to enforce the target consumer generation (don\u0027t pass consumer_generation\u003dNone to re-create the consumer).\n\n4. If the move works, great, we\u0027re done\n\n5. If we get a consumer generation conflict, we need to re-drive from the outer method move_allocations_ensure_target_consumer since the instance might be gone at that point","commit_id":"bb48d0a8060dd777df248983d891d484f4188adf"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"81bd2cedb181b89b7fcb36bb70852348962b095e","unresolved":false,"context_lines":[{"line_number":98,"context_line":"    # allocations against the sharing provider during migration."},{"line_number":99,"context_line":"    success \u003d reportclient.move_allocations(context, migration.uuid,"},{"line_number":100,"context_line":"                                            instance.uuid,"},{"line_number":101,"context_line":"                                            target_is_new\u003dFalse)"},{"line_number":102,"context_line":"    if not success:"},{"line_number":103,"context_line":"        LOG.error(\u0027Unable to replace resource claim on source \u0027"},{"line_number":104,"context_line":"                  \u0027host %(host)s node %(node)s for instance\u0027,"}],"source_content_type":"text/x-python","patch_set":3,"id":"3fa7e38b_0ba04f91","line":101,"in_reply_to":"3fa7e38b_2b1c2b12","updated":"2019-10-18 15:48:29.000000000","message":"Thinking about doing something like this:\n\nhttp://paste.openstack.org/show/784726/","commit_id":"bb48d0a8060dd777df248983d891d484f4188adf"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"a635f41b34b55c900cf77455da6c255187d99c95","unresolved":false,"context_lines":[{"line_number":98,"context_line":"    # allocations against the sharing provider during migration."},{"line_number":99,"context_line":"    success \u003d reportclient.move_allocations(context, migration.uuid,"},{"line_number":100,"context_line":"                                            instance.uuid,"},{"line_number":101,"context_line":"                                            target_is_new\u003dFalse)"},{"line_number":102,"context_line":"    if not success:"},{"line_number":103,"context_line":"        LOG.error(\u0027Unable to replace resource claim on source \u0027"},{"line_number":104,"context_line":"                  \u0027host %(host)s node %(node)s for instance\u0027,"}],"source_content_type":"text/x-python","patch_set":3,"id":"3fa7e38b_1329619a","line":101,"in_reply_to":"3fa7e38b_4b0ba77c","updated":"2019-10-18 19:07:39.000000000","message":"(12:34:16 PM) efried: mriedem: Correct me if I\u0027m wrong, move_allocations needs to deal with these scenarios:\n(12:34:17 PM) efried: - (live/cold) migrate execute: source is instance, target is migration.\n(12:34:17 PM) efried: - revert, including from a failed migration: source is migration, target is instance.\n(12:34:17 PM) efried:     - In either case, if instance disappears, we want the operation fail, but that\u0027s something the caller needs to be aware of, not move_allocations itself.\n(12:34:17 PM) efried:     - If an oob operation updates the instance\u0027s allocs (which only applies to the execute case; I assume you can\u0027t resize an instance that\u0027s in CONFIRM_RESIZE or ERROR, right?) we also want the migration to fail.\n(12:34:17 PM) efried:       However, just like the delete thing that started you down this rathole, we can\u0027t close that window effectively while doing the GET from within move_allocations\n(12:34:17 PM) efried: So here\u0027s what I think needs to happen:\n(12:34:18 PM) efried: - move_allocations should always use \u0027allocations\u0027: {} to delete, never DELETE.\n(12:34:18 PM) efried: - move_allocations should *not retry on a consumer 409*; it should raise AllocationMoveFailed. It *should* retry on a *provider* 409 though. (This is a little complicated, and we have seen this issue elsewhere -- gibi L@@K.)\n(12:34:19 PM) efried: - Eventually (probably not now) the calling flows should be responsible for pulling the instance consumer (at least the generation, if not the whole allocation record) *early*, before entering the \"critical path\", and funneling that information into move_allocations. This is the only way we\u0027re going to effectively detect the race.\n(12:34:19 PM) efried: TL;DR the only thing that should change right now is: don\u0027t retry on consumer 409.","commit_id":"bb48d0a8060dd777df248983d891d484f4188adf"}],"nova/scheduler/client/report.py":[{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"8cc51c64dcd7f191b70564372336e61d51dc1486","unresolved":false,"context_lines":[{"line_number":1841,"context_line":""},{"line_number":1842,"context_line":"        If the target consumer no longer exists (does not have allocations)"},{"line_number":1843,"context_line":"        then the source consumer allocations are simply deleted."},{"line_number":1844,"context_line":""},{"line_number":1845,"context_line":"        :param context: The security context"},{"line_number":1846,"context_line":"        :param source_consumer_uuid: the UUID of the consumer from which"},{"line_number":1847,"context_line":"                                     allocations are moving"}],"source_content_type":"text/x-python","patch_set":1,"id":"3fa7e38b_43dde73e","line":1844,"updated":"2019-10-17 10:32:46.000000000","message":"I think the move_allocation is called with the below parameters during migration:\n\n* migrate:\n  source_consumer \u003d instance_uuid (holding allocation on the source host)\n  target_consumer \u003d migration_uuid (does not exists yet) \n\n* revert migrate:\n  source_consumer \u003d migration_uuid (holding allocation on the source host)\n  target_consumer \u003d instance_uuid (if it is a normal revert then this consumer exists and holds allocation on the dest, if the instance was deleted in the middle of scheduling then this consumer does not exists)\n\nSo simply deleting the source_consumer if the target_consumer does not exists is wrong for the first case.","commit_id":"20a6386397cf2c36ac94d1be8a201dda89ffaa68"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"b86b62089e273927709e3244a4d36ee74d702740","unresolved":false,"context_lines":[{"line_number":1841,"context_line":""},{"line_number":1842,"context_line":"        If the target consumer no longer exists (does not have allocations)"},{"line_number":1843,"context_line":"        then the source consumer allocations are simply deleted."},{"line_number":1844,"context_line":""},{"line_number":1845,"context_line":"        :param context: The security context"},{"line_number":1846,"context_line":"        :param source_consumer_uuid: the UUID of the consumer from which"},{"line_number":1847,"context_line":"                                     allocations are moving"}],"source_content_type":"text/x-python","patch_set":1,"id":"3fa7e38b_a78b8466","line":1844,"in_reply_to":"3fa7e38b_43dde73e","updated":"2019-10-17 13:53:27.000000000","message":"Yup, you\u0027re right, thanks for looking and saving me some time. I\u0027ll have to pass a kwarg to the method to tell it what to do if the target consumer does not exist.","commit_id":"20a6386397cf2c36ac94d1be8a201dda89ffaa68"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"b73fa5e196ad6fcbd82fa0e8652ff0cb933e9524","unresolved":false,"context_lines":[{"line_number":1880,"context_line":"            # therefore should have a consumer_generation so honor it."},{"line_number":1881,"context_line":"            target_consumer_gen \u003d target_alloc[\u0027consumer_generation\u0027]"},{"line_number":1882,"context_line":"        elif not target_is_new:"},{"line_number":1883,"context_line":"            # The target consumer no longer exists, just delete the"},{"line_number":1884,"context_line":"            # allocations for the source consumer."},{"line_number":1885,"context_line":"            LOG.info(\u0027Allocations not found for target consumer %s; \u0027"},{"line_number":1886,"context_line":"                     \u0027deleting allocations for source consumer %s only.\u0027,"}],"source_content_type":"text/x-python","patch_set":3,"id":"3fa7e38b_0b1cde11","line":1883,"range":{"start_line":1883,"start_character":34,"end_line":1883,"end_character":50},"updated":"2019-10-17 20:13:46.000000000","message":"...which only happens if the target consumer was deleted out of band -- that\u0027s the whole case you\u0027re trying to account for via this fix, right? IMO this comment should explain that a bit more, since the reader won\u0027t have the context of the commit message.","commit_id":"bb48d0a8060dd777df248983d891d484f4188adf"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"a332ccb1924d8ed7f953f06aadb827dbc0bbb3df","unresolved":false,"context_lines":[{"line_number":1880,"context_line":"            # therefore should have a consumer_generation so honor it."},{"line_number":1881,"context_line":"            target_consumer_gen \u003d target_alloc[\u0027consumer_generation\u0027]"},{"line_number":1882,"context_line":"        elif not target_is_new:"},{"line_number":1883,"context_line":"            # The target consumer no longer exists, just delete the"},{"line_number":1884,"context_line":"            # allocations for the source consumer."},{"line_number":1885,"context_line":"            LOG.info(\u0027Allocations not found for target consumer %s; \u0027"},{"line_number":1886,"context_line":"                     \u0027deleting allocations for source consumer %s only.\u0027,"}],"source_content_type":"text/x-python","patch_set":3,"id":"3fa7e38b_d004221b","line":1883,"range":{"start_line":1883,"start_character":34,"end_line":1883,"end_character":50},"in_reply_to":"3fa7e38b_0b1cde11","updated":"2019-10-18 15:27:37.000000000","message":"\u003e ...which only happens if the target consumer was deleted out of\n \u003e band -- that\u0027s the whole case you\u0027re trying to account for via this\n \u003e fix, right? IMO this comment should explain that a bit more, since\n \u003e the reader won\u0027t have the context of the commit message.\n\nSure, I can add something like, \"e.g. it was deleted concurrently during a move operation\".","commit_id":"bb48d0a8060dd777df248983d891d484f4188adf"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"b73fa5e196ad6fcbd82fa0e8652ff0cb933e9524","unresolved":false,"context_lines":[{"line_number":1887,"context_line":"                     target_consumer_uuid, source_consumer_uuid)"},{"line_number":1888,"context_line":"            resp \u003d self.delete(\u0027/allocations/%s\u0027 % source_consumer_uuid,"},{"line_number":1889,"context_line":"                               global_request_id\u003dcontext.global_id)"},{"line_number":1890,"context_line":"            # This could return False from a 404 response if the source"},{"line_number":1891,"context_line":"            # consumer no longer exists either."},{"line_number":1892,"context_line":"            return resp.status_code \u003d\u003d 204"},{"line_number":1893,"context_line":"        else:"},{"line_number":1894,"context_line":"            # The target consumer does not exist and is new so there is no"}],"source_content_type":"text/x-python","patch_set":3,"id":"3fa7e38b_0be13efd","line":1891,"range":{"start_line":1890,"start_character":65,"end_line":1891,"end_character":47},"updated":"2019-10-17 20:13:46.000000000","message":"How does that happen, also concurrent oob delete?","commit_id":"bb48d0a8060dd777df248983d891d484f4188adf"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"a332ccb1924d8ed7f953f06aadb827dbc0bbb3df","unresolved":false,"context_lines":[{"line_number":1887,"context_line":"                     target_consumer_uuid, source_consumer_uuid)"},{"line_number":1888,"context_line":"            resp \u003d self.delete(\u0027/allocations/%s\u0027 % source_consumer_uuid,"},{"line_number":1889,"context_line":"                               global_request_id\u003dcontext.global_id)"},{"line_number":1890,"context_line":"            # This could return False from a 404 response if the source"},{"line_number":1891,"context_line":"            # consumer no longer exists either."},{"line_number":1892,"context_line":"            return resp.status_code \u003d\u003d 204"},{"line_number":1893,"context_line":"        else:"},{"line_number":1894,"context_line":"            # The target consumer does not exist and is new so there is no"}],"source_content_type":"text/x-python","patch_set":3,"id":"3fa7e38b_2b0d0b35","line":1891,"range":{"start_line":1890,"start_character":65,"end_line":1891,"end_character":47},"in_reply_to":"3fa7e38b_0be13efd","updated":"2019-10-18 15:27:37.000000000","message":"I don\u0027t have a recreate scenario that would hit this, but I\u0027m accounting for it which is why I\u0027m checking the response value. For example, if some day we made the instance delete flow detect that the instance is being migrated and not only delete the instance consumer allocations but also the migration consumer allocations, we could hit this.","commit_id":"bb48d0a8060dd777df248983d891d484f4188adf"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"b73fa5e196ad6fcbd82fa0e8652ff0cb933e9524","unresolved":false,"context_lines":[{"line_number":1889,"context_line":"                               global_request_id\u003dcontext.global_id)"},{"line_number":1890,"context_line":"            # This could return False from a 404 response if the source"},{"line_number":1891,"context_line":"            # consumer no longer exists either."},{"line_number":1892,"context_line":"            return resp.status_code \u003d\u003d 204"},{"line_number":1893,"context_line":"        else:"},{"line_number":1894,"context_line":"            # The target consumer does not exist and is new so there is no"},{"line_number":1895,"context_line":"            # generation."}],"source_content_type":"text/x-python","patch_set":3,"id":"3fa7e38b_6bb9d2ea","line":1892,"range":{"start_line":1892,"start_character":19,"end_line":1892,"end_character":42},"updated":"2019-10-17 20:13:46.000000000","message":"Should this always just be True -- doesn\u0027t \"(or already done)\" (L1856) apply in the 404 case?\n\n[Later] I guess the only place the return value makes a behavioral (not-just-logging) difference is replace_allocation_with_migration, where we *would* actually want to fail if the source went away. ([Later later] but that code path is using target_is_new\u003dTrue so this branch is unreachable.) But still, I think raising AllocationMoveFailed in that case (and catching it at the callers) would be more appropriate. That goes for L1948 as well.\n\nAnd then we could get rid of the return value entirely, which IMO has always been a weird semantic.\n\nBut I guess that\u0027s for a separate change.","commit_id":"bb48d0a8060dd777df248983d891d484f4188adf"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"b73fa5e196ad6fcbd82fa0e8652ff0cb933e9524","unresolved":false,"context_lines":[{"line_number":1893,"context_line":"        else:"},{"line_number":1894,"context_line":"            # The target consumer does not exist and is new so there is no"},{"line_number":1895,"context_line":"            # generation."},{"line_number":1896,"context_line":"            LOG.debug(\u0027Creating allocations %(source_alloc)s for consumer \u0027"},{"line_number":1897,"context_line":"                      \u0027%(target_consumer)s and dropping allocations from \u0027"},{"line_number":1898,"context_line":"                      \u0027consumer %(source_consumer)s.\u0027,"},{"line_number":1899,"context_line":"                      {\u0027source_alloc\u0027: source_alloc,"}],"source_content_type":"text/x-python","patch_set":3,"id":"3fa7e38b_8b620ead","line":1896,"range":{"start_line":1896,"start_character":44,"end_line":1896,"end_character":60},"updated":"2019-10-17 20:13:46.000000000","message":"nit, having this dict inline will make the sentence tough to read, suggest putting it at the end of the message","commit_id":"bb48d0a8060dd777df248983d891d484f4188adf"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"a332ccb1924d8ed7f953f06aadb827dbc0bbb3df","unresolved":false,"context_lines":[{"line_number":1893,"context_line":"        else:"},{"line_number":1894,"context_line":"            # The target consumer does not exist and is new so there is no"},{"line_number":1895,"context_line":"            # generation."},{"line_number":1896,"context_line":"            LOG.debug(\u0027Creating allocations %(source_alloc)s for consumer \u0027"},{"line_number":1897,"context_line":"                      \u0027%(target_consumer)s and dropping allocations from \u0027"},{"line_number":1898,"context_line":"                      \u0027consumer %(source_consumer)s.\u0027,"},{"line_number":1899,"context_line":"                      {\u0027source_alloc\u0027: source_alloc,"}],"source_content_type":"text/x-python","patch_set":3,"id":"3fa7e38b_6b59c333","line":1896,"range":{"start_line":1896,"start_character":44,"end_line":1896,"end_character":60},"in_reply_to":"3fa7e38b_8b620ead","updated":"2019-10-18 15:27:37.000000000","message":"This was just based on the log message at L1875. Agree it\u0027s a little weird. When I was debugging this in a functional test there was somewhere that logged something like this and it was a dict_keys iterator that was logged.","commit_id":"bb48d0a8060dd777df248983d891d484f4188adf"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"975850c46683887b2b55f2a20b1ca25f7a615701","unresolved":false,"context_lines":[{"line_number":1928,"context_line":"                # NOTE(jaypipes): Yes, it sucks doing string comparison like"},{"line_number":1929,"context_line":"                # this but we have no error codes, only error messages."},{"line_number":1930,"context_line":"                # TODO(gibi): Use more granular error codes when available"},{"line_number":1931,"context_line":"                if \u0027consumer generation conflict\u0027 in err[\u0027detail\u0027]:"},{"line_number":1932,"context_line":"                    raise exception.AllocationMoveFailed("},{"line_number":1933,"context_line":"                        source_consumer\u003dsource_consumer_uuid,"},{"line_number":1934,"context_line":"                        target_consumer\u003dtarget_consumer_uuid,"}],"source_content_type":"text/x-python","patch_set":3,"id":"3fa7e38b_602ea4fb","line":1931,"updated":"2019-10-21 21:12:22.000000000","message":"@Eric, unless I\u0027m mistaken we don\u0027t retry on consumer generation conflicts because of this.","commit_id":"bb48d0a8060dd777df248983d891d484f4188adf"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"975850c46683887b2b55f2a20b1ca25f7a615701","unresolved":false,"context_lines":[{"line_number":1937,"context_line":"                reason \u003d (\u0027another process changed the resource providers \u0027"},{"line_number":1938,"context_line":"                          \u0027involved in our attempt to post allocations for \u0027"},{"line_number":1939,"context_line":"                          \u0027consumer %s\u0027 % target_consumer_uuid)"},{"line_number":1940,"context_line":"                raise Retry(\u0027move_allocations\u0027, reason)"},{"line_number":1941,"context_line":"            else:"},{"line_number":1942,"context_line":"                LOG.warning("},{"line_number":1943,"context_line":"                    \u0027Unable to post allocations for consumer \u0027"}],"source_content_type":"text/x-python","patch_set":3,"id":"3fa7e38b_00333064","line":1940,"updated":"2019-10-21 21:12:22.000000000","message":"This is where we\u0027re retry because of provider conflicts.","commit_id":"bb48d0a8060dd777df248983d891d484f4188adf"}],"nova/tests/functional/test_servers.py":[{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"6cdde253f16a93c06df32a00ac4ada4351236122","unresolved":false,"context_lines":[{"line_number":4643,"context_line":"        self.compute1 \u003d self._start_compute(\u0027compute1\u0027)"},{"line_number":4644,"context_line":"        self.compute2 \u003d self._start_compute(\u0027compute2\u0027)"},{"line_number":4645,"context_line":"        # Stub out the time.sleep that is used in the report client module"},{"line_number":4646,"context_line":"        # for the retries decorator so tests are faster."},{"line_number":4647,"context_line":"        self.stub_out(\u0027nova.scheduler.client.report.sleep\u0027,"},{"line_number":4648,"context_line":"                      lambda *a, **kw: None)"},{"line_number":4649,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"3fa7e38b_0fdb517d","line":4646,"range":{"start_line":4646,"start_character":49,"end_line":4646,"end_character":55},"updated":"2019-10-22 15:54:18.000000000","message":"also deterministic. A couple of negative tests that stub out POST /allocations to always return a 409 intermittently failed for me locally because of the random backoff sleep in the retries function.","commit_id":"dcfd1839a613a6cdcecd9155082e08123b2ca498"}]}
