)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"2de41ce7d835bf3acaabca87483e0c9a5b4f8d30","unresolved":false,"context_lines":[{"line_number":4,"context_line":"Commit:     Chris Dent \u003ccdent@anticdent.org\u003e"},{"line_number":5,"context_line":"CommitDate: 2017-06-05 15:02:55 +0000"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Sync os-traits to Traits database"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"When a new version of the os-traits library is released, the Traits"},{"line_number":10,"context_line":"table in the api database needs to be updated to reflect those new"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":11,"id":"df140735_5c6ccdcc","line":7,"range":{"start_line":7,"start_character":25,"end_line":7,"end_character":33},"updated":"2017-06-06 01:23:21.000000000","message":"not really a db, it\u0027s a table, but meh","commit_id":"8df62f59b4bb7c60efcb3fc4dcf67ae41a53cdfb"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"fddbf083b6c0170fe0cba5815837edde92c988ce","unresolved":false,"context_lines":[{"line_number":4,"context_line":"Commit:     Chris Dent \u003ccdent@anticdent.org\u003e"},{"line_number":5,"context_line":"CommitDate: 2017-06-05 15:02:55 +0000"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Sync os-traits to Traits database"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"When a new version of the os-traits library is released, the Traits"},{"line_number":10,"context_line":"table in the api database needs to be updated to reflect those new"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":11,"id":"df140735_de00c7ad","line":7,"in_reply_to":"df140735_5c6ccdcc","updated":"2017-06-06 10:14:39.000000000","message":"Done","commit_id":"8df62f59b4bb7c60efcb3fc4dcf67ae41a53cdfb"}],"nova/objects/resource_provider.py":[{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"2c8e57f34ee7f427c3f4c0bd8de98a17b6900e52","unresolved":false,"context_lines":[{"line_number":76,"context_line":"    :param ctx: `nova.context.RequestContext` that may be used to grab a DB"},{"line_number":77,"context_line":"                connection."},{"line_number":78,"context_line":"    \"\"\""},{"line_number":79,"context_line":"    global _TRAIT_SYNC"},{"line_number":80,"context_line":"    if not _TRAIT_SYNC:"},{"line_number":81,"context_line":"        std_traits \u003d set(os_traits.get_traits())"},{"line_number":82,"context_line":"        conn \u003d ctx.session.connection()"}],"source_content_type":"text/x-python","patch_set":5,"id":"df140735_b4ddb471","line":79,"updated":"2017-06-01 11:24:06.000000000","message":"I guess we need lock?\n\nAlso, I guess we need to handle the case when multiple placement api deployed. Only one can success, other concurrent syncs will fail due to duplicated trait name. But we need to ensure the API request return successfully.","commit_id":"5404267a1273799b986b346759995b9ec5cf6c95"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"2c8e57f34ee7f427c3f4c0bd8de98a17b6900e52","unresolved":false,"context_lines":[{"line_number":92,"context_line":"            {\u0027name\u0027: six.text_type(trait)}"},{"line_number":93,"context_line":"            for trait in need_sync"},{"line_number":94,"context_line":"        ]"},{"line_number":95,"context_line":"        conn.execute(ins, batch_args)"},{"line_number":96,"context_line":"        _TRAIT_SYNC \u003d True"},{"line_number":97,"context_line":"        LOG.info(\"Synced traits from os_traits into API DB: %s\", need_sync)"},{"line_number":98,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"df140735_14ed8024","line":95,"range":{"start_line":95,"start_character":26,"end_line":95,"end_character":36},"updated":"2017-06-01 11:24:06.000000000","message":"We need to handle the case when this is empty list. Also need a test for this case.","commit_id":"5404267a1273799b986b346759995b9ec5cf6c95"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"8bfb3214971f17b57b99f34b69ae656329ca47c2","unresolved":false,"context_lines":[{"line_number":94,"context_line":"    ]"},{"line_number":95,"context_line":"    if batch_args:"},{"line_number":96,"context_line":"        conn.execute(ins, batch_args)"},{"line_number":97,"context_line":"        LOG.info(\"Synced traits from os_traits into API DB: %s\", need_sync)"},{"line_number":98,"context_line":""},{"line_number":99,"context_line":""},{"line_number":100,"context_line":"def _ensure_trait_sync(ctx):"}],"source_content_type":"text/x-python","patch_set":6,"id":"df140735_d2902a4d","line":97,"updated":"2017-06-01 19:47:44.000000000","message":"Hmm, the above code looks familiar... mind adding me as a Co-author on this patch? I\u0027m going to abandon mine in favor of yours.","commit_id":"51a3497a2ff388d5fea8dc31e75646dd969533ee"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"655b512588a1132f4aa5525a795cb56085c5bc65","unresolved":false,"context_lines":[{"line_number":117,"context_line":"    # thread and we\u0027ll simply return."},{"line_number":118,"context_line":"    with lockutils.lock(_TRAIT_LOCK):"},{"line_number":119,"context_line":"        if not _TRAIT_SYNC:"},{"line_number":120,"context_line":"            _trait_sync(ctx)"},{"line_number":121,"context_line":"            _TRAIT_SYNC \u003d True"},{"line_number":122,"context_line":""},{"line_number":123,"context_line":""},{"line_number":124,"context_line":"def _get_current_inventory_resources(conn, rp):"}],"source_content_type":"text/x-python","patch_set":6,"id":"df140735_281dbcbc","line":121,"range":{"start_line":120,"start_character":12,"end_line":121,"end_character":23},"updated":"2017-06-01 17:06:05.000000000","message":"I know, I know, Python is case-sensitive, but I really don\u0027t like two different names differing only in case. How about naming the flag _TRAITS_SYNCED, to indicate that yes, the traits have been synced? Or give the method an active name, such as _sync_traits()?","commit_id":"51a3497a2ff388d5fea8dc31e75646dd969533ee"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"8bfb3214971f17b57b99f34b69ae656329ca47c2","unresolved":false,"context_lines":[{"line_number":117,"context_line":"    # thread and we\u0027ll simply return."},{"line_number":118,"context_line":"    with lockutils.lock(_TRAIT_LOCK):"},{"line_number":119,"context_line":"        if not _TRAIT_SYNC:"},{"line_number":120,"context_line":"            _trait_sync(ctx)"},{"line_number":121,"context_line":"            _TRAIT_SYNC \u003d True"},{"line_number":122,"context_line":""},{"line_number":123,"context_line":""},{"line_number":124,"context_line":"def _get_current_inventory_resources(conn, rp):"}],"source_content_type":"text/x-python","patch_set":6,"id":"df140735_d295ca34","line":121,"range":{"start_line":120,"start_character":12,"end_line":121,"end_character":23},"in_reply_to":"df140735_281dbcbc","updated":"2017-06-01 19:47:44.000000000","message":"agreed with Ed","commit_id":"51a3497a2ff388d5fea8dc31e75646dd969533ee"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"3ecc2cfed63681bd0aee99ebcbc2994e13dd034e","unresolved":false,"context_lines":[{"line_number":93,"context_line":"        for trait in need_sync"},{"line_number":94,"context_line":"    ]"},{"line_number":95,"context_line":"    if batch_args:"},{"line_number":96,"context_line":"        conn.execute(ins, batch_args)"},{"line_number":97,"context_line":"        LOG.info(\"Synced traits from os_traits into API DB: %s\", need_sync)"},{"line_number":98,"context_line":""},{"line_number":99,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"df140735_6b54c053","line":96,"updated":"2017-06-02 01:21:49.000000000","message":"Emm....looks like one of my comment is missed. We also need to handle the case when we have multiple placement apis deployed. The concurrent syncs happened, then one of them will fail.\n\nThat means we need to handle the DBDuplicated exception to ensure the user request return successfully.","commit_id":"78916b3dcaf52bb777cc76331b7ea7b3c1b55a46"},{"author":{"_account_id":15888,"name":"Zhenyu Zheng","email":"zheng.zhenyu@outlook.com","username":"Kevin_Zheng"},"change_message_id":"6915d10bbb9e462f6649e7d631690582364fac15","unresolved":false,"context_lines":[{"line_number":93,"context_line":"        for trait in need_sync"},{"line_number":94,"context_line":"    ]"},{"line_number":95,"context_line":"    if batch_args:"},{"line_number":96,"context_line":"        conn.execute(ins, batch_args)"},{"line_number":97,"context_line":"        LOG.info(\"Synced traits from os_traits into API DB: %s\", need_sync)"},{"line_number":98,"context_line":""},{"line_number":99,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"df140735_eb52103b","line":96,"in_reply_to":"df140735_6b54c053","updated":"2017-06-02 01:31:17.000000000","message":"+1","commit_id":"78916b3dcaf52bb777cc76331b7ea7b3c1b55a46"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"542caab5b7ae3f4a88a4114b17a36d22910d1a27","unresolved":false,"context_lines":[{"line_number":93,"context_line":"        for trait in need_sync"},{"line_number":94,"context_line":"    ]"},{"line_number":95,"context_line":"    if batch_args:"},{"line_number":96,"context_line":"        conn.execute(ins, batch_args)"},{"line_number":97,"context_line":"        LOG.info(\"Synced traits from os_traits into API DB: %s\", need_sync)"},{"line_number":98,"context_line":""},{"line_number":99,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"df140735_8c54c154","line":96,"in_reply_to":"df140735_6b54c053","updated":"2017-06-02 09:19:09.000000000","message":"I asked this in irc too, because my brain hasn\u0027t had enough coffee to properly process this.\n\n\"can you add a bit more detail on the scenario that would cause the duplicate problems? I had though that the combination of the local process lock, and the writer transaction would handle it? Are you concerned about the situation where there are different versions of the os-traits library on different machines?\"","commit_id":"78916b3dcaf52bb777cc76331b7ea7b3c1b55a46"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"7b8309f7f00ac173f61e940c8091bfec9f8abbd2","unresolved":false,"context_lines":[{"line_number":93,"context_line":"        for trait in need_sync"},{"line_number":94,"context_line":"    ]"},{"line_number":95,"context_line":"    if batch_args:"},{"line_number":96,"context_line":"        conn.execute(ins, batch_args)"},{"line_number":97,"context_line":"        LOG.info(\"Synced traits from os_traits into API DB: %s\", need_sync)"},{"line_number":98,"context_line":""},{"line_number":99,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"df140735_eed8c7ef","line":96,"in_reply_to":"df140735_8c54c154","updated":"2017-06-02 15:29:08.000000000","message":"No, Alex is concerned about scenarios where \u003e1 placement-api process is deployed (for example on \u003e1 controller node).\n\nThe conn.execute() will raise an sqlalchemy.IntegrityError indicating a duplicate key violation. In MySQL-land, this is a 1022 error.\n\nI think it\u0027s fair to add a\n\n try:\n     conn.execute(ins, batch_args)\n except sqlalchemy.IntegrityError:\n     pass  # Ignore duplicate key issues in case another process already added...\n\nto here to prevent the placement-api service from faulting.","commit_id":"78916b3dcaf52bb777cc76331b7ea7b3c1b55a46"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"2406809054439cb227430cded5a55b5d56c972ab","unresolved":false,"context_lines":[{"line_number":97,"context_line":"            conn.execute(ins, batch_args)"},{"line_number":98,"context_line":"            LOG.info(\"Synced traits from os_traits into API DB: %s\","},{"line_number":99,"context_line":"                     need_sync)"},{"line_number":100,"context_line":"        except sa.IntegrityError:"},{"line_number":101,"context_line":"            pass  # some other process sync\u0027d, just ignore"},{"line_number":102,"context_line":""},{"line_number":103,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"df140735_106f75c5","line":100,"updated":"2017-06-05 08:15:07.000000000","message":"we should catch \u0027oslo_db.exception.DBDuplicateEntry\u0027. The oslo db convert the IntegrityErrot to DBDuplicateEntry.","commit_id":"6695300219fd086f71a39fec3ab101fde226f5f4"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"6bcdf5bf51e04b9855811b9dd7141abd7c02281e","unresolved":false,"context_lines":[{"line_number":97,"context_line":"            conn.execute(ins, batch_args)"},{"line_number":98,"context_line":"            LOG.info(\"Synced traits from os_traits into API DB: %s\","},{"line_number":99,"context_line":"                     need_sync)"},{"line_number":100,"context_line":"        except sa.IntegrityError:"},{"line_number":101,"context_line":"            pass  # some other process sync\u0027d, just ignore"},{"line_number":102,"context_line":""},{"line_number":103,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"df140735_2e344ddd","line":100,"in_reply_to":"df140735_106f75c5","updated":"2017-06-05 14:51:54.000000000","message":"Done","commit_id":"6695300219fd086f71a39fec3ab101fde226f5f4"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"2de41ce7d835bf3acaabca87483e0c9a5b4f8d30","unresolved":false,"context_lines":[{"line_number":70,"context_line":"    \"\"\"Sync the os_traits symbols to the database."},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"    Reads all symbols from the os_traits library, checks if any of them do"},{"line_number":73,"context_line":"    not exist in the database (and therefore have an internal integer"},{"line_number":74,"context_line":"    identifier) and bulk-inserts any that are not in the DB. This is done"},{"line_number":75,"context_line":"    once, after the process starts and either Trait.get_by_name or"},{"line_number":76,"context_line":"    TraitList.get_all is called."}],"source_content_type":"text/x-python","patch_set":11,"id":"df140735_3cac79eb","line":73,"range":{"start_line":73,"start_character":45,"end_line":73,"end_character":49},"updated":"2017-06-06 01:23:21.000000000","message":"do not have? I\u0027m not really sure why the \"(and therefore...)\" aside is necessary anyway as we aren\u0027t checking for IDs or anything, we\u0027re just getting all trait names from the DB and doing a diff of those against the ones from the library.","commit_id":"8df62f59b4bb7c60efcb3fc4dcf67ae41a53cdfb"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"fddbf083b6c0170fe0cba5815837edde92c988ce","unresolved":false,"context_lines":[{"line_number":70,"context_line":"    \"\"\"Sync the os_traits symbols to the database."},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"    Reads all symbols from the os_traits library, checks if any of them do"},{"line_number":73,"context_line":"    not exist in the database (and therefore have an internal integer"},{"line_number":74,"context_line":"    identifier) and bulk-inserts any that are not in the DB. This is done"},{"line_number":75,"context_line":"    once, after the process starts and either Trait.get_by_name or"},{"line_number":76,"context_line":"    TraitList.get_all is called."}],"source_content_type":"text/x-python","patch_set":11,"id":"df140735_1ed2bf28","line":73,"in_reply_to":"df140735_3cac79eb","updated":"2017-06-06 10:14:39.000000000","message":"Done","commit_id":"8df62f59b4bb7c60efcb3fc4dcf67ae41a53cdfb"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"2de41ce7d835bf3acaabca87483e0c9a5b4f8d30","unresolved":false,"context_lines":[{"line_number":72,"context_line":"    Reads all symbols from the os_traits library, checks if any of them do"},{"line_number":73,"context_line":"    not exist in the database (and therefore have an internal integer"},{"line_number":74,"context_line":"    identifier) and bulk-inserts any that are not in the DB. This is done"},{"line_number":75,"context_line":"    once, after the process starts and either Trait.get_by_name or"},{"line_number":76,"context_line":"    TraitList.get_all is called."},{"line_number":77,"context_line":""},{"line_number":78,"context_line":"    :param ctx: `nova.context.RequestContext` that may be used to grab a DB"}],"source_content_type":"text/x-python","patch_set":11,"id":"df140735_3c711977","line":75,"range":{"start_line":75,"start_character":10,"end_line":75,"end_character":34},"updated":"2017-06-06 01:23:21.000000000","message":"What is triggering this when the process starts? I only see this hit via get_by_name and get_all which go through the REST API.","commit_id":"8df62f59b4bb7c60efcb3fc4dcf67ae41a53cdfb"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"fddbf083b6c0170fe0cba5815837edde92c988ce","unresolved":false,"context_lines":[{"line_number":72,"context_line":"    Reads all symbols from the os_traits library, checks if any of them do"},{"line_number":73,"context_line":"    not exist in the database (and therefore have an internal integer"},{"line_number":74,"context_line":"    identifier) and bulk-inserts any that are not in the DB. This is done"},{"line_number":75,"context_line":"    once, after the process starts and either Trait.get_by_name or"},{"line_number":76,"context_line":"    TraitList.get_all is called."},{"line_number":77,"context_line":""},{"line_number":78,"context_line":"    :param ctx: `nova.context.RequestContext` that may be used to grab a DB"}],"source_content_type":"text/x-python","patch_set":11,"id":"df140735_feccab89","line":75,"in_reply_to":"df140735_3c711977","updated":"2017-06-06 10:14:39.000000000","message":"Done","commit_id":"8df62f59b4bb7c60efcb3fc4dcf67ae41a53cdfb"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"2de41ce7d835bf3acaabca87483e0c9a5b4f8d30","unresolved":false,"context_lines":[{"line_number":84,"context_line":"    res \u003d conn.execute(sel).fetchall()"},{"line_number":85,"context_line":"    db_traits \u003d set("},{"line_number":86,"context_line":"        r[0] for r in res"},{"line_number":87,"context_line":"        if not os_traits.is_custom(r[0])"},{"line_number":88,"context_line":"    )"},{"line_number":89,"context_line":"    need_sync \u003d std_traits - db_traits"},{"line_number":90,"context_line":"    ins \u003d _TRAIT_TBL.insert()"}],"source_content_type":"text/x-python","patch_set":11,"id":"df140735_1ce53538","line":87,"range":{"start_line":87,"start_character":8,"end_line":87,"end_character":40},"updated":"2017-06-06 01:23:21.000000000","message":"OK exclude custom traits since they\u0027ll never be in the library and we don\u0027t want to accidentally try to re-insert them. Comment in the code might be nice as a clarification.","commit_id":"8df62f59b4bb7c60efcb3fc4dcf67ae41a53cdfb"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"fddbf083b6c0170fe0cba5815837edde92c988ce","unresolved":false,"context_lines":[{"line_number":84,"context_line":"    res \u003d conn.execute(sel).fetchall()"},{"line_number":85,"context_line":"    db_traits \u003d set("},{"line_number":86,"context_line":"        r[0] for r in res"},{"line_number":87,"context_line":"        if not os_traits.is_custom(r[0])"},{"line_number":88,"context_line":"    )"},{"line_number":89,"context_line":"    need_sync \u003d std_traits - db_traits"},{"line_number":90,"context_line":"    ins \u003d _TRAIT_TBL.insert()"}],"source_content_type":"text/x-python","patch_set":11,"id":"df140735_3eac639d","line":87,"in_reply_to":"df140735_1ce53538","updated":"2017-06-06 10:14:39.000000000","message":"Done","commit_id":"8df62f59b4bb7c60efcb3fc4dcf67ae41a53cdfb"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"2de41ce7d835bf3acaabca87483e0c9a5b4f8d30","unresolved":false,"context_lines":[{"line_number":95,"context_line":"    if batch_args:"},{"line_number":96,"context_line":"        try:"},{"line_number":97,"context_line":"            conn.execute(ins, batch_args)"},{"line_number":98,"context_line":"            LOG.info(\"Synced traits from os_traits into API DB: %s\","},{"line_number":99,"context_line":"                     need_sync)"},{"line_number":100,"context_line":"        except db_exc.DBDuplicateEntry:"},{"line_number":101,"context_line":"            pass  # some other process sync\u0027d, just ignore"},{"line_number":102,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"df140735_fc8a8161","line":99,"range":{"start_line":98,"start_character":12,"end_line":99,"end_character":31},"updated":"2017-06-06 01:23:21.000000000","message":"Maybe we should log this outside a DB API context manager? I thought funky things can happen with logging within DB API routines (+eventlet).","commit_id":"8df62f59b4bb7c60efcb3fc4dcf67ae41a53cdfb"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"fddbf083b6c0170fe0cba5815837edde92c988ce","unresolved":false,"context_lines":[{"line_number":96,"context_line":"        try:"},{"line_number":97,"context_line":"            conn.execute(ins, batch_args)"},{"line_number":98,"context_line":"            LOG.info(\"Synced traits from os_traits into API DB: %s\","},{"line_number":99,"context_line":"                     need_sync)"},{"line_number":100,"context_line":"        except db_exc.DBDuplicateEntry:"},{"line_number":101,"context_line":"            pass  # some other process sync\u0027d, just ignore"},{"line_number":102,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"df140735_9e8c8f36","line":99,"in_reply_to":"df140735_fc8a8161","updated":"2017-06-06 10:14:39.000000000","message":"no eventlet in the placement service","commit_id":"8df62f59b4bb7c60efcb3fc4dcf67ae41a53cdfb"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"2de41ce7d835bf3acaabca87483e0c9a5b4f8d30","unresolved":false,"context_lines":[{"line_number":98,"context_line":"            LOG.info(\"Synced traits from os_traits into API DB: %s\","},{"line_number":99,"context_line":"                     need_sync)"},{"line_number":100,"context_line":"        except db_exc.DBDuplicateEntry:"},{"line_number":101,"context_line":"            pass  # some other process sync\u0027d, just ignore"},{"line_number":102,"context_line":""},{"line_number":103,"context_line":""},{"line_number":104,"context_line":"def _ensure_trait_sync(ctx):"}],"source_content_type":"text/x-python","patch_set":11,"id":"df140735_3cc3598b","line":101,"range":{"start_line":101,"start_character":18,"end_line":101,"end_character":58},"updated":"2017-06-06 01:23:21.000000000","message":"Heh, or we messed up and tried re-inserting a custom trait or something. Not that that\u0027s happening now, I\u0027m just thinking this is potential silent redundant waste in the future if we\u0027re not doing something about it, at least logging, but if you\u0027re starting \u003e1 worker we don\u0027t want to be logging warnings for this or something.\n\nWe could use etcd for a global lock on doing this sync, but...that\u0027s maybe too fancy for now.","commit_id":"8df62f59b4bb7c60efcb3fc4dcf67ae41a53cdfb"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"fddbf083b6c0170fe0cba5815837edde92c988ce","unresolved":false,"context_lines":[{"line_number":98,"context_line":"            LOG.info(\"Synced traits from os_traits into API DB: %s\","},{"line_number":99,"context_line":"                     need_sync)"},{"line_number":100,"context_line":"        except db_exc.DBDuplicateEntry:"},{"line_number":101,"context_line":"            pass  # some other process sync\u0027d, just ignore"},{"line_number":102,"context_line":""},{"line_number":103,"context_line":""},{"line_number":104,"context_line":"def _ensure_trait_sync(ctx):"}],"source_content_type":"text/x-python","patch_set":11,"id":"df140735_3e0fc388","line":101,"in_reply_to":"df140735_3cc3598b","updated":"2017-06-06 10:14:39.000000000","message":"I don\u0027t think I fully understand this comment. The only things in batch_args are things that are in os_traits, so the only chance of getting a duplicate here is if some other process has won the race to insert the new os_traits.","commit_id":"8df62f59b4bb7c60efcb3fc4dcf67ae41a53cdfb"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"2de41ce7d835bf3acaabca87483e0c9a5b4f8d30","unresolved":false,"context_lines":[{"line_number":2084,"context_line":"        self._from_db_object(self._context, self, db_trait)"},{"line_number":2085,"context_line":""},{"line_number":2086,"context_line":"    @staticmethod"},{"line_number":2087,"context_line":"    @db_api.api_context_manager.writer  # trait sync can case a write"},{"line_number":2088,"context_line":"    def _get_by_name_from_db(context, name):"},{"line_number":2089,"context_line":"        _ensure_trait_sync(context)"},{"line_number":2090,"context_line":"        result \u003d context.session.query(models.Trait).filter_by("}],"source_content_type":"text/x-python","patch_set":11,"id":"df140735_1cbe55fe","line":2087,"range":{"start_line":2087,"start_character":57,"end_line":2087,"end_character":61},"updated":"2017-06-06 01:23:21.000000000","message":"cause","commit_id":"8df62f59b4bb7c60efcb3fc4dcf67ae41a53cdfb"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"fddbf083b6c0170fe0cba5815837edde92c988ce","unresolved":false,"context_lines":[{"line_number":2084,"context_line":"        self._from_db_object(self._context, self, db_trait)"},{"line_number":2085,"context_line":""},{"line_number":2086,"context_line":"    @staticmethod"},{"line_number":2087,"context_line":"    @db_api.api_context_manager.writer  # trait sync can case a write"},{"line_number":2088,"context_line":"    def _get_by_name_from_db(context, name):"},{"line_number":2089,"context_line":"        _ensure_trait_sync(context)"},{"line_number":2090,"context_line":"        result \u003d context.session.query(models.Trait).filter_by("}],"source_content_type":"text/x-python","patch_set":11,"id":"df140735_de1fa7b4","line":2087,"in_reply_to":"df140735_1cbe55fe","updated":"2017-06-06 10:14:39.000000000","message":"Done","commit_id":"8df62f59b4bb7c60efcb3fc4dcf67ae41a53cdfb"}],"nova/tests/functional/db/test_resource_provider.py":[{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"49c10691d85c52171731b3aa38767bd71534ceeb","unresolved":false,"context_lines":[{"line_number":1539,"context_line":"    def tearDown(self):"},{"line_number":1540,"context_line":"        \"\"\"Reset the _TRAIT_SYNC boolean so it doesn\u0027t interfere.\"\"\""},{"line_number":1541,"context_line":"        super(ResourceProviderTraitTestCase, self).tearDown()"},{"line_number":1542,"context_line":"        if rp_obj._TRAIT_SYNC:"},{"line_number":1543,"context_line":"            rp_obj._TRAIT_SYNC \u003d False"},{"line_number":1544,"context_line":""},{"line_number":1545,"context_line":"    def _assert_traits(self, expected_traits, traits_objs):"}],"source_content_type":"text/x-python","patch_set":1,"id":"df140735_f1f0f5cb","line":1542,"updated":"2017-05-31 17:18:32.000000000","message":"this \u0027if\u0027 really isn\u0027t needed. Just set it to False here.","commit_id":"e13b985fa7e415d1237365eb2a85b84c6a6c8d3b"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"5a579d7f23de807edcbd481d8588a4e5db8cd20a","unresolved":false,"context_lines":[{"line_number":1539,"context_line":"    def tearDown(self):"},{"line_number":1540,"context_line":"        \"\"\"Reset the _TRAIT_SYNC boolean so it doesn\u0027t interfere.\"\"\""},{"line_number":1541,"context_line":"        super(ResourceProviderTraitTestCase, self).tearDown()"},{"line_number":1542,"context_line":"        if rp_obj._TRAIT_SYNC:"},{"line_number":1543,"context_line":"            rp_obj._TRAIT_SYNC \u003d False"},{"line_number":1544,"context_line":""},{"line_number":1545,"context_line":"    def _assert_traits(self, expected_traits, traits_objs):"}],"source_content_type":"text/x-python","patch_set":1,"id":"df140735_5111e1ab","line":1542,"in_reply_to":"df140735_f1f0f5cb","updated":"2017-05-31 17:23:18.000000000","message":"der, thanks. That comes from blindly reimplementing some of jays changes (where more is done in the teardown)","commit_id":"e13b985fa7e415d1237365eb2a85b84c6a6c8d3b"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"49c10691d85c52171731b3aa38767bd71534ceeb","unresolved":false,"context_lines":[{"line_number":1553,"context_line":"    def _assert_traits_in(self, expected_traits, traits_objs):"},{"line_number":1554,"context_line":"        traits \u003d []"},{"line_number":1555,"context_line":"        for obj in traits_objs:"},{"line_number":1556,"context_line":"            traits.append(obj.name)"},{"line_number":1557,"context_line":"        for expected in expected_traits:"},{"line_number":1558,"context_line":"            self.assertIn(expected, traits)"},{"line_number":1559,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"df140735_51b9e1e6","line":1556,"updated":"2017-05-31 17:18:32.000000000","message":"traits \u003d [obj.name for obj in traits_objs]\n\nOne line instead of 3.","commit_id":"e13b985fa7e415d1237365eb2a85b84c6a6c8d3b"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"5a579d7f23de807edcbd481d8588a4e5db8cd20a","unresolved":false,"context_lines":[{"line_number":1553,"context_line":"    def _assert_traits_in(self, expected_traits, traits_objs):"},{"line_number":1554,"context_line":"        traits \u003d []"},{"line_number":1555,"context_line":"        for obj in traits_objs:"},{"line_number":1556,"context_line":"            traits.append(obj.name)"},{"line_number":1557,"context_line":"        for expected in expected_traits:"},{"line_number":1558,"context_line":"            self.assertIn(expected, traits)"},{"line_number":1559,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"df140735_917c19ec","line":1556,"in_reply_to":"df140735_51b9e1e6","updated":"2017-05-31 17:23:18.000000000","message":"ditto, will fix","commit_id":"e13b985fa7e415d1237365eb2a85b84c6a6c8d3b"},{"author":{"_account_id":1063,"name":"Ed Leafe","email":"ed@leafe.com","username":"ed-leafe"},"change_message_id":"49c10691d85c52171731b3aa38767bd71534ceeb","unresolved":false,"context_lines":[{"line_number":1619,"context_line":"            t.create()"},{"line_number":1620,"context_line":""},{"line_number":1621,"context_line":"        self._assert_traits_in(trait_names,"},{"line_number":1622,"context_line":"                            objects.TraitList.get_all(self.context))"},{"line_number":1623,"context_line":""},{"line_number":1624,"context_line":"    def test_traits_get_all_with_name_in_filter(self):"},{"line_number":1625,"context_line":"        trait_names \u003d [\u0027CUSTOM_TRAIT_A\u0027, \u0027CUSTOM_TRAIT_B\u0027, \u0027CUSTOM_TRAIT_C\u0027]"}],"source_content_type":"text/x-python","patch_set":1,"id":"df140735_71dd0541","line":1622,"range":{"start_line":1622,"start_character":28,"end_line":1622,"end_character":32},"updated":"2017-05-31 17:18:32.000000000","message":"wonky indent","commit_id":"e13b985fa7e415d1237365eb2a85b84c6a6c8d3b"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"5a579d7f23de807edcbd481d8588a4e5db8cd20a","unresolved":false,"context_lines":[{"line_number":1619,"context_line":"            t.create()"},{"line_number":1620,"context_line":""},{"line_number":1621,"context_line":"        self._assert_traits_in(trait_names,"},{"line_number":1622,"context_line":"                            objects.TraitList.get_all(self.context))"},{"line_number":1623,"context_line":""},{"line_number":1624,"context_line":"    def test_traits_get_all_with_name_in_filter(self):"},{"line_number":1625,"context_line":"        trait_names \u003d [\u0027CUSTOM_TRAIT_A\u0027, \u0027CUSTOM_TRAIT_B\u0027, \u0027CUSTOM_TRAIT_C\u0027]"}],"source_content_type":"text/x-python","patch_set":1,"id":"df140735_1168091f","line":1622,"in_reply_to":"df140735_71dd0541","updated":"2017-05-31 17:23:18.000000000","message":"Done","commit_id":"e13b985fa7e415d1237365eb2a85b84c6a6c8d3b"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"ffd27879d9689a845e10a5938c40cf03d509e43f","unresolved":false,"context_lines":[{"line_number":1536,"context_line":""},{"line_number":1537,"context_line":"class ResourceProviderTraitTestCase(ResourceProviderBaseCase):"},{"line_number":1538,"context_line":""},{"line_number":1539,"context_line":"    def tearDown(self):"},{"line_number":1540,"context_line":"        \"\"\"Reset the _TRAITS_SYNCED boolean so it doesn\u0027t interfere.\"\"\""},{"line_number":1541,"context_line":"        super(ResourceProviderTraitTestCase, self).tearDown()"},{"line_number":1542,"context_line":"        rp_obj._TRAITS_SYNCED \u003d False"}],"source_content_type":"text/x-python","patch_set":12,"id":"df140735_f87148e0","line":1539,"range":{"start_line":1539,"start_character":8,"end_line":1539,"end_character":16},"updated":"2017-06-06 22:45:37.000000000","message":"This should probably be setUp rather than tearDown, see bug 1696267.","commit_id":"e013d1cabef33f31d8361684b871ed3a5f50e3a9"}]}
