)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"a61805c54a1022ea25201a1b30767c69f47b0d23","unresolved":false,"context_lines":[{"line_number":15,"context_line":"    ctxt \u003d context.RequestContext()"},{"line_number":16,"context_line":"    cell_mapping \u003d CellMapping()"},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"    with context.target_cell(ctxt, cell_mapping) as cell_ctxt:"},{"line_number":19,"context_line":"        instance \u003d objects.Instance.get_by_uuid(cell_ctxt, uuid)"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"    cell_ctxt \u003d ctxt.target_cell(cell_mapping)"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":5,"id":"fa1b9901_b4bbbd0e","line":18,"updated":"2015-08-25 16:21:42.000000000","message":"I think I am struggling with what the default database should be, given no particular context.\n\nFor example, in the API do we default to the API database, but in child cell do we default to the main database for that cell. But then what if we have code that runs in both places?\n\nMaybe we default to the cell database, but in the API that is not a valid option, so it has to always be specific. That sounds more possible?","commit_id":"44259621c739bf5c890e38e86e9241e9883046b0"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"a6903590aa0871adb33125618d17ad3865032b3f","unresolved":false,"context_lines":[{"line_number":15,"context_line":"    ctxt \u003d context.RequestContext()"},{"line_number":16,"context_line":"    cell_mapping \u003d CellMapping()"},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"    with context.target_cell(ctxt, cell_mapping) as cell_ctxt:"},{"line_number":19,"context_line":"        instance \u003d objects.Instance.get_by_uuid(cell_ctxt, uuid)"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"    cell_ctxt \u003d ctxt.target_cell(cell_mapping)"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":5,"id":"da20952f_89ac9336","line":18,"in_reply_to":"fa1b9901_b4bbbd0e","updated":"2015-08-28 00:37:16.000000000","message":"This is a good point and I started running into trouble along these lines while writing a functional test. I brought it up briefly in the cells meeting today and it sounds like we\u0027re going to have to be deliberate for API database calls and use get_api_session() in those places. Otherwise like you said, the default would be different depending on what\u0027s local (cell or API) which wouldn\u0027t work for cell databases (they\u0027d be calling local db to get API-only records).","commit_id":"44259621c739bf5c890e38e86e9241e9883046b0"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"a61805c54a1022ea25201a1b30767c69f47b0d23","unresolved":false,"context_lines":[{"line_number":20,"context_line":""},{"line_number":21,"context_line":"    cell_ctxt \u003d ctxt.target_cell(cell_mapping)"},{"line_number":22,"context_line":"    with instance.obj_alternate_context(cell_ctxt):"},{"line_number":23,"context_line":"        instance.save()"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"Implements blueprint cells-db-connection-switching"},{"line_number":26,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":5,"id":"fa1b9901_f44cd543","line":23,"updated":"2015-08-25 16:21:42.000000000","message":"in this case, the instance should know where it came from, so maybe you can just call instance.save()? or is that too confusing?\n\nFeels like I would want to pass in the context if I wanted it to change magically like that.\n\n(Having said that, a deep copy of the context on object creation feels a bit heavy handed).","commit_id":"44259621c739bf5c890e38e86e9241e9883046b0"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"a6903590aa0871adb33125618d17ad3865032b3f","unresolved":false,"context_lines":[{"line_number":20,"context_line":""},{"line_number":21,"context_line":"    cell_ctxt \u003d ctxt.target_cell(cell_mapping)"},{"line_number":22,"context_line":"    with instance.obj_alternate_context(cell_ctxt):"},{"line_number":23,"context_line":"        instance.save()"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"Implements blueprint cells-db-connection-switching"},{"line_number":26,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":5,"id":"da20952f_c947eb75","line":23,"in_reply_to":"fa1b9901_f44cd543","updated":"2015-08-28 00:37:16.000000000","message":"I thought about that but was thinking, I thought this information gets lost after traveling over RPC. That is, I remember working with Migration objects in the past and creating them with admin context didn\u0027t stick once an object arrived on the other side of an RPC. That\u0027s where obj_alternate_context came about","commit_id":"44259621c739bf5c890e38e86e9241e9883046b0"}],"nova/context.py":[{"author":{"_account_id":12548,"name":"Dheeraj Gupta","email":"dheeraj.gupta4@gmail.com","username":"dgupta"},"change_message_id":"e8e316441e42536811c9787c3081cb115d12ca7e","unresolved":false,"context_lines":[{"line_number":227,"context_line":"        from nova import db"},{"line_number":228,"context_line":"        context \u003d copy.deepcopy(self)"},{"line_number":229,"context_line":"        connection_string \u003d target_cell.get(\u0027database_connection\u0027)"},{"line_number":230,"context_line":"        context.db_connection \u003d db.get_facade(connection_string)"},{"line_number":231,"context_line":"        return context"},{"line_number":232,"context_line":""},{"line_number":233,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"fa1b9901_ace7503f","line":230,"updated":"2015-08-18 06:11:34.000000000","message":"This calls db.get_facade with a connection_string","commit_id":"44259621c739bf5c890e38e86e9241e9883046b0"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"01f4ba487432a9919d54b3a6b6d5c7817c7ab84f","unresolved":false,"context_lines":[{"line_number":146,"context_line":"        # connection information for connecting to the target cell."},{"line_number":147,"context_line":"        # It is only manipulated using the target_cell contextmanager"},{"line_number":148,"context_line":"        # provided by this module and the target_cell method"},{"line_number":149,"context_line":"        self.db_connection \u003d None"},{"line_number":150,"context_line":"        self.user_auth_plugin \u003d user_auth_plugin"},{"line_number":151,"context_line":"        if self.is_admin is None:"},{"line_number":152,"context_line":"            self.is_admin \u003d policy.check_is_admin(self)"}],"source_content_type":"text/x-python","patch_set":7,"id":"da85f559_86284e9b","line":149,"updated":"2015-11-12 15:35:30.000000000","message":"We will need one for the queue as well.","commit_id":"6d835b6caac63b21f1ec96539ac1bbdf4ed2f258"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"763e45060651d4ad2f77d334aa6ba0fdb47a1fc3","unresolved":false,"context_lines":[{"line_number":146,"context_line":"        # connection information for connecting to the target cell."},{"line_number":147,"context_line":"        # It is only manipulated using the target_cell contextmanager"},{"line_number":148,"context_line":"        # provided by this module and the target_cell method"},{"line_number":149,"context_line":"        self.db_connection \u003d None"},{"line_number":150,"context_line":"        self.user_auth_plugin \u003d user_auth_plugin"},{"line_number":151,"context_line":"        if self.is_admin is None:"},{"line_number":152,"context_line":"            self.is_admin \u003d policy.check_is_admin(self)"}],"source_content_type":"text/x-python","patch_set":7,"id":"ba8a016a_5b176b51","line":149,"in_reply_to":"da85f559_86284e9b","updated":"2015-11-16 21:24:37.000000000","message":"True","commit_id":"6d835b6caac63b21f1ec96539ac1bbdf4ed2f258"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"01f4ba487432a9919d54b3a6b6d5c7817c7ab84f","unresolved":false,"context_lines":[{"line_number":221,"context_line":""},{"line_number":222,"context_line":"        :param target_cell: A nova.db.sqlalachemy.api_models.CellMapping"},{"line_number":223,"context_line":"                            object. Alternatively, it can be any dict-like"},{"line_number":224,"context_line":"                            object with a key \"database_connection\""},{"line_number":225,"context_line":"        \"\"\""},{"line_number":226,"context_line":"        # avoid circular import"},{"line_number":227,"context_line":"        from nova import db"}],"source_content_type":"text/x-python","patch_set":7,"id":"da85f559_6945fb40","line":224,"updated":"2015-11-12 15:35:30.000000000","message":"Shouldn\u0027t this be/require an objects.CellMapping? I would think so...","commit_id":"6d835b6caac63b21f1ec96539ac1bbdf4ed2f258"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"763e45060651d4ad2f77d334aa6ba0fdb47a1fc3","unresolved":false,"context_lines":[{"line_number":221,"context_line":""},{"line_number":222,"context_line":"        :param target_cell: A nova.db.sqlalachemy.api_models.CellMapping"},{"line_number":223,"context_line":"                            object. Alternatively, it can be any dict-like"},{"line_number":224,"context_line":"                            object with a key \"database_connection\""},{"line_number":225,"context_line":"        \"\"\""},{"line_number":226,"context_line":"        # avoid circular import"},{"line_number":227,"context_line":"        from nova import db"}],"source_content_type":"text/x-python","patch_set":7,"id":"ba8a016a_e648065e","line":224,"in_reply_to":"da85f559_6945fb40","updated":"2015-11-16 21:24:37.000000000","message":"Probably. This docstring goes way back to the original rev of this patch. I\u0027ll change it","commit_id":"6d835b6caac63b21f1ec96539ac1bbdf4ed2f258"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"01f4ba487432a9919d54b3a6b6d5c7817c7ab84f","unresolved":false,"context_lines":[{"line_number":226,"context_line":"        # avoid circular import"},{"line_number":227,"context_line":"        from nova import db"},{"line_number":228,"context_line":"        context \u003d copy.deepcopy(self)"},{"line_number":229,"context_line":"        connection_string \u003d target_cell.get(\u0027database_connection\u0027)"},{"line_number":230,"context_line":"        context.db_connection \u003d db.get_facade(connection_string)"},{"line_number":231,"context_line":"        return context"},{"line_number":232,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"da85f559_099eafb8","line":229,"updated":"2015-11-12 15:35:30.000000000","message":"No need to get() here I think. If it\u0027s not set, then that\u0027s a problem and we should fail.","commit_id":"6d835b6caac63b21f1ec96539ac1bbdf4ed2f258"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"763e45060651d4ad2f77d334aa6ba0fdb47a1fc3","unresolved":false,"context_lines":[{"line_number":226,"context_line":"        # avoid circular import"},{"line_number":227,"context_line":"        from nova import db"},{"line_number":228,"context_line":"        context \u003d copy.deepcopy(self)"},{"line_number":229,"context_line":"        connection_string \u003d target_cell.get(\u0027database_connection\u0027)"},{"line_number":230,"context_line":"        context.db_connection \u003d db.get_facade(connection_string)"},{"line_number":231,"context_line":"        return context"},{"line_number":232,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"ba8a016a_26660eee","line":229,"in_reply_to":"da85f559_099eafb8","updated":"2015-11-16 21:24:37.000000000","message":"Yeah, makes sense","commit_id":"6d835b6caac63b21f1ec96539ac1bbdf4ed2f258"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"01f4ba487432a9919d54b3a6b6d5c7817c7ab84f","unresolved":false,"context_lines":[{"line_number":299,"context_line":"    :param context: The RequestContext to add database connection information"},{"line_number":300,"context_line":"    :param target_cell: A nova.db.sqlalachemy.api_models.CellMapping object."},{"line_number":301,"context_line":"                        Alternatively, it can be  any dict-like object with"},{"line_number":302,"context_line":"                        a key \"database_connection\""},{"line_number":303,"context_line":"    \"\"\""},{"line_number":304,"context_line":"    # avoid circular import"},{"line_number":305,"context_line":"    from nova import db"}],"source_content_type":"text/x-python","patch_set":7,"id":"da85f559_e9a6cb0d","line":302,"updated":"2015-11-12 15:35:30.000000000","message":"Same here: should be the object.","commit_id":"6d835b6caac63b21f1ec96539ac1bbdf4ed2f258"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"763e45060651d4ad2f77d334aa6ba0fdb47a1fc3","unresolved":false,"context_lines":[{"line_number":299,"context_line":"    :param context: The RequestContext to add database connection information"},{"line_number":300,"context_line":"    :param target_cell: A nova.db.sqlalachemy.api_models.CellMapping object."},{"line_number":301,"context_line":"                        Alternatively, it can be  any dict-like object with"},{"line_number":302,"context_line":"                        a key \"database_connection\""},{"line_number":303,"context_line":"    \"\"\""},{"line_number":304,"context_line":"    # avoid circular import"},{"line_number":305,"context_line":"    from nova import db"}],"source_content_type":"text/x-python","patch_set":7,"id":"ba8a016a_e65fa60c","line":302,"in_reply_to":"da85f559_e9a6cb0d","updated":"2015-11-16 21:24:37.000000000","message":"Done","commit_id":"6d835b6caac63b21f1ec96539ac1bbdf4ed2f258"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"01f4ba487432a9919d54b3a6b6d5c7817c7ab84f","unresolved":false,"context_lines":[{"line_number":303,"context_line":"    \"\"\""},{"line_number":304,"context_line":"    # avoid circular import"},{"line_number":305,"context_line":"    from nova import db"},{"line_number":306,"context_line":"    connection_string \u003d target_cell.get(\u0027database_connection\u0027)"},{"line_number":307,"context_line":"    context.db_connection \u003d db.get_facade(connection_string)"},{"line_number":308,"context_line":""},{"line_number":309,"context_line":"    try:"}],"source_content_type":"text/x-python","patch_set":7,"id":"da85f559_a9ad23ea","line":306,"updated":"2015-11-12 15:35:30.000000000","message":"Also this get.","commit_id":"6d835b6caac63b21f1ec96539ac1bbdf4ed2f258"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"763e45060651d4ad2f77d334aa6ba0fdb47a1fc3","unresolved":false,"context_lines":[{"line_number":303,"context_line":"    \"\"\""},{"line_number":304,"context_line":"    # avoid circular import"},{"line_number":305,"context_line":"    from nova import db"},{"line_number":306,"context_line":"    connection_string \u003d target_cell.get(\u0027database_connection\u0027)"},{"line_number":307,"context_line":"    context.db_connection \u003d db.get_facade(connection_string)"},{"line_number":308,"context_line":""},{"line_number":309,"context_line":"    try:"}],"source_content_type":"text/x-python","patch_set":7,"id":"ba8a016a_869b3ac9","line":306,"in_reply_to":"da85f559_a9ad23ea","updated":"2015-11-16 21:24:37.000000000","message":"Done","commit_id":"6d835b6caac63b21f1ec96539ac1bbdf4ed2f258"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"01f4ba487432a9919d54b3a6b6d5c7817c7ab84f","unresolved":false,"context_lines":[{"line_number":309,"context_line":"    try:"},{"line_number":310,"context_line":"        yield context"},{"line_number":311,"context_line":"    finally:"},{"line_number":312,"context_line":"        context.db_connection \u003d None"}],"source_content_type":"text/x-python","patch_set":7,"id":"da85f559_a9c20383","line":312,"updated":"2015-11-12 15:35:30.000000000","message":"So, I think it\u0027s bad and confusing when context managers that look like they restore something, don\u0027t.\n\nIMHO, you should capture the existing db_connection, change it, yield, and then restore it. If it was None, then it\u0027ll be None afterwards. If it was something else, then it will be whatever it was. Otherwise, the behavior here will confuse someone down the line.","commit_id":"6d835b6caac63b21f1ec96539ac1bbdf4ed2f258"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"763e45060651d4ad2f77d334aa6ba0fdb47a1fc3","unresolved":false,"context_lines":[{"line_number":309,"context_line":"    try:"},{"line_number":310,"context_line":"        yield context"},{"line_number":311,"context_line":"    finally:"},{"line_number":312,"context_line":"        context.db_connection \u003d None"}],"source_content_type":"text/x-python","patch_set":7,"id":"ba8a016a_a6ee7e20","line":312,"in_reply_to":"da85f559_a9c20383","updated":"2015-11-16 21:24:37.000000000","message":"Makes sense","commit_id":"6d835b6caac63b21f1ec96539ac1bbdf4ed2f258"},{"author":{"_account_id":7730,"name":"Sahid Orentino Ferdjaoui","email":"sahid.ferdjaoui@industrialdiscipline.com","username":"sahid"},"change_message_id":"e3a48a4239ca9c7a6a28f4c2fdac80616f2bcfe5","unresolved":false,"context_lines":[{"line_number":225,"context_line":"        \"\"\""},{"line_number":226,"context_line":"        # avoid circular import"},{"line_number":227,"context_line":"        from nova import db"},{"line_number":228,"context_line":"        context \u003d copy.deepcopy(self)"},{"line_number":229,"context_line":"        connection_string \u003d target_cell.database_connection"},{"line_number":230,"context_line":"        context.db_connection \u003d db.get_context_manager(connection_string)"},{"line_number":231,"context_line":"        return context"}],"source_content_type":"text/x-python","patch_set":8,"id":"9a8ffd7b_c87921fe","line":228,"updated":"2015-11-25 15:41:37.000000000","message":"nit: Instead of this direct call deepcopy here, a method \"clone\" in RequestContext can be nice.\n\n  def clone(self):\n    return copy.deepcopy(self)","commit_id":"1ffd6ad75fcc31dbb714404abe44729c8f6a32af"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"eb1d2a85442c04a344ff774e3ba50688f42a9d07","unresolved":false,"context_lines":[{"line_number":225,"context_line":"        \"\"\""},{"line_number":226,"context_line":"        # avoid circular import"},{"line_number":227,"context_line":"        from nova import db"},{"line_number":228,"context_line":"        context \u003d copy.deepcopy(self)"},{"line_number":229,"context_line":"        connection_string \u003d target_cell.database_connection"},{"line_number":230,"context_line":"        context.db_connection \u003d db.get_context_manager(connection_string)"},{"line_number":231,"context_line":"        return context"}],"source_content_type":"text/x-python","patch_set":8,"id":"9a8ffd7b_2ab4a0cf","line":228,"in_reply_to":"9a8ffd7b_c87921fe","updated":"2015-11-30 19:56:44.000000000","message":"Ah, thank you","commit_id":"1ffd6ad75fcc31dbb714404abe44729c8f6a32af"},{"author":{"_account_id":7730,"name":"Sahid Orentino Ferdjaoui","email":"sahid.ferdjaoui@industrialdiscipline.com","username":"sahid"},"change_message_id":"e3a48a4239ca9c7a6a28f4c2fdac80616f2bcfe5","unresolved":false,"context_lines":[{"line_number":298,"context_line":""},{"line_number":299,"context_line":"    :param context: The RequestContext to add database connection information"},{"line_number":300,"context_line":"    :param target_cell: A objects.CellMapping object"},{"line_number":301,"context_line":"    \"\"\""},{"line_number":302,"context_line":"    original_db_connection \u003d context.db_connection"},{"line_number":303,"context_line":"    # avoid circular import"},{"line_number":304,"context_line":"    from nova import db"}],"source_content_type":"text/x-python","patch_set":8,"id":"9a8ffd7b_ad470f76","line":301,"updated":"2015-11-25 15:41:37.000000000","message":"You should probably reuse the just created method \"target_cell\" from RequestContext\u0027s object.\n\n  ...\n     yield context.target_cell(target_cell)\n\nThat said I think to use same name of method and argument is not a good idea.","commit_id":"1ffd6ad75fcc31dbb714404abe44729c8f6a32af"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"eb1d2a85442c04a344ff774e3ba50688f42a9d07","unresolved":false,"context_lines":[{"line_number":298,"context_line":""},{"line_number":299,"context_line":"    :param context: The RequestContext to add database connection information"},{"line_number":300,"context_line":"    :param target_cell: A objects.CellMapping object"},{"line_number":301,"context_line":"    \"\"\""},{"line_number":302,"context_line":"    original_db_connection \u003d context.db_connection"},{"line_number":303,"context_line":"    # avoid circular import"},{"line_number":304,"context_line":"    from nova import db"}],"source_content_type":"text/x-python","patch_set":8,"id":"9a8ffd7b_6a1628a9","line":301,"in_reply_to":"9a8ffd7b_ad470f76","updated":"2015-11-30 19:56:44.000000000","message":"Hm, good point on the naming.\n\nI was thinking maybe I should get rid of the other target_cell and just let nested contextmanagers be used in the case:\n\n with context.target_cell(ctxt, mapping) as cell_ctxt:\n     with instance.obj_alternate_context(cell_ctxt):\n         instance.save()","commit_id":"1ffd6ad75fcc31dbb714404abe44729c8f6a32af"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"2abf19e5b530de7acc8d5cd18698485974c58298","unresolved":false,"context_lines":[{"line_number":292,"context_line":"    original_db_connection \u003d context.db_connection"},{"line_number":293,"context_line":"    # avoid circular import"},{"line_number":294,"context_line":"    from nova import db"},{"line_number":295,"context_line":"    connection_string \u003d cell_mapping.database_connection"},{"line_number":296,"context_line":"    context.db_connection \u003d db.create_context_manager(connection_string)"},{"line_number":297,"context_line":""},{"line_number":298,"context_line":"    try:"}],"source_content_type":"text/x-python","patch_set":17,"id":"3a57f1b5_a105c57a","line":295,"updated":"2016-02-11 12:04:48.000000000","message":"Could avoid the import if we push this into the cell_mapping, so you get:\n\n  context.db_connection \u003d cell_mapping.create_context_manager()","commit_id":"e3b6d29705ae6d48df8555ad0afffc822cbd6678"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"76cd7d30dd2a2dd9400728edd99fe78e48a373a5","unresolved":false,"context_lines":[{"line_number":292,"context_line":"    original_db_connection \u003d context.db_connection"},{"line_number":293,"context_line":"    # avoid circular import"},{"line_number":294,"context_line":"    from nova import db"},{"line_number":295,"context_line":"    connection_string \u003d cell_mapping.database_connection"},{"line_number":296,"context_line":"    context.db_connection \u003d db.create_context_manager(connection_string)"},{"line_number":297,"context_line":""},{"line_number":298,"context_line":"    try:"}],"source_content_type":"text/x-python","patch_set":17,"id":"3a57f1b5_78645048","line":295,"in_reply_to":"3a57f1b5_18de7c3f","updated":"2016-02-11 15:55:31.000000000","message":"true, its nice and explicit.","commit_id":"e3b6d29705ae6d48df8555ad0afffc822cbd6678"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"58a94539a343cbf8e907fa74ec1d4d082ac7d52c","unresolved":false,"context_lines":[{"line_number":292,"context_line":"    original_db_connection \u003d context.db_connection"},{"line_number":293,"context_line":"    # avoid circular import"},{"line_number":294,"context_line":"    from nova import db"},{"line_number":295,"context_line":"    connection_string \u003d cell_mapping.database_connection"},{"line_number":296,"context_line":"    context.db_connection \u003d db.create_context_manager(connection_string)"},{"line_number":297,"context_line":""},{"line_number":298,"context_line":"    try:"}],"source_content_type":"text/x-python","patch_set":17,"id":"3a57f1b5_18de7c3f","line":295,"in_reply_to":"3a57f1b5_a105c57a","updated":"2016-02-11 15:52:31.000000000","message":"It doesn\u0027t seem worth it to go through that indirection to avoid the import here. This makes it a little more direct and obvious, so I think it\u0027s probably the best thing.\n\nThere is already a lot of roundabout indirection here..","commit_id":"e3b6d29705ae6d48df8555ad0afffc822cbd6678"}],"nova/db/api.py":[{"author":{"_account_id":12548,"name":"Dheeraj Gupta","email":"dheeraj.gupta4@gmail.com","username":"dgupta"},"change_message_id":"e8e316441e42536811c9787c3081cb115d12ca7e","unresolved":false,"context_lines":[{"line_number":88,"context_line":""},{"line_number":89,"context_line":"def get_facade(connection):"},{"line_number":90,"context_line":"    \"\"\"Return a facade for a cell database connection.\"\"\""},{"line_number":91,"context_line":"    return IMPL.get_facade(connection\u003dconnection)"},{"line_number":92,"context_line":""},{"line_number":93,"context_line":""},{"line_number":94,"context_line":"###################"}],"source_content_type":"text/x-python","patch_set":5,"id":"fa1b9901_acc43040","line":91,"updated":"2015-08-18 06:11:34.000000000","message":"The connection string passed from target_cell is passed to the sqlalchemy/api.py:get_facade as connection","commit_id":"44259621c739bf5c890e38e86e9241e9883046b0"}],"nova/db/sqlalchemy/api.py":[{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"120f3433f78897a839354dc2f1c25c02ea319423","unresolved":false,"context_lines":[{"line_number":449,"context_line":""},{"line_number":450,"context_line":""},{"line_number":451,"context_line":"def service_destroy(context, service_id):"},{"line_number":452,"context_line":"    session \u003d get_session(context\u003dcontext)"},{"line_number":453,"context_line":"    with session.begin():"},{"line_number":454,"context_line":"        service \u003d _service_get(context, service_id)"},{"line_number":455,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"1a4dcd0f_8d5063d6","line":452,"updated":"2015-08-13 21:47:52.000000000","message":"You could clean this up a little by leaving these calls to get_session alone and the context parameter can be added if a call needs to work with both databases.  But most of these sqlalchemy api methods will only need to work with a single database.","commit_id":"1df6701a2d40341f6928757cb2f667a122ad4a24"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"2730d3bd346e855f1f9ee22991556c3c185fa1c4","unresolved":false,"context_lines":[{"line_number":449,"context_line":""},{"line_number":450,"context_line":""},{"line_number":451,"context_line":"def service_destroy(context, service_id):"},{"line_number":452,"context_line":"    session \u003d get_session(context\u003dcontext)"},{"line_number":453,"context_line":"    with session.begin():"},{"line_number":454,"context_line":"        service \u003d _service_get(context, service_id)"},{"line_number":455,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"1a4dcd0f_36b4fcd2","line":452,"in_reply_to":"1a4dcd0f_8d5063d6","updated":"2015-08-13 23:07:12.000000000","message":"That makes a lot of sense. I felt wary about adding it hundreds of times in this file. I\u0027ll update it to only be the calls that could access a cell database.","commit_id":"1df6701a2d40341f6928757cb2f667a122ad4a24"},{"author":{"_account_id":12548,"name":"Dheeraj Gupta","email":"dheeraj.gupta4@gmail.com","username":"dgupta"},"change_message_id":"e8e316441e42536811c9787c3081cb115d12ca7e","unresolved":false,"context_lines":[{"line_number":156,"context_line":"        retry_interval\u003dconf_group.retry_interval)"},{"line_number":157,"context_line":""},{"line_number":158,"context_line":""},{"line_number":159,"context_line":"def _create_facade_lazily(facade, conf_group, connection\u003dNone):"},{"line_number":160,"context_line":"    global _LOCK, _ENGINE_FACADE"},{"line_number":161,"context_line":"    if _ENGINE_FACADE[facade] is None:"},{"line_number":162,"context_line":"        with _LOCK:"}],"source_content_type":"text/x-python","patch_set":5,"id":"fa1b9901_2c41000c","line":159,"updated":"2015-08-18 06:11:34.000000000","message":"facade is always \"main\" for every target_cell() call","commit_id":"44259621c739bf5c890e38e86e9241e9883046b0"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"0a9f1231fa3c0c621ef79db0567f6efb8afd2ef4","unresolved":false,"context_lines":[{"line_number":156,"context_line":"        retry_interval\u003dconf_group.retry_interval)"},{"line_number":157,"context_line":""},{"line_number":158,"context_line":""},{"line_number":159,"context_line":"def _create_facade_lazily(facade, conf_group, connection\u003dNone):"},{"line_number":160,"context_line":"    global _LOCK, _ENGINE_FACADE"},{"line_number":161,"context_line":"    if _ENGINE_FACADE[facade] is None:"},{"line_number":162,"context_line":"        with _LOCK:"}],"source_content_type":"text/x-python","patch_set":5,"id":"fa1b9901_73e814e3","line":159,"in_reply_to":"fa1b9901_2c41000c","updated":"2015-08-18 18:48:41.000000000","message":"My thinking is that a cell database will always be a \"main\" database, so target_cell should always let facade be \"main\"","commit_id":"44259621c739bf5c890e38e86e9241e9883046b0"},{"author":{"_account_id":12548,"name":"Dheeraj Gupta","email":"dheeraj.gupta4@gmail.com","username":"dgupta"},"change_message_id":"e8e316441e42536811c9787c3081cb115d12ca7e","unresolved":false,"context_lines":[{"line_number":160,"context_line":"    global _LOCK, _ENGINE_FACADE"},{"line_number":161,"context_line":"    if _ENGINE_FACADE[facade] is None:"},{"line_number":162,"context_line":"        with _LOCK:"},{"line_number":163,"context_line":"            if _ENGINE_FACADE[facade] is None:"},{"line_number":164,"context_line":"                _ENGINE_FACADE[facade] \u003d _create_facade(conf_group,"},{"line_number":165,"context_line":"                                                        connection\u003dconnection)"},{"line_number":166,"context_line":"    return _ENGINE_FACADE[facade]"}],"source_content_type":"text/x-python","patch_set":5,"id":"fa1b9901_6c37f8b0","line":163,"updated":"2015-08-18 06:11:34.000000000","message":"As facade\u003d\"main\" and it is logical to assume that _ENGINE_FACADE[\"main\"] is already instantiated (at startup), this will never trigger and \"main\" facade will be returned.\n\nAlternatively, it may trigger on first target_cell call, but will return the same facade even if different connection is provided for subsequent calls","commit_id":"44259621c739bf5c890e38e86e9241e9883046b0"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"da756aa7b3c49490328cce1a8bbe6031cb68c60b","unresolved":false,"context_lines":[{"line_number":160,"context_line":"    global _LOCK, _ENGINE_FACADE"},{"line_number":161,"context_line":"    if _ENGINE_FACADE[facade] is None:"},{"line_number":162,"context_line":"        with _LOCK:"},{"line_number":163,"context_line":"            if _ENGINE_FACADE[facade] is None:"},{"line_number":164,"context_line":"                _ENGINE_FACADE[facade] \u003d _create_facade(conf_group,"},{"line_number":165,"context_line":"                                                        connection\u003dconnection)"},{"line_number":166,"context_line":"    return _ENGINE_FACADE[facade]"}],"source_content_type":"text/x-python","patch_set":5,"id":"fa1b9901_93d7e8be","line":163,"in_reply_to":"fa1b9901_6c37f8b0","updated":"2015-08-18 18:56:11.000000000","message":"Hm, good catch on that. Will fix","commit_id":"44259621c739bf5c890e38e86e9241e9883046b0"},{"author":{"_account_id":12548,"name":"Dheeraj Gupta","email":"dheeraj.gupta4@gmail.com","username":"dgupta"},"change_message_id":"e8e316441e42536811c9787c3081cb115d12ca7e","unresolved":false,"context_lines":[{"line_number":174,"context_line":"            pass"},{"line_number":175,"context_line":""},{"line_number":176,"context_line":""},{"line_number":177,"context_line":"def get_facade(database\u003d_MAIN_FACADE, connection\u003dNone):"},{"line_number":178,"context_line":"    \"\"\"Get a database facade object."},{"line_number":179,"context_line":""},{"line_number":180,"context_line":"    :param database: The type of database, _MAIN_FACADE or _API_FACADE"}],"source_content_type":"text/x-python","patch_set":5,"id":"fa1b9901_4cec74c7","line":177,"updated":"2015-08-18 06:11:34.000000000","message":"target_cell\u0027s call lands here with  database\u003d_MAIN_FACADE and supplied connection_string","commit_id":"44259621c739bf5c890e38e86e9241e9883046b0"},{"author":{"_account_id":12548,"name":"Dheeraj Gupta","email":"dheeraj.gupta4@gmail.com","username":"dgupta"},"change_message_id":"e8e316441e42536811c9787c3081cb115d12ca7e","unresolved":false,"context_lines":[{"line_number":184,"context_line":"        conf_group \u003d CONF.database"},{"line_number":185,"context_line":"    elif database \u003d\u003d _API_FACADE:"},{"line_number":186,"context_line":"        conf_group \u003d CONF.api_database"},{"line_number":187,"context_line":"    return _create_facade_lazily(database, conf_group, connection\u003dconnection)"},{"line_number":188,"context_line":""},{"line_number":189,"context_line":""},{"line_number":190,"context_line":"def get_engine(use_slave\u003dFalse, context\u003dNone):"}],"source_content_type":"text/x-python","patch_set":5,"id":"fa1b9901_0cc2fc85","line":187,"updated":"2015-08-18 06:11:34.000000000","message":"As only connection is passed, this calls _create_facade_lazily(\"main\", CONF.database, connection)","commit_id":"44259621c739bf5c890e38e86e9241e9883046b0"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"01f4ba487432a9919d54b3a6b6d5c7817c7ab84f","unresolved":false,"context_lines":[{"line_number":159,"context_line":""},{"line_number":160,"context_line":"def _create_facade_lazily(facade, conf_group, connection\u003dNone):"},{"line_number":161,"context_line":"    if connection is not None:"},{"line_number":162,"context_line":"        facade \u003d utils.get_hash_str(connection)"},{"line_number":163,"context_line":"    global _LOCK, _ENGINE_FACADE"},{"line_number":164,"context_line":"    if _ENGINE_FACADE.get(facade, None) is None:"},{"line_number":165,"context_line":"        with _LOCK:"}],"source_content_type":"text/x-python","patch_set":7,"id":"da85f559_69be5baf","line":162,"updated":"2015-11-12 15:35:30.000000000","message":"So, we\u0027re doing this so that we can store multiple cell connections in the dict, right?\n\nWhat are we going to do about reaping these? Every API worker having N connections (for an N sized pool) open to every cell database is probably not going to be awesome, especially given that one cell could be relatively lightly used.","commit_id":"6d835b6caac63b21f1ec96539ac1bbdf4ed2f258"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"763e45060651d4ad2f77d334aa6ba0fdb47a1fc3","unresolved":false,"context_lines":[{"line_number":159,"context_line":""},{"line_number":160,"context_line":"def _create_facade_lazily(facade, conf_group, connection\u003dNone):"},{"line_number":161,"context_line":"    if connection is not None:"},{"line_number":162,"context_line":"        facade \u003d utils.get_hash_str(connection)"},{"line_number":163,"context_line":"    global _LOCK, _ENGINE_FACADE"},{"line_number":164,"context_line":"    if _ENGINE_FACADE.get(facade, None) is None:"},{"line_number":165,"context_line":"        with _LOCK:"}],"source_content_type":"text/x-python","patch_set":7,"id":"ba8a016a_06218a4d","line":162,"in_reply_to":"da85f559_69be5baf","updated":"2015-11-16 21:24:37.000000000","message":"First idea is we could have a periodic task that clears the dict\n\nMostly I was thinking of how to avoid re-creating EngineFacade objects/connections based on the existing design that keeps API and MAIN database connections open/cached. If it\u0027s not considered to be too expensive to re-create them each time, we could also not have a dict","commit_id":"6d835b6caac63b21f1ec96539ac1bbdf4ed2f258"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"01f4ba487432a9919d54b3a6b6d5c7817c7ab84f","unresolved":false,"context_lines":[{"line_number":1446,"context_line":""},{"line_number":1447,"context_line":"    :param values: \u003d dict containing column values"},{"line_number":1448,"context_line":"    \"\"\""},{"line_number":1449,"context_line":"    session \u003d get_session(context\u003dcontext)"},{"line_number":1450,"context_line":"    try:"},{"line_number":1451,"context_line":"        vif_ref \u003d models.VirtualInterface()"},{"line_number":1452,"context_line":"        vif_ref.update(values)"}],"source_content_type":"text/x-python","patch_set":7,"id":"da85f559_e9a00b44","line":1449,"updated":"2015-11-12 15:35:30.000000000","message":"I wonder if we could break out all the changes that do this explicit session part, along with all the tests it changes into a separate patch. We can land that before this one, and thus keep this one specific to the context-related and facade-related changes.","commit_id":"6d835b6caac63b21f1ec96539ac1bbdf4ed2f258"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"763e45060651d4ad2f77d334aa6ba0fdb47a1fc3","unresolved":false,"context_lines":[{"line_number":1446,"context_line":""},{"line_number":1447,"context_line":"    :param values: \u003d dict containing column values"},{"line_number":1448,"context_line":"    \"\"\""},{"line_number":1449,"context_line":"    session \u003d get_session(context\u003dcontext)"},{"line_number":1450,"context_line":"    try:"},{"line_number":1451,"context_line":"        vif_ref \u003d models.VirtualInterface()"},{"line_number":1452,"context_line":"        vif_ref.update(values)"}],"source_content_type":"text/x-python","patch_set":7,"id":"ba8a016a_c61aa217","line":1449,"in_reply_to":"da85f559_e9a00b44","updated":"2015-11-16 21:24:37.000000000","message":"Could do that","commit_id":"6d835b6caac63b21f1ec96539ac1bbdf4ed2f258"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"de28ef690c92d4852a7299cb1358bbc99aa49529","unresolved":false,"context_lines":[{"line_number":166,"context_line":"    api_context_manager.configure(**_get_db_conf(conf.api_database))"},{"line_number":167,"context_line":""},{"line_number":168,"context_line":""},{"line_number":169,"context_line":"def get_context_manager(connection\u003dNone):"},{"line_number":170,"context_line":"    \"\"\"Get a database context manager object."},{"line_number":171,"context_line":""},{"line_number":172,"context_line":"    : param connection: The database connection string"}],"source_content_type":"text/x-python","patch_set":8,"id":"9a8ffd7b_1701a6ae","line":169,"range":{"start_line":169,"start_character":24,"end_line":169,"end_character":39},"updated":"2015-11-25 07:16:27.000000000","message":"Maybe this shouldn\u0027t be a keyword arg defaulting to None","commit_id":"1ffd6ad75fcc31dbb714404abe44729c8f6a32af"}]}
