)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"169b5330d5c3ed4a3312d3f27bfe1a333cb85bad","unresolved":false,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"enginefacade: \u0027migration\u0027"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Use enginefacade in \u0027migration\u0027 section."},{"line_number":10,"context_line":""},{"line_number":11,"context_line":"Implements: blueprint new-oslodb-enginefacade"},{"line_number":12,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":7,"id":"7a740942_14c71197","line":9,"updated":"2015-12-07 15:23:09.000000000","message":"The commit message should go into a lot more detail about the introduction of select_db_reader_mode and what that\u0027s used for, and why it needs to be used outside of the DB API.","commit_id":"e99ccbd44a81a8849d019c6c512f0c076f43ee6f"}],"nova/db/api.py":[{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"4f94cb3036808d2ae9be13e4ee5b613bd4c47dae","unresolved":false,"context_lines":[{"line_number":89,"context_line":"###################"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"def select_db_reader_mode(f):"},{"line_number":93,"context_line":"    \"\"\"Decorator to select synchronous or asynchronous reader mode.\"\"\""},{"line_number":94,"context_line":"    return IMPL.select_db_reader_mode(f)"},{"line_number":95,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"9a8ffd7b_2ef12296","line":92,"updated":"2015-11-30 15:34:21.000000000","message":"I think this is ok and allows us to use this method from objects and upper layers.\n\nLet\u0027s just document it properly, as it\u0027s public API for other parts of Nova.","commit_id":"e99ccbd44a81a8849d019c6c512f0c076f43ee6f"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"5bc3c30ac735c0efde174b47243a01ec80570a38","unresolved":false,"context_lines":[{"line_number":89,"context_line":"###################"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"def select_db_reader_mode(f):"},{"line_number":93,"context_line":"    \"\"\"Decorator to select synchronous or asynchronous reader mode.\"\"\""},{"line_number":94,"context_line":"    return IMPL.select_db_reader_mode(f)"},{"line_number":95,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"7a740942_e246327a","line":92,"in_reply_to":"7a740942_0f3dbac3","updated":"2015-12-07 21:50:15.000000000","message":"I\u0027m not against moving towards removing the indirection.  However this is being heavily relied on by an out of tree driver (https://review.openstack.org/#/c/243822/).  As a maintainer of that out of tree code I do think the smart option would be to improve our usage of sqlalchemy rather than bypass it.","commit_id":"e99ccbd44a81a8849d019c6c512f0c076f43ee6f"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"200f476d45b88c9f0992a0c4c83594c8daf3aeeb","unresolved":false,"context_lines":[{"line_number":89,"context_line":"###################"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"def select_db_reader_mode(f):"},{"line_number":93,"context_line":"    \"\"\"Decorator to select synchronous or asynchronous reader mode.\"\"\""},{"line_number":94,"context_line":"    return IMPL.select_db_reader_mode(f)"},{"line_number":95,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"7a740942_6546cc50","line":92,"in_reply_to":"7a740942_e246327a","updated":"2015-12-07 21:51:27.000000000","message":"Forgot to mention, I think this seems fine here.  It allows for the \"from nova import db; @db.select_db_reader_mode()\" model which is clean.","commit_id":"e99ccbd44a81a8849d019c6c512f0c076f43ee6f"},{"author":{"_account_id":9555,"name":"Matthew Booth","email":"mbooth@redhat.com","username":"MatthewBooth"},"change_message_id":"11f8e3aaf55c691b30006f41cd5654540e3df0df","unresolved":false,"context_lines":[{"line_number":89,"context_line":"###################"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"def select_db_reader_mode(f):"},{"line_number":93,"context_line":"    \"\"\"Decorator to select synchronous or asynchronous reader mode.\"\"\""},{"line_number":94,"context_line":"    return IMPL.select_db_reader_mode(f)"},{"line_number":95,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"7a740942_0f3dbac3","line":92,"in_reply_to":"9a8ffd7b_2cd4ca45","updated":"2015-12-07 15:37:45.000000000","message":"The underlying issue is that this pretend indirection exists at all. We should promote nova.db.sqlalchemy to nova.db and throw this all away. Until we do that, though, this is fine.","commit_id":"e99ccbd44a81a8849d019c6c512f0c076f43ee6f"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"45452a51cb0a0efd3c4cf84e72bd073f0d284c19","unresolved":false,"context_lines":[{"line_number":89,"context_line":"###################"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"def select_db_reader_mode(f):"},{"line_number":93,"context_line":"    \"\"\"Decorator to select synchronous or asynchronous reader mode.\"\"\""},{"line_number":94,"context_line":"    return IMPL.select_db_reader_mode(f)"},{"line_number":95,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"9a8ffd7b_2cd4ca45","line":92,"in_reply_to":"9a8ffd7b_2ef12296","updated":"2015-11-30 15:52:36.000000000","message":"Its a bit odd though, I feel.\n\nIf we had all the decorators at this level it would make sense.","commit_id":"e99ccbd44a81a8849d019c6c512f0c076f43ee6f"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"be23a7071e98be2cfddb0b6f2a3a17418d9951db","unresolved":false,"context_lines":[{"line_number":89,"context_line":"###################"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"def select_db_reader_mode(f):"},{"line_number":93,"context_line":"    \"\"\"Decorator to select synchronous or asynchronous reader mode."},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"    The kwarg argument \u0027use_slave\u0027 defines reader mode. Asynchronous reader"}],"source_content_type":"text/x-python","patch_set":10,"id":"7a740942_6bd076f8","line":92,"updated":"2015-12-09 14:09:31.000000000","message":"I am still not a fan of this, but I guess its the best option right now.","commit_id":"375f749edde90acf8db490de6696887147d225ba"}],"nova/db/sqlalchemy/api.py":[{"author":{"_account_id":9555,"name":"Matthew Booth","email":"mbooth@redhat.com","username":"MatthewBooth"},"change_message_id":"719cffce8e0f8450933a4a923aebcafd54442418","unresolved":false,"context_lines":[{"line_number":4458,"context_line":"    return result"},{"line_number":4459,"context_line":""},{"line_number":4460,"context_line":""},{"line_number":4461,"context_line":"@main_context_manager.async"},{"line_number":4462,"context_line":"def migration_get_unconfirmed_by_dest_compute(context, confirm_window,"},{"line_number":4463,"context_line":"                                              dest_compute):"},{"line_number":4464,"context_line":"    confirm_window \u003d (timeutils.utcnow() -"}],"source_content_type":"text/x-python","patch_set":2,"id":"ba8a016a_cb6c06d3","line":4461,"updated":"2015-11-20 13:59:35.000000000","message":"As discussed on IRC, I don\u0027t think we have the context here to mark this as async. This is going to expose a wart in enginefacade because what we really want to do here is use a @reader or @async context if it already exists, but create a @reader context if it doesn\u0027t. Enginefacade doesn\u0027t allow us to do that right now because @reader \u003e @async, but I think we should be able to work round it. We should also raise this use case with zzzeek, because he\u0027s pretty good at coming up with tidy solutions to this kind of problem.\n\nTo be clear, the *caller* should have previously created an async db context explicitly, perhaps by using this exact same decorator. Only the caller has the context to know if db reads should be sync or async.","commit_id":"7fade2d22bf83d3f9d4c3cab8f7abaa22c86c176"},{"author":{"_account_id":10618,"name":"Pavel Kholkin","email":"p.v.holkin@mail.ru","username":"pkholkin"},"change_message_id":"5b59dbceae784e5e313168337c20f1182e86ef6f","unresolved":false,"context_lines":[{"line_number":4491,"context_line":""},{"line_number":4492,"context_line":""},{"line_number":4493,"context_line":"def migration_get_unconfirmed_by_dest_compute(context, confirm_window,"},{"line_number":4494,"context_line":"                                              dest_compute):"},{"line_number":4495,"context_line":"    confirm_window \u003d (timeutils.utcnow() -"},{"line_number":4496,"context_line":"                      datetime.timedelta(seconds\u003dconfirm_window))"},{"line_number":4497,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"ba8a016a_c878852e","line":4494,"updated":"2015-11-20 15:46:15.000000000","message":"no decorator here, maybe needed some note or warning","commit_id":"59198b17267492cbaf78fd4928b1211effea0684"},{"author":{"_account_id":10618,"name":"Pavel Kholkin","email":"p.v.holkin@mail.ru","username":"pkholkin"},"change_message_id":"6f392d0a7946275c4804635889d8cf59b1d85cb8","unresolved":false,"context_lines":[{"line_number":4491,"context_line":""},{"line_number":4492,"context_line":""},{"line_number":4493,"context_line":"def migration_get_unconfirmed_by_dest_compute(context, confirm_window,"},{"line_number":4494,"context_line":"                                              dest_compute):"},{"line_number":4495,"context_line":"    confirm_window \u003d (timeutils.utcnow() -"},{"line_number":4496,"context_line":"                      datetime.timedelta(seconds\u003dconfirm_window))"},{"line_number":4497,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"9a8ffd7b_8fcff528","line":4494,"in_reply_to":"9a8ffd7b_cb6292d8","updated":"2015-11-30 13:17:38.000000000","message":"The new decorator was created and merged, just waiting for new version of oslo.db","commit_id":"59198b17267492cbaf78fd4928b1211effea0684"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"2ee7f83069e685b03a668ae7b39cccfd4580a018","unresolved":false,"context_lines":[{"line_number":4491,"context_line":""},{"line_number":4492,"context_line":""},{"line_number":4493,"context_line":"def migration_get_unconfirmed_by_dest_compute(context, confirm_window,"},{"line_number":4494,"context_line":"                                              dest_compute):"},{"line_number":4495,"context_line":"    confirm_window \u003d (timeutils.utcnow() -"},{"line_number":4496,"context_line":"                      datetime.timedelta(seconds\u003dconfirm_window))"},{"line_number":4497,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"9a8ffd7b_cb6292d8","line":4494,"in_reply_to":"ba8a016a_6b75d330","updated":"2015-11-25 10:22:58.000000000","message":"+1 for that idea.","commit_id":"59198b17267492cbaf78fd4928b1211effea0684"},{"author":{"_account_id":9555,"name":"Matthew Booth","email":"mbooth@redhat.com","username":"MatthewBooth"},"change_message_id":"76f9ea24488a23bc1c58f1b3cfc60eaf8e9e266c","unresolved":false,"context_lines":[{"line_number":4491,"context_line":""},{"line_number":4492,"context_line":""},{"line_number":4493,"context_line":"def migration_get_unconfirmed_by_dest_compute(context, confirm_window,"},{"line_number":4494,"context_line":"                                              dest_compute):"},{"line_number":4495,"context_line":"    confirm_window \u003d (timeutils.utcnow() -"},{"line_number":4496,"context_line":"                      datetime.timedelta(seconds\u003dconfirm_window))"},{"line_number":4497,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"ba8a016a_6b75d330","line":4494,"in_reply_to":"ba8a016a_c878852e","updated":"2015-11-20 15:57:42.000000000","message":"I think we need a decorator here. The decorator would be:\n\n@reader_if_not_async(main_context_manager)\n\n... or some better name :) It would check to see if an async context already exists. If it does, it would leave it alone. If it doesn\u0027t, it would invoke the @reader decorator to wrap with a non-async reader context. This would replace *all* reader decorators in this file.\n\nIdeally we\u0027d address this in oslo.db, but if we can agree what the solution looks like we can do something expedient here which we can fix with search/replace later.","commit_id":"59198b17267492cbaf78fd4928b1211effea0684"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"791d3eb28d09b3b891c06ec8587a0e4b9942579f","unresolved":false,"context_lines":[{"line_number":250,"context_line":"            reader_mode \u003d main_context_manager.reader"},{"line_number":251,"context_line":""},{"line_number":252,"context_line":"        with reader_mode.using(args[1]):"},{"line_number":253,"context_line":"            return f(*args, **kwargs)"},{"line_number":254,"context_line":"    return wrapper"},{"line_number":255,"context_line":""},{"line_number":256,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"9a8ffd7b_75e38006","line":253,"updated":"2015-11-30 13:40:14.000000000","message":"yeah, that makes sense.","commit_id":"ad0d7a3da9a29e8fa38a4f36d7fdffed5696b0e4"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"791d3eb28d09b3b891c06ec8587a0e4b9942579f","unresolved":false,"context_lines":[{"line_number":4504,"context_line":"    return result"},{"line_number":4505,"context_line":""},{"line_number":4506,"context_line":""},{"line_number":4507,"context_line":"@main_context_manager.reader.allow_async"},{"line_number":4508,"context_line":"def migration_get_unconfirmed_by_dest_compute(context, confirm_window,"},{"line_number":4509,"context_line":"                                              dest_compute):"},{"line_number":4510,"context_line":"    confirm_window \u003d (timeutils.utcnow() -"}],"source_content_type":"text/x-python","patch_set":6,"id":"9a8ffd7b_15ac748b","line":4507,"updated":"2015-11-30 13:40:14.000000000","message":"can\u0027t we just use select_db_mode here?","commit_id":"ad0d7a3da9a29e8fa38a4f36d7fdffed5696b0e4"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"e6766ddbccbc4e4402e593bf3c226a74eb91d55f","unresolved":false,"context_lines":[{"line_number":4504,"context_line":"    return result"},{"line_number":4505,"context_line":""},{"line_number":4506,"context_line":""},{"line_number":4507,"context_line":"@main_context_manager.reader.allow_async"},{"line_number":4508,"context_line":"def migration_get_unconfirmed_by_dest_compute(context, confirm_window,"},{"line_number":4509,"context_line":"                                              dest_compute):"},{"line_number":4510,"context_line":"    confirm_window \u003d (timeutils.utcnow() -"}],"source_content_type":"text/x-python","patch_set":6,"id":"9a8ffd7b_1e9251f7","line":4507,"in_reply_to":"9a8ffd7b_15ac748b","updated":"2015-11-30 14:23:40.000000000","message":"I\u0027d really like us to remove use_slave keyword arguments from DB API methods implementation and move this knowledge about what expectations we impose on the DB API methods \"up the stack\" - at least to objects layer, or even further. \n\nThus we would:\n\n1) avoid the boiler-plate of passing use_slave keyword argument and handling it in DB API\n\n2) make it possible to extend the scope of one transaction across one DB API method call (e.g. we could reduce the number of DB transactions needed for typical actions in nova-api)\n\nThough, I agree with your comment in another file, that we should not be using things from nova/db/sqalchemy/api.py directly. But nova/db/api.py is fine, IMO.","commit_id":"ad0d7a3da9a29e8fa38a4f36d7fdffed5696b0e4"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"4f94cb3036808d2ae9be13e4ee5b613bd4c47dae","unresolved":false,"context_lines":[{"line_number":249,"context_line":"        else:"},{"line_number":250,"context_line":"            reader_mode \u003d main_context_manager.reader"},{"line_number":251,"context_line":""},{"line_number":252,"context_line":"        with reader_mode.using(args[1]):"},{"line_number":253,"context_line":"            return f(*args, **kwargs)"},{"line_number":254,"context_line":"    return wrapper"},{"line_number":255,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"9a8ffd7b_6ed08af8","line":252,"updated":"2015-11-30 15:34:21.000000000","message":"AFAIU, args[0] will be self / cls depending on the what method we are wrapping.\n\nMaybe we could explicitly take self/cls and context arguments here? And assert on context being instance of RequestContext? (for documentation purposes)","commit_id":"e99ccbd44a81a8849d019c6c512f0c076f43ee6f"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"5bc3c30ac735c0efde174b47243a01ec80570a38","unresolved":false,"context_lines":[{"line_number":249,"context_line":"        else:"},{"line_number":250,"context_line":"            reader_mode \u003d main_context_manager.reader"},{"line_number":251,"context_line":""},{"line_number":252,"context_line":"        with reader_mode.using(args[1]):"},{"line_number":253,"context_line":"            return f(*args, **kwargs)"},{"line_number":254,"context_line":"    return wrapper"},{"line_number":255,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"7a740942_a53914d9","line":252,"in_reply_to":"7a740942_3489edc9","updated":"2015-12-07 21:50:15.000000000","message":"There is also a method in utils.py \u0027expects_func_args\u0027 which could potentially be leveraged as well.  But there needs to be some assurance that args[1] is a context.","commit_id":"e99ccbd44a81a8849d019c6c512f0c076f43ee6f"},{"author":{"_account_id":9555,"name":"Matthew Booth","email":"mbooth@redhat.com","username":"MatthewBooth"},"change_message_id":"11f8e3aaf55c691b30006f41cd5654540e3df0df","unresolved":false,"context_lines":[{"line_number":249,"context_line":"        else:"},{"line_number":250,"context_line":"            reader_mode \u003d main_context_manager.reader"},{"line_number":251,"context_line":""},{"line_number":252,"context_line":"        with reader_mode.using(args[1]):"},{"line_number":253,"context_line":"            return f(*args, **kwargs)"},{"line_number":254,"context_line":"    return wrapper"},{"line_number":255,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"7a740942_3489edc9","line":252,"in_reply_to":"9a8ffd7b_11679f26","updated":"2015-12-07 15:37:45.000000000","message":"Big +1. We\u0027ve already hit a bug in oslo.db due to this.","commit_id":"e99ccbd44a81a8849d019c6c512f0c076f43ee6f"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"45452a51cb0a0efd3c4cf84e72bd073f0d284c19","unresolved":false,"context_lines":[{"line_number":249,"context_line":"        else:"},{"line_number":250,"context_line":"            reader_mode \u003d main_context_manager.reader"},{"line_number":251,"context_line":""},{"line_number":252,"context_line":"        with reader_mode.using(args[1]):"},{"line_number":253,"context_line":"            return f(*args, **kwargs)"},{"line_number":254,"context_line":"    return wrapper"},{"line_number":255,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"9a8ffd7b_11679f26","line":252,"in_reply_to":"9a8ffd7b_6ed08af8","updated":"2015-11-30 15:52:36.000000000","message":"we have some utils for extract context, see:\nhttps://github.com/openstack/nova/blob/master/nova/compute/manager.py#L291\n\nWe should do that for use_slave and context, really.","commit_id":"e99ccbd44a81a8849d019c6c512f0c076f43ee6f"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"45452a51cb0a0efd3c4cf84e72bd073f0d284c19","unresolved":false,"context_lines":[{"line_number":4506,"context_line":""},{"line_number":4507,"context_line":"@main_context_manager.reader.allow_async"},{"line_number":4508,"context_line":"def migration_get_unconfirmed_by_dest_compute(context, confirm_window,"},{"line_number":4509,"context_line":"                                              dest_compute):"},{"line_number":4510,"context_line":"    confirm_window \u003d (timeutils.utcnow() -"},{"line_number":4511,"context_line":"                      datetime.timedelta(seconds\u003dconfirm_window))"},{"line_number":4512,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"9a8ffd7b_b1cfb328","line":4509,"updated":"2015-11-30 15:52:36.000000000","message":"Hmm, I still think I personally would prefer having use_slave passed in here. Just seems much simpler.","commit_id":"e99ccbd44a81a8849d019c6c512f0c076f43ee6f"},{"author":{"_account_id":9555,"name":"Matthew Booth","email":"mbooth@redhat.com","username":"MatthewBooth"},"change_message_id":"11f8e3aaf55c691b30006f41cd5654540e3df0df","unresolved":false,"context_lines":[{"line_number":4506,"context_line":""},{"line_number":4507,"context_line":"@main_context_manager.reader.allow_async"},{"line_number":4508,"context_line":"def migration_get_unconfirmed_by_dest_compute(context, confirm_window,"},{"line_number":4509,"context_line":"                                              dest_compute):"},{"line_number":4510,"context_line":"    confirm_window \u003d (timeutils.utcnow() -"},{"line_number":4511,"context_line":"                      datetime.timedelta(seconds\u003dconfirm_window))"},{"line_number":4512,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"7a740942_54335962","line":4509,"in_reply_to":"9a8ffd7b_b1cfb328","updated":"2015-12-07 15:37:45.000000000","message":"use_slave is a property of the connection, though, which isn\u0027t necessarily established here. It\u0027s a property of whatever creates the connection, so it lives in enginefacade. The code here doesn\u0027t change according to whether a sync or async connection is used, so passing it as an argument it just a source of potential error.\n\nI would personally prefer that *all* reader methods were also allow_async, defaulting to reader if there is no current async context. However, this is fine.","commit_id":"e99ccbd44a81a8849d019c6c512f0c076f43ee6f"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"4fe09130616d4c1872facfe8ff83ad789cab41f1","unresolved":false,"context_lines":[{"line_number":245,"context_line":"    \"\"\""},{"line_number":246,"context_line":""},{"line_number":247,"context_line":"    @functools.wraps(f)"},{"line_number":248,"context_line":"    def wrapper(self, context, *args, **kwargs):"},{"line_number":249,"context_line":"        keyed_args \u003d safe_utils.getcallargs(f, context, *args, **kwargs)"},{"line_number":250,"context_line":"        use_slave \u003d keyed_args[\u0027use_slave\u0027]"},{"line_number":251,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"7a740942_7f711077","line":248,"updated":"2015-12-09 15:12:50.000000000","message":"Nit: why not go for just *args, **kwargs here, to make the whole thing more flexible?","commit_id":"675325a2481fe07aa619937035e94fb529f432f7"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"6d78d37c49f5cf3a55aa8f299ff4e190e4648493","unresolved":false,"context_lines":[{"line_number":242,"context_line":"    \"\"\""},{"line_number":243,"context_line":""},{"line_number":244,"context_line":"    @functools.wraps(f)"},{"line_number":245,"context_line":"    def wrapper(*args, **kwargs):"},{"line_number":246,"context_line":"        keyed_args \u003d safe_utils.getcallargs(f, *args, **kwargs)"},{"line_number":247,"context_line":"        context \u003d keyed_args[\u0027context\u0027]"},{"line_number":248,"context_line":"        use_slave \u003d keyed_args[\u0027use_slave\u0027]"}],"source_content_type":"text/x-python","patch_set":13,"id":"7a740942_eb477b75","line":245,"updated":"2015-12-09 17:25:03.000000000","message":"If you change this to (self, *args, **kwargs) then getcallargs works as expected.  This is is not ideal because then you need a different wrapper if decorating something not on a class.  A better fix would be to update getcallargs to ignore self if passed in, which requires identifying when it has been passed in.\n\nCompare to the usage in https://github.com/openstack/nova/blob/b5890b3c36613919338f83c4f59225f424c99cb1/nova/compute/manager.py#L291 and you\u0027ll see that\u0027s the difference.","commit_id":"142b0a6fdc600553ea383005508e1454a751becd"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"d9b4eb6c72c08849aa20305a9c5b7151ef26c6b0","unresolved":false,"context_lines":[{"line_number":246,"context_line":"        wrapped_func \u003d safe_utils.get_wrapped_function(f)"},{"line_number":247,"context_line":"        keyed_args \u003d inspect.getcallargs(wrapped_func, *args, **kwargs)"},{"line_number":248,"context_line":"        context \u003d keyed_args[\u0027context\u0027]"},{"line_number":249,"context_line":"        use_slave \u003d keyed_args[\u0027use_slave\u0027]"},{"line_number":250,"context_line":""},{"line_number":251,"context_line":"        if use_slave:"},{"line_number":252,"context_line":"            reader_mode \u003d main_context_manager.async"}],"source_content_type":"text/x-python","patch_set":15,"id":"7a740942_1a8a7e1b","line":249,"updated":"2015-12-14 17:13:16.000000000","message":"I don\u0027t think you can assume that \u0027use_slave\u0027 will be present here.  You need to safeguard against that.  Or is this limited to methods that have that?","commit_id":"3db371b4c5b1a1868b353194a4e401733e44de20"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"8a2f303f2fb62c101ac0da3d7bbc58b27ee875ba","unresolved":false,"context_lines":[{"line_number":246,"context_line":"        wrapped_func \u003d safe_utils.get_wrapped_function(f)"},{"line_number":247,"context_line":"        keyed_args \u003d inspect.getcallargs(wrapped_func, *args, **kwargs)"},{"line_number":248,"context_line":"        context \u003d keyed_args[\u0027context\u0027]"},{"line_number":249,"context_line":"        use_slave \u003d keyed_args[\u0027use_slave\u0027]"},{"line_number":250,"context_line":""},{"line_number":251,"context_line":"        if use_slave:"},{"line_number":252,"context_line":"            reader_mode \u003d main_context_manager.async"}],"source_content_type":"text/x-python","patch_set":15,"id":"3a7e1126_21dea33f","line":249,"in_reply_to":"5a710552_7d4fbe92","updated":"2015-12-18 10:13:58.000000000","message":"I guess could be more defensive here, but without the args, that decorator is meaningless, I guess.","commit_id":"3db371b4c5b1a1868b353194a4e401733e44de20"},{"author":{"_account_id":10618,"name":"Pavel Kholkin","email":"p.v.holkin@mail.ru","username":"pkholkin"},"change_message_id":"795aa1afe528bcfa9d123c6d001809feacb88466","unresolved":false,"context_lines":[{"line_number":246,"context_line":"        wrapped_func \u003d safe_utils.get_wrapped_function(f)"},{"line_number":247,"context_line":"        keyed_args \u003d inspect.getcallargs(wrapped_func, *args, **kwargs)"},{"line_number":248,"context_line":"        context \u003d keyed_args[\u0027context\u0027]"},{"line_number":249,"context_line":"        use_slave \u003d keyed_args[\u0027use_slave\u0027]"},{"line_number":250,"context_line":""},{"line_number":251,"context_line":"        if use_slave:"},{"line_number":252,"context_line":"            reader_mode \u003d main_context_manager.async"}],"source_content_type":"text/x-python","patch_set":15,"id":"5a710552_7d4fbe92","line":249,"in_reply_to":"7a740942_1a8a7e1b","updated":"2015-12-15 10:28:26.000000000","message":"We assume that \u0027use_slave\u0027 is always present in the args, but we decide to set default False value for it to make the decorator safe and add corresponding phrase to the doc string.","commit_id":"3db371b4c5b1a1868b353194a4e401733e44de20"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"2c3a9eae14b10f7e15c38d560d35d8ee533dd00c","unresolved":false,"context_lines":[{"line_number":250,"context_line":"        keyed_args \u003d inspect.getcallargs(wrapped_func, *args, **kwargs)"},{"line_number":251,"context_line":""},{"line_number":252,"context_line":"        context \u003d keyed_args[\u0027context\u0027]"},{"line_number":253,"context_line":"        use_slave \u003d keyed_args.get(\u0027use_slave\u0027, False)"},{"line_number":254,"context_line":""},{"line_number":255,"context_line":"        if use_slave:"},{"line_number":256,"context_line":"            reader_mode \u003d main_context_manager.async"}],"source_content_type":"text/x-python","patch_set":18,"id":"3a7e1126_c48c8d81","line":253,"updated":"2015-12-18 10:25:00.000000000","message":"honestly, I slightly preferred the hard requirement on use_slave, but this is OK.","commit_id":"6eb1c0e1bc35a94a4e7b7f80e70489fb1c260eef"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"99327a31fb90213bef2a39b5f416809e62005c52","unresolved":false,"context_lines":[{"line_number":250,"context_line":"        keyed_args \u003d inspect.getcallargs(wrapped_func, *args, **kwargs)"},{"line_number":251,"context_line":""},{"line_number":252,"context_line":"        context \u003d keyed_args[\u0027context\u0027]"},{"line_number":253,"context_line":"        use_slave \u003d keyed_args.get(\u0027use_slave\u0027, False)"},{"line_number":254,"context_line":""},{"line_number":255,"context_line":"        if use_slave:"},{"line_number":256,"context_line":"            reader_mode \u003d main_context_manager.async"}],"source_content_type":"text/x-python","patch_set":18,"id":"3a7e1126_2620e747","line":253,"in_reply_to":"3a7e1126_04e4d50a","updated":"2015-12-18 14:52:40.000000000","message":"The use of use_slave is not as ubiquitous as context so I\u0027d rather not rely on it being there.  And while this wrapper requires a context in order to be functional it does not require use_slave.  use_slave just offers some additional capability.  So I don\u0027t think it should be required in order for the method to work.","commit_id":"6eb1c0e1bc35a94a4e7b7f80e70489fb1c260eef"},{"author":{"_account_id":10618,"name":"Pavel Kholkin","email":"p.v.holkin@mail.ru","username":"pkholkin"},"change_message_id":"6333c992d6bb48be960e0e62e7c79cad2ae94995","unresolved":false,"context_lines":[{"line_number":250,"context_line":"        keyed_args \u003d inspect.getcallargs(wrapped_func, *args, **kwargs)"},{"line_number":251,"context_line":""},{"line_number":252,"context_line":"        context \u003d keyed_args[\u0027context\u0027]"},{"line_number":253,"context_line":"        use_slave \u003d keyed_args.get(\u0027use_slave\u0027, False)"},{"line_number":254,"context_line":""},{"line_number":255,"context_line":"        if use_slave:"},{"line_number":256,"context_line":"            reader_mode \u003d main_context_manager.async"}],"source_content_type":"text/x-python","patch_set":18,"id":"3a7e1126_04e4d50a","line":253,"in_reply_to":"3a7e1126_c48c8d81","updated":"2015-12-18 10:27:44.000000000","message":"yes, of course \u0027use_slave\u0027 should be in args, but still we decide to be safe if somebody forgot to pass it and leave sync context in this case","commit_id":"6eb1c0e1bc35a94a4e7b7f80e70489fb1c260eef"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"410b6b2236b75f23950306dd84c7e9e0f48891bb","unresolved":false,"context_lines":[{"line_number":4481,"context_line":""},{"line_number":4482,"context_line":"@main_context_manager.writer"},{"line_number":4483,"context_line":"def migration_update(context, id, values):"},{"line_number":4484,"context_line":"    migration \u003d migration_get(context, id)"},{"line_number":4485,"context_line":"    migration.update(values)"},{"line_number":4486,"context_line":""},{"line_number":4487,"context_line":"    return migration"}],"source_content_type":"text/x-python","patch_set":18,"id":"3a7e1126_61134bb9","line":4484,"updated":"2015-12-18 10:23:07.000000000","message":"hmm, this one is playing with my head a little. Apparently the decorators play rock, paper, scissors, and writer beats reader, so this is all good.","commit_id":"6eb1c0e1bc35a94a4e7b7f80e70489fb1c260eef"}],"nova/objects/migration.py":[{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"0a59dcb072ad16315a301c77340c3f418acfabdc","unresolved":false,"context_lines":[{"line_number":137,"context_line":""},{"line_number":138,"context_line":"    @base.remotable_classmethod"},{"line_number":139,"context_line":"    def get_unconfirmed_by_dest_compute(cls, context, confirm_window,"},{"line_number":140,"context_line":"                                        dest_compute):"},{"line_number":141,"context_line":"        db_migrations \u003d db.migration_get_unconfirmed_by_dest_compute("},{"line_number":142,"context_line":"            context, confirm_window, dest_compute)"},{"line_number":143,"context_line":"        return base.obj_make_list(context, cls(context), objects.Migration,"}],"source_content_type":"text/x-python","patch_set":1,"id":"da85f559_0f08fd26","line":140,"updated":"2015-11-12 12:41:13.000000000","message":"I think this breaks upgrade, dropping this requires a major version bump I believe.","commit_id":"95395e5181c3594ee1a9ef83a618a0780410ba78"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"f27a5808d2122b5993e55a304854764434a4c3f1","unresolved":false,"context_lines":[{"line_number":135,"context_line":""},{"line_number":136,"context_line":"    @base.remotable_classmethod"},{"line_number":137,"context_line":"    def get_unconfirmed_by_dest_compute(cls, context, confirm_window,"},{"line_number":138,"context_line":"                                        dest_compute, use_slave\u003dFalse):"},{"line_number":139,"context_line":"        db_migrations \u003d db.migration_get_unconfirmed_by_dest_compute("},{"line_number":140,"context_line":"            context, confirm_window, dest_compute)"},{"line_number":141,"context_line":"        return base.obj_make_list(context, cls(context), objects.Migration,"}],"source_content_type":"text/x-python","patch_set":2,"id":"ba8a016a_0dba26c1","line":138,"updated":"2015-11-20 13:34:29.000000000","message":"so to be more precise, we need to keep this interface, so the caller is very explicitly selecting use_slave.\n\nAs an aside, this call goes over RPC, so the caller can\u0027t setup the context as async, because the context gets reset across the RPC call, but thats not really a thing I am worried about here.","commit_id":"7fade2d22bf83d3f9d4c3cab8f7abaa22c86c176"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"f27a5808d2122b5993e55a304854764434a4c3f1","unresolved":false,"context_lines":[{"line_number":136,"context_line":"    @base.remotable_classmethod"},{"line_number":137,"context_line":"    def get_unconfirmed_by_dest_compute(cls, context, confirm_window,"},{"line_number":138,"context_line":"                                        dest_compute, use_slave\u003dFalse):"},{"line_number":139,"context_line":"        db_migrations \u003d db.migration_get_unconfirmed_by_dest_compute("},{"line_number":140,"context_line":"            context, confirm_window, dest_compute)"},{"line_number":141,"context_line":"        return base.obj_make_list(context, cls(context), objects.Migration,"},{"line_number":142,"context_line":"                                  db_migrations)"}],"source_content_type":"text/x-python","patch_set":2,"id":"ba8a016a_cdeadeac","line":139,"updated":"2015-11-20 13:34:29.000000000","message":"this bit could use the decoratored method, or if use_slave\u003dFalse, use a non-decorated method? So switch between async and read based on the use_slave flag.","commit_id":"7fade2d22bf83d3f9d4c3cab8f7abaa22c86c176"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"791d3eb28d09b3b891c06ec8587a0e4b9942579f","unresolved":false,"context_lines":[{"line_number":136,"context_line":"        }"},{"line_number":137,"context_line":""},{"line_number":138,"context_line":"    @base.remotable_classmethod"},{"line_number":139,"context_line":"    @sql_api.select_db_mode"},{"line_number":140,"context_line":"    def get_unconfirmed_by_dest_compute(cls, context, confirm_window,"},{"line_number":141,"context_line":"                                        dest_compute, use_slave\u003dFalse):"},{"line_number":142,"context_line":"        db_migrations \u003d db.migration_get_unconfirmed_by_dest_compute("}],"source_content_type":"text/x-python","patch_set":6,"id":"9a8ffd7b_9597043a","line":139,"updated":"2015-11-30 13:40:14.000000000","message":"it feels like this is sqlalchemy specific, so should stay inside the sqlalchemy API\n\nPutting it here feels like a layer violation.","commit_id":"ad0d7a3da9a29e8fa38a4f36d7fdffed5696b0e4"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"e6766ddbccbc4e4402e593bf3c226a74eb91d55f","unresolved":false,"context_lines":[{"line_number":136,"context_line":"        }"},{"line_number":137,"context_line":""},{"line_number":138,"context_line":"    @base.remotable_classmethod"},{"line_number":139,"context_line":"    @sql_api.select_db_mode"},{"line_number":140,"context_line":"    def get_unconfirmed_by_dest_compute(cls, context, confirm_window,"},{"line_number":141,"context_line":"                                        dest_compute, use_slave\u003dFalse):"},{"line_number":142,"context_line":"        db_migrations \u003d db.migration_get_unconfirmed_by_dest_compute("}],"source_content_type":"text/x-python","patch_set":6,"id":"9a8ffd7b_3e5155d9","line":139,"in_reply_to":"9a8ffd7b_9597043a","updated":"2015-11-30 14:23:40.000000000","message":"How about we make this a part of DB API and put it to nova/db/api.py?","commit_id":"ad0d7a3da9a29e8fa38a4f36d7fdffed5696b0e4"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"45452a51cb0a0efd3c4cf84e72bd073f0d284c19","unresolved":false,"context_lines":[{"line_number":134,"context_line":"        }"},{"line_number":135,"context_line":""},{"line_number":136,"context_line":"    @base.remotable_classmethod"},{"line_number":137,"context_line":"    @db.select_db_reader_mode"},{"line_number":138,"context_line":"    def get_unconfirmed_by_dest_compute(cls, context, confirm_window,"},{"line_number":139,"context_line":"                                        dest_compute, use_slave\u003dFalse):"},{"line_number":140,"context_line":"        db_migrations \u003d db.migration_get_unconfirmed_by_dest_compute("}],"source_content_type":"text/x-python","patch_set":7,"id":"9a8ffd7b_b110135b","line":137,"updated":"2015-11-30 15:52:36.000000000","message":"We should have some tests for this please.","commit_id":"e99ccbd44a81a8849d019c6c512f0c076f43ee6f"},{"author":{"_account_id":9555,"name":"Matthew Booth","email":"mbooth@redhat.com","username":"MatthewBooth"},"change_message_id":"11f8e3aaf55c691b30006f41cd5654540e3df0df","unresolved":false,"context_lines":[{"line_number":134,"context_line":"        }"},{"line_number":135,"context_line":""},{"line_number":136,"context_line":"    @base.remotable_classmethod"},{"line_number":137,"context_line":"    @db.select_db_reader_mode"},{"line_number":138,"context_line":"    def get_unconfirmed_by_dest_compute(cls, context, confirm_window,"},{"line_number":139,"context_line":"                                        dest_compute, use_slave\u003dFalse):"},{"line_number":140,"context_line":"        db_migrations \u003d db.migration_get_unconfirmed_by_dest_compute("}],"source_content_type":"text/x-python","patch_set":7,"id":"7a740942_2f419638","line":137,"in_reply_to":"9a8ffd7b_b110135b","updated":"2015-12-07 15:37:45.000000000","message":"+1","commit_id":"e99ccbd44a81a8849d019c6c512f0c076f43ee6f"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"5e1dd069082bae65efaff26b873a79aac314cf3c","unresolved":false,"context_lines":[{"line_number":128,"context_line":"    #              Migration \u003c\u003d 1.1"},{"line_number":129,"context_line":"    # Version 1.1: Added use_slave to get_unconfirmed_by_dest_compute"},{"line_number":130,"context_line":"    # Version 1.2: Migration version 1.2"},{"line_number":131,"context_line":"    VERSION \u003d \u00271.2\u0027"},{"line_number":132,"context_line":""},{"line_number":133,"context_line":"    fields \u003d {"},{"line_number":134,"context_line":"        \u0027objects\u0027: fields.ListOfObjectsField(\u0027Migration\u0027),"}],"source_content_type":"text/x-python","patch_set":10,"id":"7a740942_d89ce25f","line":131,"updated":"2015-12-09 14:00:42.000000000","message":"The test implies we have to increase the version here, but I suspect if we get ln138 correct, we will not need to bump the version here.","commit_id":"375f749edde90acf8db490de6696887147d225ba"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"5e1dd069082bae65efaff26b873a79aac314cf3c","unresolved":false,"context_lines":[{"line_number":135,"context_line":"        }"},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"    @base.remotable_classmethod"},{"line_number":138,"context_line":"    @db.select_db_reader_mode"},{"line_number":139,"context_line":"    def get_unconfirmed_by_dest_compute(cls, context, confirm_window,"},{"line_number":140,"context_line":"                                        dest_compute, use_slave\u003dFalse):"},{"line_number":141,"context_line":"        db_migrations \u003d db.migration_get_unconfirmed_by_dest_compute("}],"source_content_type":"text/x-python","patch_set":10,"id":"7a740942_b8331662","line":138,"updated":"2015-12-09 14:00:42.000000000","message":"So I think this might be a bad order here. We need the remote to happen, then on the remote host select the db reader mode, otherwise the translation logic gets lost across the wire.\n\nMaybe its cleaner to have a separate _get_unconfirmed_by_dest_compute_impl method that has the decorator added on it, so the other of application is super clear. Not sure.\n\nMaybe it would be better to have a context manager rather than a decorator here, to mutate the context?","commit_id":"375f749edde90acf8db490de6696887147d225ba"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"e14c4b854936e16d884867ea02ea5d6518ea2655","unresolved":false,"context_lines":[{"line_number":135,"context_line":"        }"},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"    @db.select_db_reader_mode"},{"line_number":138,"context_line":"    def _get_unconfirmed_by_dest_compute_impl(cls, context, confirm_window,"},{"line_number":139,"context_line":"                                              dest_compute, use_slave\u003dFalse):"},{"line_number":140,"context_line":"        db_migrations \u003d db.migration_get_unconfirmed_by_dest_compute("},{"line_number":141,"context_line":"            context, confirm_window, dest_compute)"}],"source_content_type":"text/x-python","patch_set":11,"id":"7a740942_ce15f849","line":138,"updated":"2015-12-09 14:34:52.000000000","message":"Nit: Sorry, looking at this, I wonder if we should just have _migration_get_unconfirmed_by_dest_compute() that calls the DB method.","commit_id":"675325a2481fe07aa619937035e94fb529f432f7"}],"nova/tests/unit/objects/test_migration.py":[{"author":{"_account_id":10618,"name":"Pavel Kholkin","email":"p.v.holkin@mail.ru","username":"pkholkin"},"change_message_id":"5b59dbceae784e5e313168337c20f1182e86ef6f","unresolved":false,"context_lines":[{"line_number":150,"context_line":"        db_migrations \u003d [fake_migration, dict(fake_migration, id\u003d456)]"},{"line_number":151,"context_line":"        self.mox.StubOutWithMock("},{"line_number":152,"context_line":"            db, \u0027migration_get_unconfirmed_by_dest_compute\u0027)"},{"line_number":153,"context_line":"        with sql_api.get_db_reader().using(ctxt):"},{"line_number":154,"context_line":"            db.migration_get_unconfirmed_by_dest_compute("},{"line_number":155,"context_line":"                ctxt, \u0027window\u0027, \u0027foo\u0027).AndReturn(db_migrations)"},{"line_number":156,"context_line":"        self.mox.ReplayAll()"}],"source_content_type":"text/x-python","patch_set":4,"id":"ba8a016a_48649548","line":153,"updated":"2015-11-20 15:46:15.000000000","message":"is it needed here?","commit_id":"59198b17267492cbaf78fd4928b1211effea0684"}],"nova/tests/unit/objects/test_objects.py":[{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"5e1dd069082bae65efaff26b873a79aac314cf3c","unresolved":false,"context_lines":[{"line_number":1156,"context_line":"    \u0027KeyPairList\u0027: \u00271.2-58b94f96e776bedaf1e192ddb2a24c4e\u0027,"},{"line_number":1157,"context_line":"    \u0027Migration\u0027: \u00271.2-8784125bedcea0a9227318511904e853\u0027,"},{"line_number":1158,"context_line":"    \u0027MigrationContext\u0027: \u00271.0-d8c2f10069e410f639c49082b5932c92\u0027,"},{"line_number":1159,"context_line":"    \u0027MigrationList\u0027: \u00271.2-c4544ef4c39e438ba4339bc0fc27f125\u0027,"},{"line_number":1160,"context_line":"    \u0027MonitorMetric\u0027: \u00271.1-53b1db7c4ae2c531db79761e7acc52ba\u0027,"},{"line_number":1161,"context_line":"    \u0027MonitorMetricList\u0027: \u00271.1-15ecf022a68ddbb8c2a6739cfc9f8f5e\u0027,"},{"line_number":1162,"context_line":"    \u0027NUMACell\u0027: \u00271.2-74fc993ac5c83005e76e34e8487f1c05\u0027,"}],"source_content_type":"text/x-python","patch_set":10,"id":"7a740942_188caa34","line":1159,"updated":"2015-12-09 14:00:42.000000000","message":"This means the object version has to be increased.","commit_id":"375f749edde90acf8db490de6696887147d225ba"}],"nova/utils.py":[{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"30aa8be9cae463bfd1a3c2fc41cb340729221df9","unresolved":false,"context_lines":[{"line_number":1542,"context_line":""},{"line_number":1543,"context_line":""},{"line_number":1544,"context_line":"def get_db_reader(async):"},{"line_number":1545,"context_line":"    from nova.db.sqlalchemy import api as sql_api"},{"line_number":1546,"context_line":"    if async:"},{"line_number":1547,"context_line":"        return sql_api.main_context_manager.async"},{"line_number":1548,"context_line":"    else:"}],"source_content_type":"text/x-python","patch_set":3,"id":"ba8a016a_2525baad","line":1545,"updated":"2015-11-20 15:16:30.000000000","message":"we should probably add this to our indirection layer in nova.db.api","commit_id":"0d4e60838e9941fe65016ec10b52b6fd30d6c3bc"}]}
