)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"02fdad0bee3dfe8432bea08b8ba4f6e86d2585bc","unresolved":false,"context_lines":[{"line_number":22,"context_line":"        return rpc.get_cell_client(context, self.client)"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"    def build_and_run_instances(self, ctxt, instance, host, image, ...)"},{"line_number":25,"context_line":"        cctxt \u003d self.get_cell_client.prepare(...)"},{"line_number":26,"context_line":"        cctxt.cast(...)"},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"Implements blueprint cells-mq-connection-switching"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":10,"id":"1a122d0e_d27b78bc","line":25,"range":{"start_line":25,"start_character":21,"end_line":25,"end_character":36},"updated":"2016-04-20 17:42:59.000000000","message":"Dangit, this should be get_cell_client(ctxt)","commit_id":"49982f0349b76769955e8c22692e735dbe14f50e"}],"nova/compute/rpcapi.py":[{"author":{"_account_id":11803,"name":"Ryan Rossiter","email":"rlrossit@us.ibm.com","username":"rlrossiter"},"change_message_id":"a4a5141aeedb0020fec867e84c7b1b81fcfc3891","unresolved":false,"context_lines":[{"line_number":85,"context_line":"        original_client \u003d self.client"},{"line_number":86,"context_line":"        try:"},{"line_number":87,"context_line":"            if context.mq_connection:"},{"line_number":88,"context_line":"                self.client \u003d messaging.RPCClient("},{"line_number":89,"context_line":"                        context.mq_connection, original_client.target,"},{"line_number":90,"context_line":"                        version_cap\u003doriginal_client.version_cap,"},{"line_number":91,"context_line":"                        serializer\u003doriginal_client.serializer)"}],"source_content_type":"text/x-python","patch_set":2,"id":"5a5ae5dd_d9490cd2","line":88,"updated":"2016-02-03 22:56:06.000000000","message":"It really feels like these clients should be cached instead of having to create a new one every time we are swapping the contexts... but it hurts my head to think of how we would do that.","commit_id":"0ee17ea1c1ca702b02376efe5fbc44757634f77d"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"139b0aa0d4a2f152212b8050fc76bdc3f53de3a4","unresolved":false,"context_lines":[{"line_number":85,"context_line":"        original_client \u003d self.client"},{"line_number":86,"context_line":"        try:"},{"line_number":87,"context_line":"            if context.mq_connection:"},{"line_number":88,"context_line":"                self.client \u003d messaging.RPCClient("},{"line_number":89,"context_line":"                        context.mq_connection, original_client.target,"},{"line_number":90,"context_line":"                        version_cap\u003doriginal_client.version_cap,"},{"line_number":91,"context_line":"                        serializer\u003doriginal_client.serializer)"}],"source_content_type":"text/x-python","patch_set":2,"id":"5a5ae5dd_2a11dc52","line":88,"in_reply_to":"5a5ae5dd_d9490cd2","updated":"2016-02-03 23:25:24.000000000","message":"Yeah, I agree. In the db switching patch initially I had a global dict to cache enginefacades (now would be db transaction contexts) by hashes of connection strings. The missing piece there was a policy for expiring connections as you could end up with a connection to every cell staying open even for low traffic cells (periodic task that closes old connections? dict size limit that replaces oldest connections? etc)\n\nI realized I didn\u0027t know how expensive re-creating these objects is so I decided to keep it simple at first, then add it as we learn more","commit_id":"0ee17ea1c1ca702b02376efe5fbc44757634f77d"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"eff6aa13df77dfc0b9ea6f35654a8ba23668d3a5","unresolved":false,"context_lines":[{"line_number":394,"context_line":"                              version_cap\u003dversion_cap,"},{"line_number":395,"context_line":"                              serializer\u003dserializer)"},{"line_number":396,"context_line":""},{"line_number":397,"context_line":"    @rpc.client_from_context"},{"line_number":398,"context_line":"    def add_aggregate_host(self, ctxt, aggregate, host_param, host,"},{"line_number":399,"context_line":"                           slave_info\u003dNone):"},{"line_number":400,"context_line":"        \u0027\u0027\u0027Add aggregate host."}],"source_content_type":"text/x-python","patch_set":8,"id":"5a18252c_583b6f9c","line":397,"updated":"2016-04-13 18:36:57.000000000","message":"I feel like maybe decorating every method in here with this, besides being rather heavy, is also somewhat accident-prone. What if we just make all the calls do this:\n\n cctxt \u003d self.cell_client(ctxt).prepare(...)\n\nThat makes it a little more explicit, and also helps to address my comment on the next file.","commit_id":"c55611ca5f6dc656744bc7b76948c68c7c1e4db1"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"574a826c8fbb24428425de2c3689a6dee3d77d28","unresolved":false,"context_lines":[{"line_number":405,"context_line":"        :param host: This is the host to send the message to."},{"line_number":406,"context_line":"        \u0027\u0027\u0027"},{"line_number":407,"context_line":"        version \u003d \u00274.0\u0027"},{"line_number":408,"context_line":"        cctxt \u003d rpc.get_cell_client(ctxt, self.client).prepare("},{"line_number":409,"context_line":"                server\u003dhost, version\u003dversion)"},{"line_number":410,"context_line":"        cctxt.cast(ctxt, \u0027add_aggregate_host\u0027,"},{"line_number":411,"context_line":"                   aggregate\u003daggregate, host\u003dhost_param,"}],"source_content_type":"text/x-python","patch_set":9,"id":"1a122d0e_2d49bcb7","line":408,"updated":"2016-04-20 14:29:17.000000000","message":"I was probably confusing when I commented on the previous patch, but I was thinking this would still be an instance method. Something like\n\n self.get_cell_client(ctxt).prepare(\n\nwhich would be even shorter. If that thing needs to call into the rpc module for the proper imports, then that\u0027s fine, but it seems like we should unify this locally to make it overridable and a little more OOish.","commit_id":"dece8207ec904a5d82c236e098f5d5965a6ff9b9"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"9da0dbcc2679571ad396d4ea50b32253afd9052e","unresolved":false,"context_lines":[{"line_number":405,"context_line":"        :param host: This is the host to send the message to."},{"line_number":406,"context_line":"        \u0027\u0027\u0027"},{"line_number":407,"context_line":"        version \u003d \u00274.0\u0027"},{"line_number":408,"context_line":"        cctxt \u003d rpc.get_cell_client(ctxt, self.client).prepare("},{"line_number":409,"context_line":"                server\u003dhost, version\u003dversion)"},{"line_number":410,"context_line":"        cctxt.cast(ctxt, \u0027add_aggregate_host\u0027,"},{"line_number":411,"context_line":"                   aggregate\u003daggregate, host\u003dhost_param,"}],"source_content_type":"text/x-python","patch_set":9,"id":"1a122d0e_d7008a04","line":408,"in_reply_to":"1a122d0e_2d49bcb7","updated":"2016-04-20 17:31:27.000000000","message":"It\u0027s not so much about the imports but I was thinking \"what if other APIs need to switch transports\" and wanted to put the logic in a common place","commit_id":"dece8207ec904a5d82c236e098f5d5965a6ff9b9"}],"nova/context.py":[{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"9fe07f52b5473110702f7ef3b587323f91413fa1","unresolved":false,"context_lines":[{"line_number":299,"context_line":"    db_connection_string \u003d cell_mapping.database_connection"},{"line_number":300,"context_line":"    context.db_connection \u003d db.create_context_manager(db_connection_string)"},{"line_number":301,"context_line":"    # NOTE(melwitt): cell0 is a special sentinel value meaning do not switch"},{"line_number":302,"context_line":"    if cell_mapping.transport_url !\u003d \u0027cell0\u0027:"},{"line_number":303,"context_line":"        context.mq_connection \u003d rpc.create_transport("},{"line_number":304,"context_line":"                cell_mapping.transport_url)"},{"line_number":305,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"ba0121b8_bee5afa9","line":302,"updated":"2016-03-28 23:38:35.000000000","message":"Change this to not .startswith(\u0027none\u0027)","commit_id":"7c1ae3896e9af42e7940ad5bea12893c25f64fd2"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"f932dfa2de504520477ed68c9dd8d20e636ff97d","unresolved":false,"context_lines":[{"line_number":299,"context_line":"    db_connection_string \u003d cell_mapping.database_connection"},{"line_number":300,"context_line":"    context.db_connection \u003d db.create_context_manager(db_connection_string)"},{"line_number":301,"context_line":"    # NOTE(melwitt): none:// url is a special value meaning do not switch"},{"line_number":302,"context_line":"    if not cell_mapping.transport_url.startswith(\u0027none\u0027):"},{"line_number":303,"context_line":"        context.mq_connection \u003d rpc.create_transport("},{"line_number":304,"context_line":"                cell_mapping.transport_url)"},{"line_number":305,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"1a122d0e_ab8762b3","line":302,"updated":"2016-04-20 20:51:12.000000000","message":"I\u0027m of the opinion that hitting this case is probably a bug in the code and it may warrant an error. I don\u0027t think you should change it here, but it\u0027s something we probably should investigate later.","commit_id":"49982f0349b76769955e8c22692e735dbe14f50e"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"737de9e6ca69dab8d130ce3b516d08402f75f187","unresolved":false,"context_lines":[{"line_number":299,"context_line":"    db_connection_string \u003d cell_mapping.database_connection"},{"line_number":300,"context_line":"    context.db_connection \u003d db.create_context_manager(db_connection_string)"},{"line_number":301,"context_line":"    # NOTE(melwitt): none:// url is a special value meaning do not switch"},{"line_number":302,"context_line":"    if not cell_mapping.transport_url.startswith(\u0027none\u0027):"},{"line_number":303,"context_line":"        context.mq_connection \u003d rpc.create_transport("},{"line_number":304,"context_line":"                cell_mapping.transport_url)"},{"line_number":305,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"1a122d0e_a572a1e1","line":302,"in_reply_to":"1a122d0e_56ed72ee","updated":"2016-05-03 03:47:11.000000000","message":"FYI I tried removing this line that avoids creating the Transport object if url starts with \u0027none\u0027 and got:\n\n oslo_messaging.transport.DriverLoadFailure: Failed to load transport driver \"none\": No \u0027oslo.messaging.drivers\u0027 driver found, looking for u\u0027none\u0027\n\nwith a CellMapping that had \u0027none:///\u0027 for transport_url.","commit_id":"49982f0349b76769955e8c22692e735dbe14f50e"},{"author":{"_account_id":18247,"name":"Mark Doffman","email":"mdoffman@linux.vnet.ibm.com","username":"doffm"},"change_message_id":"3b3a1ccc130b634c38c5e529232cf4dda636779a","unresolved":false,"context_lines":[{"line_number":299,"context_line":"    db_connection_string \u003d cell_mapping.database_connection"},{"line_number":300,"context_line":"    context.db_connection \u003d db.create_context_manager(db_connection_string)"},{"line_number":301,"context_line":"    # NOTE(melwitt): none:// url is a special value meaning do not switch"},{"line_number":302,"context_line":"    if not cell_mapping.transport_url.startswith(\u0027none\u0027):"},{"line_number":303,"context_line":"        context.mq_connection \u003d rpc.create_transport("},{"line_number":304,"context_line":"                cell_mapping.transport_url)"},{"line_number":305,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"1a122d0e_be057d15","line":302,"in_reply_to":"1a122d0e_66b9a5cb","updated":"2016-05-03 15:21:23.000000000","message":"I guess we agreed that \u0027none:///\u0027 would imply \u0027no-different\u0027 or \u0027same as the api\u0027. I see how that could be confusing.","commit_id":"49982f0349b76769955e8c22692e735dbe14f50e"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"a55aaeedcb4570e1f6462e27aa64d96260bb8452","unresolved":false,"context_lines":[{"line_number":299,"context_line":"    db_connection_string \u003d cell_mapping.database_connection"},{"line_number":300,"context_line":"    context.db_connection \u003d db.create_context_manager(db_connection_string)"},{"line_number":301,"context_line":"    # NOTE(melwitt): none:// url is a special value meaning do not switch"},{"line_number":302,"context_line":"    if not cell_mapping.transport_url.startswith(\u0027none\u0027):"},{"line_number":303,"context_line":"        context.mq_connection \u003d rpc.create_transport("},{"line_number":304,"context_line":"                cell_mapping.transport_url)"},{"line_number":305,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"1a122d0e_7352ee36","line":302,"in_reply_to":"1a122d0e_66b9a5cb","updated":"2016-05-03 23:04:14.000000000","message":"Well, cell0 isn\u0027t supposed to be connected to any message queue -- it\u0027s a database-only. So we were going to use \u0027none:///\u0027 transport_url for it. What I meant is that at some point I thought someone said \u0027none:///\u0027 would result in the successful creation of a Transport object and wouldn\u0027t error until a send was attempted later on at the rpcapi, and thus the if statement here wasn\u0027t needed. But when I tried it, it does actually error here which is a problem since we want to use target_cell for db-only switching too.\n\nPoint being, I think the if statement guard around creating the Transport is necessary.","commit_id":"49982f0349b76769955e8c22692e735dbe14f50e"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"a683f313c0ae7d08c6824798d4a492d995216c7e","unresolved":false,"context_lines":[{"line_number":299,"context_line":"    db_connection_string \u003d cell_mapping.database_connection"},{"line_number":300,"context_line":"    context.db_connection \u003d db.create_context_manager(db_connection_string)"},{"line_number":301,"context_line":"    # NOTE(melwitt): none:// url is a special value meaning do not switch"},{"line_number":302,"context_line":"    if not cell_mapping.transport_url.startswith(\u0027none\u0027):"},{"line_number":303,"context_line":"        context.mq_connection \u003d rpc.create_transport("},{"line_number":304,"context_line":"                cell_mapping.transport_url)"},{"line_number":305,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"1a122d0e_56ed72ee","line":302,"in_reply_to":"1a122d0e_980f5536","updated":"2016-04-21 12:18:18.000000000","message":"Right, if RPC is attempted to cell0 that\u0027s going to be a bug. All instances there should be in an error state so the only allowable action should be to delete it, and that will need to be run as a local delete.\n\nI realized during our irc conversation that this can\u0027t error here because it\u0027s valid to call this method for cell0 to set the db_connection, but it won\u0027t be valid to use get_cell_client if the cell_mapping is cell0 so maybe we log and/or error there.\n\nBut that would probably be better in a separate patch.","commit_id":"49982f0349b76769955e8c22692e735dbe14f50e"},{"author":{"_account_id":11803,"name":"Ryan Rossiter","email":"rlrossit@us.ibm.com","username":"rlrossiter"},"change_message_id":"9ebb21b708c247fea886f2beb258bf25334ca5fb","unresolved":false,"context_lines":[{"line_number":299,"context_line":"    db_connection_string \u003d cell_mapping.database_connection"},{"line_number":300,"context_line":"    context.db_connection \u003d db.create_context_manager(db_connection_string)"},{"line_number":301,"context_line":"    # NOTE(melwitt): none:// url is a special value meaning do not switch"},{"line_number":302,"context_line":"    if not cell_mapping.transport_url.startswith(\u0027none\u0027):"},{"line_number":303,"context_line":"        context.mq_connection \u003d rpc.create_transport("},{"line_number":304,"context_line":"                cell_mapping.transport_url)"},{"line_number":305,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"1a122d0e_66b9a5cb","line":302,"in_reply_to":"1a122d0e_a572a1e1","updated":"2016-05-03 13:23:20.000000000","message":"A CellMapping with none:/// in the transport_url is incorrect from a deployment sense though right? Because that would mean a cell with no MQ. At a minimum, the transport_url of the cell will be the same as everyone else (meaning all cells are using the same queue) right?","commit_id":"49982f0349b76769955e8c22692e735dbe14f50e"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"b3e937800dd8c19ea658c775343bf6d9f4bd555e","unresolved":false,"context_lines":[{"line_number":299,"context_line":"    db_connection_string \u003d cell_mapping.database_connection"},{"line_number":300,"context_line":"    context.db_connection \u003d db.create_context_manager(db_connection_string)"},{"line_number":301,"context_line":"    # NOTE(melwitt): none:// url is a special value meaning do not switch"},{"line_number":302,"context_line":"    if not cell_mapping.transport_url.startswith(\u0027none\u0027):"},{"line_number":303,"context_line":"        context.mq_connection \u003d rpc.create_transport("},{"line_number":304,"context_line":"                cell_mapping.transport_url)"},{"line_number":305,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"1a122d0e_980f5536","line":302,"in_reply_to":"1a122d0e_ab8762b3","updated":"2016-04-20 22:20:10.000000000","message":"Oh, because cell0 actions shouldn\u0027t be trying to communicate over rpc in the first place. I can get rid of this","commit_id":"49982f0349b76769955e8c22692e735dbe14f50e"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"f932dfa2de504520477ed68c9dd8d20e636ff97d","unresolved":false,"context_lines":[{"line_number":300,"context_line":"    context.db_connection \u003d db.create_context_manager(db_connection_string)"},{"line_number":301,"context_line":"    # NOTE(melwitt): none:// url is a special value meaning do not switch"},{"line_number":302,"context_line":"    if not cell_mapping.transport_url.startswith(\u0027none\u0027):"},{"line_number":303,"context_line":"        context.mq_connection \u003d rpc.create_transport("},{"line_number":304,"context_line":"                cell_mapping.transport_url)"},{"line_number":305,"context_line":""},{"line_number":306,"context_line":"    try:"}],"source_content_type":"text/x-python","patch_set":10,"id":"1a122d0e_6b3d4adc","line":303,"updated":"2016-04-20 20:51:12.000000000","message":"Again not something to change in this patch, but I would actually like to see just a cell_id or something set on context. The cell_id would be mapped to cached db connections and rpc transports stored elsewhere. Then in rpc.py it would just pull the cached transport for the cell_id set on the context, or create and cache it.","commit_id":"49982f0349b76769955e8c22692e735dbe14f50e"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"b3e937800dd8c19ea658c775343bf6d9f4bd555e","unresolved":false,"context_lines":[{"line_number":300,"context_line":"    context.db_connection \u003d db.create_context_manager(db_connection_string)"},{"line_number":301,"context_line":"    # NOTE(melwitt): none:// url is a special value meaning do not switch"},{"line_number":302,"context_line":"    if not cell_mapping.transport_url.startswith(\u0027none\u0027):"},{"line_number":303,"context_line":"        context.mq_connection \u003d rpc.create_transport("},{"line_number":304,"context_line":"                cell_mapping.transport_url)"},{"line_number":305,"context_line":""},{"line_number":306,"context_line":"    try:"}],"source_content_type":"text/x-python","patch_set":10,"id":"1a122d0e_83388ad4","line":303,"in_reply_to":"1a122d0e_6b3d4adc","updated":"2016-04-20 22:20:10.000000000","message":"Understood. We might have to go that route and as we said we\u0027ll start simpler and add the caching if we see issues. The cache will have to have some expiry mechanism which makes it a little less straightforward (timer and just cleans old?)","commit_id":"49982f0349b76769955e8c22692e735dbe14f50e"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"a683f313c0ae7d08c6824798d4a492d995216c7e","unresolved":false,"context_lines":[{"line_number":300,"context_line":"    context.db_connection \u003d db.create_context_manager(db_connection_string)"},{"line_number":301,"context_line":"    # NOTE(melwitt): none:// url is a special value meaning do not switch"},{"line_number":302,"context_line":"    if not cell_mapping.transport_url.startswith(\u0027none\u0027):"},{"line_number":303,"context_line":"        context.mq_connection \u003d rpc.create_transport("},{"line_number":304,"context_line":"                cell_mapping.transport_url)"},{"line_number":305,"context_line":""},{"line_number":306,"context_line":"    try:"}],"source_content_type":"text/x-python","patch_set":10,"id":"1a122d0e_36dc3674","line":303,"in_reply_to":"1a122d0e_83388ad4","updated":"2016-04-21 12:18:18.000000000","message":"Totally agree. Yeah, I think to start a simple time based expiration makes sense. Then if it makes sense to optimize after that we should be able to collect data to help guide those improvements.","commit_id":"49982f0349b76769955e8c22692e735dbe14f50e"}],"nova/rpc.py":[{"author":{"_account_id":15424,"name":"javeme","email":"javaloveme@gmail.com","username":"javeme"},"change_message_id":"b57d9bb895a3c73054951a66a6a9089565b09358","unresolved":false,"context_lines":[{"line_number":86,"context_line":"    @functools.wraps(f)"},{"line_number":87,"context_line":"    def wrapped(self, context, *args, **kwargs):"},{"line_number":88,"context_line":"        original_client \u003d self.client"},{"line_number":89,"context_line":"        try:"},{"line_number":90,"context_line":"            if context.mq_connection:"},{"line_number":91,"context_line":"                self.client \u003d messaging.RPCClient("},{"line_number":92,"context_line":"                        context.mq_connection, original_client.target,"}],"source_content_type":"text/x-python","patch_set":7,"id":"ba0121b8_db9fca5d","line":89,"range":{"start_line":89,"start_character":8,"end_line":89,"end_character":11},"updated":"2016-03-29 07:18:56.000000000","message":"It may be better to put the try-finally behind the \"if context.mq_connection:\" -- because there is no need to try if context.mq_connection is null.","commit_id":"764999c9309fa03355740fb1cbb4a12331be1a89"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"134f36da0beb7cb13836e38ab2e6da9caf1aa17a","unresolved":false,"context_lines":[{"line_number":86,"context_line":"    @functools.wraps(f)"},{"line_number":87,"context_line":"    def wrapped(self, context, *args, **kwargs):"},{"line_number":88,"context_line":"        original_client \u003d self.client"},{"line_number":89,"context_line":"        try:"},{"line_number":90,"context_line":"            if context.mq_connection:"},{"line_number":91,"context_line":"                self.client \u003d messaging.RPCClient("},{"line_number":92,"context_line":"                        context.mq_connection, original_client.target,"}],"source_content_type":"text/x-python","patch_set":7,"id":"ba0121b8_81656bb6","line":89,"range":{"start_line":89,"start_character":8,"end_line":89,"end_character":11},"in_reply_to":"ba0121b8_db9fca5d","updated":"2016-03-30 23:52:01.000000000","message":"Yeah, I did this to avoid having two different \"return f()\" statements for the two cases but I think it\u0027s probably better/clearer to separate the paths and just duplicate that call. Will do it in the next PS","commit_id":"764999c9309fa03355740fb1cbb4a12331be1a89"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"eff6aa13df77dfc0b9ea6f35654a8ba23668d3a5","unresolved":false,"context_lines":[{"line_number":88,"context_line":"        original_client \u003d self.client"},{"line_number":89,"context_line":"        try:"},{"line_number":90,"context_line":"            if context.mq_connection:"},{"line_number":91,"context_line":"                self.client \u003d messaging.RPCClient("},{"line_number":92,"context_line":"                        context.mq_connection, original_client.target,"},{"line_number":93,"context_line":"                        version_cap\u003doriginal_client.version_cap,"},{"line_number":94,"context_line":"                        serializer\u003doriginal_client.serializer)"}],"source_content_type":"text/x-python","patch_set":8,"id":"5a18252c_58ed2f24","line":91,"updated":"2016-04-13 18:36:57.000000000","message":"This seems a little evil, and depends on the rpc client class continuing to use self.client in the actual method.\n\nWhy don\u0027t we just make this be a function that returns you a client based on your context, and have the rpc calls just call that instead of use self.client?\n\nI also wonder if this is going to end up sending calls to the wrong cell if  we have two calls that muck with the shared state on self and intertwine poorly.\n\n1. Thread 1 goes to send to cell 1, original is real\n2. Thread 2 goes to send to cell 2, original is cell1\n3. Thread 1 finishes, restores to original\n4. Thread 2 finishes, restores to cell1\n\nAfter 4, we end up with the wrong self.client on the rpc client. Now, maybe it doesn\u0027t make any difference if we wrap all calls and always reset the client based on where we\u0027re going. However, if we ever do something in the rpc layer that causes us to yield, we could definitely use the wrong client to send our actual message.","commit_id":"c55611ca5f6dc656744bc7b76948c68c7c1e4db1"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"e4b369b508456a43801ab9240b1bdd18725c9830","unresolved":false,"context_lines":[{"line_number":88,"context_line":"        original_client \u003d self.client"},{"line_number":89,"context_line":"        try:"},{"line_number":90,"context_line":"            if context.mq_connection:"},{"line_number":91,"context_line":"                self.client \u003d messaging.RPCClient("},{"line_number":92,"context_line":"                        context.mq_connection, original_client.target,"},{"line_number":93,"context_line":"                        version_cap\u003doriginal_client.version_cap,"},{"line_number":94,"context_line":"                        serializer\u003doriginal_client.serializer)"}],"source_content_type":"text/x-python","patch_set":8,"id":"1a122d0e_f00fbd36","line":91,"in_reply_to":"5a18252c_58ed2f24","updated":"2016-04-20 02:40:49.000000000","message":"Good points, I\u0027ll rework this","commit_id":"c55611ca5f6dc656744bc7b76948c68c7c1e4db1"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"f55dde4a8cbe2e218f290095fed3321967f7329c","unresolved":false,"context_lines":[{"line_number":74,"context_line":"}"},{"line_number":75,"context_line":""},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"def get_cell_client(context, default_client):"},{"line_number":78,"context_line":"    \"\"\"Get a RPCClient object based on a RequestContext."},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    :param context: The RequestContext that can contain a Transport"}],"source_content_type":"text/x-python","patch_set":10,"id":"1a122d0e_ef2f5886","line":77,"updated":"2016-05-03 03:35:55.000000000","message":"If we make this take an instance instead of a context and use instance._context, we would have something like:\n\n with context.target_cell(ctxt, cell_mapping):\n     with instance.obj_alternate_context(ctxt):\n         rpcapi.do_something(ctxt, instance, ...)","commit_id":"49982f0349b76769955e8c22692e735dbe14f50e"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"b367546d8a1388056bb1a9021dd95e11f3539fa4","unresolved":false,"context_lines":[{"line_number":74,"context_line":"}"},{"line_number":75,"context_line":""},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"def get_cell_client(context, default_client):"},{"line_number":78,"context_line":"    \"\"\"Get a RPCClient object based on a RequestContext."},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    :param context: The RequestContext that can contain a Transport"}],"source_content_type":"text/x-python","patch_set":10,"id":"1a122d0e_e461283a","line":77,"in_reply_to":"1a122d0e_ef2f5886","updated":"2016-05-03 16:02:24.000000000","message":"So the flow from having an instance to an RPC call is something like the following:\n\nFrom instance get cell_mapping.\nWith cell_mapping use \n\n    with context.target_cell(context, cell_mapping):\n        compute_rpcapi.detach_interface(...)\n\nFor the suggestion of moving it into get_cell_client I think we\u0027d need to rework this to make get_cell_client a decorator or contextmanager and then end up with something like:\n\n    # in compute/rpcapi.py\n    def detach_interface(...):\n        with get_cell_client(context, instance, default_client) as cell_client:\n            cctxt \u003d cell_client.prepare(...)\n            cctxt.call/cast()\n\nI don\u0027t know that I\u0027m totally sold on the idea because I like having the explicit \"with context.target_cell()\" in compute/api.py when making an RPC cast/call, but it does make the switchover happen much faster.\n\nIt also means we need a separate method for switching when it\u0027s based on a host and not an instance. If we rely on the context.target_cell method then get_cell_client continues to work in all cases.\n\nUltimately I\u0027m not totally opposed to trying the all-at-once method, but I do have a preference for one-by-one.","commit_id":"49982f0349b76769955e8c22692e735dbe14f50e"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"f932dfa2de504520477ed68c9dd8d20e636ff97d","unresolved":false,"context_lines":[{"line_number":83,"context_line":"    if context.mq_connection:"},{"line_number":84,"context_line":"        return messaging.RPCClient("},{"line_number":85,"context_line":"                context.mq_connection, default_client.target,"},{"line_number":86,"context_line":"                version_cap\u003ddefault_client.version_cap,"},{"line_number":87,"context_line":"                serializer\u003ddefault_client.serializer)"},{"line_number":88,"context_line":"    return default_client"},{"line_number":89,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"1a122d0e_0b06561f","line":86,"updated":"2016-04-20 20:51:12.000000000","message":"For now I think assuming a homogeneous version cap works, but this is something else we\u0027ll need to look at in the future.","commit_id":"49982f0349b76769955e8c22692e735dbe14f50e"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"b3e937800dd8c19ea658c775343bf6d9f4bd555e","unresolved":false,"context_lines":[{"line_number":83,"context_line":"    if context.mq_connection:"},{"line_number":84,"context_line":"        return messaging.RPCClient("},{"line_number":85,"context_line":"                context.mq_connection, default_client.target,"},{"line_number":86,"context_line":"                version_cap\u003ddefault_client.version_cap,"},{"line_number":87,"context_line":"                serializer\u003ddefault_client.serializer)"},{"line_number":88,"context_line":"    return default_client"},{"line_number":89,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"1a122d0e_2350960a","line":86,"in_reply_to":"1a122d0e_0b06561f","updated":"2016-04-20 22:20:10.000000000","message":"Noted","commit_id":"49982f0349b76769955e8c22692e735dbe14f50e"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"0873d708692994c39544f58305d1ad2683fc6d22","unresolved":false,"context_lines":[{"line_number":83,"context_line":"    if context.mq_connection:"},{"line_number":84,"context_line":"        return messaging.RPCClient("},{"line_number":85,"context_line":"                context.mq_connection, default_client.target,"},{"line_number":86,"context_line":"                version_cap\u003ddefault_client.version_cap,"},{"line_number":87,"context_line":"                serializer\u003ddefault_client.serializer)"},{"line_number":88,"context_line":"    return default_client"},{"line_number":89,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"1a122d0e_cb071080","line":86,"in_reply_to":"1a122d0e_2350960a","updated":"2016-04-21 15:26:53.000000000","message":"Ah, right because one cell could be at a different version than another right? Hmm..","commit_id":"49982f0349b76769955e8c22692e735dbe14f50e"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"61e9125f075dbd8882da267be3478487fa657de2","unresolved":false,"context_lines":[{"line_number":83,"context_line":"    if context.mq_connection:"},{"line_number":84,"context_line":"        return messaging.RPCClient("},{"line_number":85,"context_line":"                context.mq_connection, default_client.target,"},{"line_number":86,"context_line":"                version_cap\u003ddefault_client.version_cap,"},{"line_number":87,"context_line":"                serializer\u003ddefault_client.serializer)"},{"line_number":88,"context_line":"    return default_client"},{"line_number":89,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"1a122d0e_3ac9a3ad","line":86,"in_reply_to":"1a122d0e_cb071080","updated":"2016-04-21 18:27:14.000000000","message":"Version cap is determined by querying services, and services will be in cell dbs, so maybe all we need (in the future) is to move that version cap determination to this step and cache it per cell?","commit_id":"49982f0349b76769955e8c22692e735dbe14f50e"}],"nova/tests/functional/db/test_connection_switch.py":[{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"574a826c8fbb24428425de2c3689a6dee3d77d28","unresolved":false,"context_lines":[{"line_number":42,"context_line":"    def test_connection_switch(self):"},{"line_number":43,"context_line":"        ctxt \u003d context.RequestContext(\u0027fake-user\u0027, \u0027fake-project\u0027)"},{"line_number":44,"context_line":"        # Make a request context with a cell mapping"},{"line_number":45,"context_line":"        mapping \u003d objects.CellMapping(database_connection\u003dself.fake_conn)"},{"line_number":46,"context_line":"        mapping \u003d objects.CellMapping(context\u003dctxt,"},{"line_number":47,"context_line":"                                      uuid\u003duuidutils.generate_uuid(),"},{"line_number":48,"context_line":"                                      database_connection\u003dself.fake_conn,"}],"source_content_type":"text/x-python","patch_set":9,"id":"1a122d0e_8db9f0ce","line":45,"range":{"start_line":45,"start_character":8,"end_line":45,"end_character":73},"updated":"2016-04-20 14:29:17.000000000","message":"Did you mean to delete this line?","commit_id":"dece8207ec904a5d82c236e098f5d5965a6ff9b9"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"9da0dbcc2679571ad396d4ea50b32253afd9052e","unresolved":false,"context_lines":[{"line_number":42,"context_line":"    def test_connection_switch(self):"},{"line_number":43,"context_line":"        ctxt \u003d context.RequestContext(\u0027fake-user\u0027, \u0027fake-project\u0027)"},{"line_number":44,"context_line":"        # Make a request context with a cell mapping"},{"line_number":45,"context_line":"        mapping \u003d objects.CellMapping(database_connection\u003dself.fake_conn)"},{"line_number":46,"context_line":"        mapping \u003d objects.CellMapping(context\u003dctxt,"},{"line_number":47,"context_line":"                                      uuid\u003duuidutils.generate_uuid(),"},{"line_number":48,"context_line":"                                      database_connection\u003dself.fake_conn,"}],"source_content_type":"text/x-python","patch_set":9,"id":"1a122d0e_f23314f4","line":45,"range":{"start_line":45,"start_character":8,"end_line":45,"end_character":73},"in_reply_to":"1a122d0e_8db9f0ce","updated":"2016-04-20 17:31:27.000000000","message":"Yes, thank you. Missed that","commit_id":"dece8207ec904a5d82c236e098f5d5965a6ff9b9"}]}
