)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":748,"name":"Armando Migliaccio","email":"armamig@gmail.com","username":"armando-migliaccio"},"change_message_id":"a2ca6b85528ca405d53f19aabcce58102bcb3d59","unresolved":false,"context_lines":[{"line_number":7,"context_line":"Introduce the AFTER_READ callback for ports"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"This callback can be used by extensions and service plugins to extend"},{"line_number":10,"context_line":"port information on read time, without the need of plugin mixins."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"Change-Id: Ifc92c19a69d28784c030d605c2eb161c2ba4b3f5"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"fa32b979_3ba646ab","line":10,"updated":"2015-06-25 15:39:00.000000000","message":"Can you point me to how this is used by subscribers? The object being dispatched should be considered immutable, otherwise things may get messy. I didn\u0027t think it was necessary, as a way to enforce this constraint, to make a copy of the object being dispatched because of the cost involved, but Python is not expressive enough to allow us any other way to allow readonly use.\n\nI should probably make a note in the callback devref.\n\nDoes this complicate your use case?","commit_id":"0aafa932e15df8c661dfac25a977bc511aac32dc"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"f59358f23d6c1558e9cdd4f67380da41e3b98f7c","unresolved":false,"context_lines":[{"line_number":7,"context_line":"Introduce the AFTER_READ callback for ports"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"This callback can be used by extensions and service plugins to extend"},{"line_number":10,"context_line":"port information on read time, without the need of plugin mixins."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"Change-Id: Ifc92c19a69d28784c030d605c2eb161c2ba4b3f5"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"fa32b979_cd009c38","line":10,"in_reply_to":"fa32b979_0d97643b","updated":"2015-06-26 09:25:08.000000000","message":"Nah, I probably bad at wording. I said that we should instead allow callback mechanism to apply extension based on what callback provides, but guard against non-additive changes. And there is no need for a separate event since callback user can just say that it\u0027s interested in extending the object on registration time.","commit_id":"0aafa932e15df8c661dfac25a977bc511aac32dc"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"49b4206cc574624154a9f79ae7527c3ff6e28c57","unresolved":false,"context_lines":[{"line_number":7,"context_line":"Introduce the AFTER_READ callback for ports"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"This callback can be used by extensions and service plugins to extend"},{"line_number":10,"context_line":"port information on read time, without the need of plugin mixins."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"Change-Id: Ifc92c19a69d28784c030d605c2eb161c2ba4b3f5"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"fa32b979_f0777739","line":10,"in_reply_to":"fa32b979_106c5bcf","updated":"2015-06-26 09:36:39.000000000","message":"Yeah, sounds like a plan. I am not sure we want to raise exception instead of silently ignoring the issue though.","commit_id":"0aafa932e15df8c661dfac25a977bc511aac32dc"},{"author":{"_account_id":748,"name":"Armando Migliaccio","email":"armamig@gmail.com","username":"armando-migliaccio"},"change_message_id":"87ffafe30df3a329996784df968e07f2cb0dfbb4","unresolved":false,"context_lines":[{"line_number":7,"context_line":"Introduce the AFTER_READ callback for ports"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"This callback can be used by extensions and service plugins to extend"},{"line_number":10,"context_line":"port information on read time, without the need of plugin mixins."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"Change-Id: Ifc92c19a69d28784c030d605c2eb161c2ba4b3f5"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"fa32b979_9a3945db","line":10,"in_reply_to":"fa32b979_2cc4955d","updated":"2015-06-27 00:33:03.000000000","message":"wanna let me have a stab at this?","commit_id":"0aafa932e15df8c661dfac25a977bc511aac32dc"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"dbaca2a8ff22744692e5473be547181ec5b5586e","unresolved":false,"context_lines":[{"line_number":7,"context_line":"Introduce the AFTER_READ callback for ports"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"This callback can be used by extensions and service plugins to extend"},{"line_number":10,"context_line":"port information on read time, without the need of plugin mixins."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"Change-Id: Ifc92c19a69d28784c030d605c2eb161c2ba4b3f5"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"fa32b979_0d97643b","line":10,"in_reply_to":"fa32b979_2d7108a9","updated":"2015-06-26 09:19:01.000000000","message":"Hmm, that makes sense Ihar, I believe making a separate event should make code design simpler.\n\n@armax, what do you think? :)","commit_id":"0aafa932e15df8c661dfac25a977bc511aac32dc"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"bd05e29396c0d524cf872e56597c1f9674ac86a7","unresolved":false,"context_lines":[{"line_number":7,"context_line":"Introduce the AFTER_READ callback for ports"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"This callback can be used by extensions and service plugins to extend"},{"line_number":10,"context_line":"port information on read time, without the need of plugin mixins."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"Change-Id: Ifc92c19a69d28784c030d605c2eb161c2ba4b3f5"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"fa32b979_da93745b","line":10,"in_reply_to":"fa32b979_3ba646ab","updated":"2015-06-26 08:59:07.000000000","message":"The idea is that service plugins subscribe to the AFTER_READ event, and extend any core resources which have been read with new fields (or new sub-objects when we have objects...)\n\nhttps://review.openstack.org/#/c/189628/4/neutron/services/qos/qos_plugin.py  (L64 here)\n\nIf we make the object immutable for the read case I cannot think of other ways for extending core resources by service plugins without mixins or without making a very similar mechanism to callback just for extending them, ok:\n\nHow does it sound if we introduce specific callbacks just for object extension at read?, and then we can fully control order of events: for example, we first call AFTER_READ_EXTEND, and then AFTER_READ ..  \n\nThis way all the AFTER_READ subscribers will get the extended resource. And we make AFTER_READ immutable, and any READ_EXTEND parameters mutable.\n\nWARNING/PLEASE HELP ;) :\nPlease, note that without this piece I really don\u0027t know how to do the QoS part without mixins, we may need your guidance, and the coding-sprint is next week :( . Any other ideas?","commit_id":"0aafa932e15df8c661dfac25a977bc511aac32dc"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"615096247b83f2cbee497b7cb8b26b84aa4627aa","unresolved":false,"context_lines":[{"line_number":7,"context_line":"Introduce the AFTER_READ callback for ports"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"This callback can be used by extensions and service plugins to extend"},{"line_number":10,"context_line":"port information on read time, without the need of plugin mixins."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"Change-Id: Ifc92c19a69d28784c030d605c2eb161c2ba4b3f5"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"fa32b979_0b6ddacb","line":10,"in_reply_to":"fa32b979_9a3945db","updated":"2015-06-28 05:59:11.000000000","message":"@Armando, we would like to see the decision till the start of qos code sprint. If you like, you can get a draft with API described just to make sure we are on the same page, and send it as WIP, then we\u0027ll hop it and implement. Comments?","commit_id":"0aafa932e15df8c661dfac25a977bc511aac32dc"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"02d694a0ef5736b100b8edbb167b2bc18c31c57e","unresolved":false,"context_lines":[{"line_number":7,"context_line":"Introduce the AFTER_READ callback for ports"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"This callback can be used by extensions and service plugins to extend"},{"line_number":10,"context_line":"port information on read time, without the need of plugin mixins."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"Change-Id: Ifc92c19a69d28784c030d605c2eb161c2ba4b3f5"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"fa32b979_106c5bcf","line":10,"in_reply_to":"fa32b979_cd009c38","updated":"2015-06-26 09:30:27.000000000","message":"Ok,\n\n\nHow does this strategy sound then (based on your comments):  collecting a list of the return results (dicts) of all callback callees, and then, after all the callbacks have been called, we extend the resource (in the callback library) for all the non-existing fields, and ... throw an exception if the field already existed?\n\nWe can also send the subscribers a copy of the object to avoid direct modification...\n\nThis way we can also trace/log/debug if we wanted what fields have been extended on every read.","commit_id":"0aafa932e15df8c661dfac25a977bc511aac32dc"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"f041bf0ebb506a572b2d21e8d992a08983825611","unresolved":false,"context_lines":[{"line_number":7,"context_line":"Introduce the AFTER_READ callback for ports"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"This callback can be used by extensions and service plugins to extend"},{"line_number":10,"context_line":"port information on read time, without the need of plugin mixins."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"Change-Id: Ifc92c19a69d28784c030d605c2eb161c2ba4b3f5"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"fa32b979_7a7ca8eb","line":10,"in_reply_to":"fa32b979_da93745b","updated":"2015-06-26 09:02:29.000000000","message":"Another option to AFTER_READ_EXTEND \u003d\u003e EXTEND_READ ? \n\nI\u0027m not sure we may need other cases of extending but for READ, for write\u0027s the information should be there, and just every interested party just picks up it\u0027s piece.","commit_id":"0aafa932e15df8c661dfac25a977bc511aac32dc"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"b15552cbc87a21a551777f80db15f5f158d56f61","unresolved":false,"context_lines":[{"line_number":7,"context_line":"Introduce the AFTER_READ callback for ports"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"This callback can be used by extensions and service plugins to extend"},{"line_number":10,"context_line":"port information on read time, without the need of plugin mixins."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"Change-Id: Ifc92c19a69d28784c030d605c2eb161c2ba4b3f5"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"fa32b979_2d7108a9","line":10,"in_reply_to":"fa32b979_da93745b","updated":"2015-06-26 09:11:26.000000000","message":"So, I think Armando is right in saying that callbacks should not modify existing properties of the object. Otherwise we may get into situation where one callback depends on another being executed before or after itself.\n\nI think it\u0027s a good thing if we guard the object from modifications by e.g. copying it.\n\nThough there are still other ways to extend an object. Let\u0027s say an interested party registers a callback, saying (with an argument to register function) that it is also interested in extending the object after the event is handled. After that, when the callback is executed, it returns some kind of extension specification, and callback mechanism then can proceed with extending the object, while making sure that e.g. no existing fields are touched.\n\nI would try to avoid adding separate event types just to differentiate extension callbacks from normal.","commit_id":"0aafa932e15df8c661dfac25a977bc511aac32dc"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"6ee3589ff1aa0825f5e092bc0634a91ff2a2c33f","unresolved":false,"context_lines":[{"line_number":7,"context_line":"Introduce the AFTER_READ callback for ports"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"This callback can be used by extensions and service plugins to extend"},{"line_number":10,"context_line":"port information on read time, without the need of plugin mixins."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"Change-Id: Ifc92c19a69d28784c030d605c2eb161c2ba4b3f5"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"fa32b979_2cc4955d","line":10,"in_reply_to":"fa32b979_efdb027c","updated":"2015-06-26 16:56:18.000000000","message":"@armax, it sounds good to me, this way we also have the control over how things happen (first receiving all the published stuff), and then calling the callbacks or... in reverse as it makes more sense.\n\nSounds good to me!!, I can work on it.","commit_id":"0aafa932e15df8c661dfac25a977bc511aac32dc"},{"author":{"_account_id":748,"name":"Armando Migliaccio","email":"armamig@gmail.com","username":"armando-migliaccio"},"change_message_id":"d0720bf5379135c0cfd1b25bb6e17b9633cb6771","unresolved":false,"context_lines":[{"line_number":7,"context_line":"Introduce the AFTER_READ callback for ports"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"This callback can be used by extensions and service plugins to extend"},{"line_number":10,"context_line":"port information on read time, without the need of plugin mixins."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"Change-Id: Ifc92c19a69d28784c030d605c2eb161c2ba4b3f5"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"fa32b979_efdb027c","line":10,"in_reply_to":"fa32b979_f0777739","updated":"2015-06-26 16:16:11.000000000","message":"Lots to digest here, but I was envisioning extending the callback registry with new APIs, \u0027receive\u0027, that an object would call to retrieve N responses from objects that are interested in \u0027publishing\u0027 a certain payload, and \u0027advertise\u0027 API that an object would call to manifest the intention of advertising something. So for instance:\n\n def receive(resource, event, identifier):\n    \"\"\"Return messages pertaining the resource identified by identifier during a specific event.\"\"\" \n    # This will loop over all publishers interested in advertising stuff about the resource\n    pass\n\n def enroll(publisher, resource, event):\n    \"\"\"Enroll publisher to parties interested in advertising...\"\"\"\n    # publisher is method that reports the info to be returned during \u0027receive\u0027 loop\n\nEffectively, this is pretty equivalent to subscribe/notify, but we\u0027re explicitly distinguishing between the objectives of the two API\u0027s.\n\nOne is aimed at \u0027notifying\u0027 stuff; the other is done about \u0027receiving\u0027 stuff.\n\nThoughts?","commit_id":"0aafa932e15df8c661dfac25a977bc511aac32dc"}],"neutron/db/db_base_plugin_common.py":[{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"ba8230a9596c606822fc585e05822127284ebc58","unresolved":false,"context_lines":[{"line_number":151,"context_line":"            # registry (enroll, receive)."},{"line_number":152,"context_line":"            kwargs \u003d {\u0027context\u0027: None, \u0027port_dict\u0027: res}"},{"line_number":153,"context_line":"            registry.notify("},{"line_number":154,"context_line":"                resources.PORT, events.AFTER_READ, None, **kwargs)"},{"line_number":155,"context_line":"        return self._fields(res, fields)"},{"line_number":156,"context_line":""},{"line_number":157,"context_line":"    def _get_network(self, context, id):"}],"source_content_type":"text/x-python","patch_set":2,"id":"ba3cc151_85978b8f","line":154,"updated":"2015-06-30 18:25:49.000000000","message":"in this case I believe it makes sense to use a different name, instead of AFTER_READ for this temporary thing, something more like EXTEND_OBJECT or EXTEND, or so, otherwise it\u0027s confusing, since we\u0027re not reading here, but just constructing/extending the dict.","commit_id":"8a4605e857fcd6f7aa10aaca8e41ebef54dc636f"},{"author":{"_account_id":7921,"name":"Mike Kolesnik","email":"mkolesni@redhat.com","username":"mkolesni"},"change_message_id":"525ff0202bdd361d33b1efe4d821c41a58ac81ea","unresolved":false,"context_lines":[{"line_number":151,"context_line":"            # registry (enroll, receive)."},{"line_number":152,"context_line":"            kwargs \u003d {\u0027context\u0027: None, \u0027port_dict\u0027: res}"},{"line_number":153,"context_line":"            registry.notify("},{"line_number":154,"context_line":"                resources.PORT, events.AFTER_READ, None, **kwargs)"},{"line_number":155,"context_line":"        return self._fields(res, fields)"},{"line_number":156,"context_line":""},{"line_number":157,"context_line":"    def _get_network(self, context, id):"}],"source_content_type":"text/x-python","patch_set":2,"id":"ba3cc151_3527b465","line":154,"in_reply_to":"ba3cc151_85978b8f","updated":"2015-07-01 10:15:21.000000000","message":"I don\u0027t believe we need to change it ATM since we\u0027re planning to change the registry API anyway so I believe it should be part of that change..","commit_id":"8a4605e857fcd6f7aa10aaca8e41ebef54dc636f"},{"author":{"_account_id":11343,"name":"Gal Sagie","email":"gal.sagie@gmail.com","username":"GalSagie"},"change_message_id":"27ad1f18f467c3d4fb8051f96363e386cec191ff","unresolved":false,"context_lines":[{"line_number":246,"context_line":"                attributes.NETWORKS, res, network)"},{"line_number":247,"context_line":"            # TODO(QoS): Once its available, use the new API for the callback"},{"line_number":248,"context_line":"            # registry (enroll, receive)."},{"line_number":249,"context_line":"            kwargs \u003d {\u0027context\u0027: None, \u0027port_dict\u0027: res}"},{"line_number":250,"context_line":"            registry.notify("},{"line_number":251,"context_line":"                resources.NETWORK, events.AFTER_READ, None, **kwargs)"},{"line_number":252,"context_line":"        return self._fields(res, fields)"}],"source_content_type":"text/x-python","patch_set":2,"id":"ba3cc151_4aa0b29f","line":249,"updated":"2015-06-30 18:10:02.000000000","message":"you mean network_dict not port_dict","commit_id":"8a4605e857fcd6f7aa10aaca8e41ebef54dc636f"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"ba8230a9596c606822fc585e05822127284ebc58","unresolved":false,"context_lines":[{"line_number":246,"context_line":"                attributes.NETWORKS, res, network)"},{"line_number":247,"context_line":"            # TODO(QoS): Once its available, use the new API for the callback"},{"line_number":248,"context_line":"            # registry (enroll, receive)."},{"line_number":249,"context_line":"            kwargs \u003d {\u0027context\u0027: None, \u0027port_dict\u0027: res}"},{"line_number":250,"context_line":"            registry.notify("},{"line_number":251,"context_line":"                resources.NETWORK, events.AFTER_READ, None, **kwargs)"},{"line_number":252,"context_line":"        return self._fields(res, fields)"}],"source_content_type":"text/x-python","patch_set":2,"id":"ba3cc151_a53defbc","line":249,"in_reply_to":"ba3cc151_4aa0b29f","updated":"2015-06-30 18:25:49.000000000","message":"good catch :)","commit_id":"8a4605e857fcd6f7aa10aaca8e41ebef54dc636f"},{"author":{"_account_id":7921,"name":"Mike Kolesnik","email":"mkolesni@redhat.com","username":"mkolesni"},"change_message_id":"525ff0202bdd361d33b1efe4d821c41a58ac81ea","unresolved":false,"context_lines":[{"line_number":246,"context_line":"                attributes.NETWORKS, res, network)"},{"line_number":247,"context_line":"            # TODO(QoS): Once its available, use the new API for the callback"},{"line_number":248,"context_line":"            # registry (enroll, receive)."},{"line_number":249,"context_line":"            kwargs \u003d {\u0027context\u0027: None, \u0027port_dict\u0027: res}"},{"line_number":250,"context_line":"            registry.notify("},{"line_number":251,"context_line":"                resources.NETWORK, events.AFTER_READ, None, **kwargs)"},{"line_number":252,"context_line":"        return self._fields(res, fields)"}],"source_content_type":"text/x-python","patch_set":2,"id":"ba3cc151_151dd00e","line":249,"in_reply_to":"ba3cc151_a53defbc","updated":"2015-07-01 10:15:21.000000000","message":"Done","commit_id":"8a4605e857fcd6f7aa10aaca8e41ebef54dc636f"},{"author":{"_account_id":9423,"name":"Roey Chen","email":"roeyc@vmware.com","username":"roeyc"},"change_message_id":"f2fe2f48bc4302a4fab69cac188e2d25ad217d00","unresolved":false,"context_lines":[{"line_number":124,"context_line":"        # TODO(QoS): Once its available, use the new API for the callback"},{"line_number":125,"context_line":"        # registry (enroll, receive)."},{"line_number":126,"context_line":"        try:"},{"line_number":127,"context_line":"            # TODO(QoS): Figure out what to send as context"},{"line_number":128,"context_line":"            ctx \u003d context.get_admin_context()"},{"line_number":129,"context_line":"            kwargs \u003d {\u0027context\u0027: ctx, resource_type: resource}"},{"line_number":130,"context_line":"            registry.notify("}],"source_content_type":"text/x-python","patch_set":11,"id":"ba3cc151_92ff1aaa","line":127,"updated":"2015-07-05 12:05:17.000000000","message":"I guess that you want the same context that the request was initiated with,\nperhaps you have only admin only readable attributes..","commit_id":"e3dba1424114575581c153e02227282e036ad0a2"},{"author":{"_account_id":9423,"name":"Roey Chen","email":"roeyc@vmware.com","username":"roeyc"},"change_message_id":"f2fe2f48bc4302a4fab69cac188e2d25ad217d00","unresolved":false,"context_lines":[{"line_number":130,"context_line":"            registry.notify("},{"line_number":131,"context_line":"                resource_type, event_type, None, **kwargs)"},{"line_number":132,"context_line":"        except exceptions.CallbackFailure:"},{"line_number":133,"context_line":"            # TODO(QoS): Decide what to actually do here"},{"line_number":134,"context_line":"            pass"},{"line_number":135,"context_line":""},{"line_number":136,"context_line":"    def _make_port_dict(self, port, fields\u003dNone,"}],"source_content_type":"text/x-python","patch_set":11,"id":"ba3cc151_122a2a2d","line":133,"updated":"2015-07-05 12:05:17.000000000","message":"Maybe debug-log it here, and debug-error in the callback itself?","commit_id":"e3dba1424114575581c153e02227282e036ad0a2"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"3f28b468a31c1725b87397d3b578f997ec44dc92","unresolved":false,"context_lines":[{"line_number":244,"context_line":"        if process_extensions:"},{"line_number":245,"context_line":"            self._apply_dict_extend_functions("},{"line_number":246,"context_line":"                attributes.NETWORKS, res, network)"},{"line_number":247,"context_line":"            self._extend_resource(resources.NETWORK, events.AFTER_READ, res)"},{"line_number":248,"context_line":""},{"line_number":249,"context_line":"        return self._fields(res, fields)"},{"line_number":250,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"ba3cc151_1fc78346","line":247,"updated":"2015-07-06 10:37:20.000000000","message":"is resources.NETWORK correct?","commit_id":"e3dba1424114575581c153e02227282e036ad0a2"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"0a61461b2bfd1478a462c1c1fecb9175a5fbbe39","unresolved":false,"context_lines":[{"line_number":244,"context_line":"        if process_extensions:"},{"line_number":245,"context_line":"            self._apply_dict_extend_functions("},{"line_number":246,"context_line":"                attributes.NETWORKS, res, network)"},{"line_number":247,"context_line":"            self._extend_resource(resources.NETWORK, events.AFTER_READ, res)"},{"line_number":248,"context_line":""},{"line_number":249,"context_line":"        return self._fields(res, fields)"},{"line_number":250,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"ba3cc151_9f995322","line":247,"in_reply_to":"ba3cc151_1fc78346","updated":"2015-07-06 10:42:57.000000000","message":"oops.","commit_id":"e3dba1424114575581c153e02227282e036ad0a2"}],"neutron/tests/unit/plugins/ml2/test_plugin.py":[{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"fa4d02af55155ca652eb948f81bea9707c130787","unresolved":false,"context_lines":[{"line_number":1606,"context_line":"                   \u0027_raise_if_updates_provider_attributes\u0027).start()"},{"line_number":1607,"context_line":""},{"line_number":1608,"context_line":"        self.notify.side_effect \u003d ("},{"line_number":1609,"context_line":"            lambda r, e, t, **kwargs: None if e \u003d\u003d events.AFTER_READ"},{"line_number":1610,"context_line":"            else self._ensure_transaction_is_closed())"},{"line_number":1611,"context_line":""},{"line_number":1612,"context_line":"        return plugin"}],"source_content_type":"text/x-python","patch_set":2,"id":"ba3cc151_5b02c20c","line":1609,"updated":"2015-06-30 19:26:34.000000000","message":"So is it part of your intended semantics that you get the callback called from under the same transaction as read? Can you explicitly describe it somehow? And if that\u0027s the explicit expectation, then why don\u0027t we check for the transaction to be still opened in that side_effect?","commit_id":"8a4605e857fcd6f7aa10aaca8e41ebef54dc636f"},{"author":{"_account_id":7921,"name":"Mike Kolesnik","email":"mkolesni@redhat.com","username":"mkolesni"},"change_message_id":"525ff0202bdd361d33b1efe4d821c41a58ac81ea","unresolved":false,"context_lines":[{"line_number":1606,"context_line":"                   \u0027_raise_if_updates_provider_attributes\u0027).start()"},{"line_number":1607,"context_line":""},{"line_number":1608,"context_line":"        self.notify.side_effect \u003d ("},{"line_number":1609,"context_line":"            lambda r, e, t, **kwargs: None if e \u003d\u003d events.AFTER_READ"},{"line_number":1610,"context_line":"            else self._ensure_transaction_is_closed())"},{"line_number":1611,"context_line":""},{"line_number":1612,"context_line":"        return plugin"}],"source_content_type":"text/x-python","patch_set":2,"id":"ba3cc151_55eb58b0","line":1609,"in_reply_to":"ba3cc151_5b02c20c","updated":"2015-07-01 10:15:21.000000000","message":"No this test is expecting transaction close when you\u0027re notifying about create/update/delete it doesn\u0027t care what you do about read.\nI\u0027ll add a comment..","commit_id":"8a4605e857fcd6f7aa10aaca8e41ebef54dc636f"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"fa4d02af55155ca652eb948f81bea9707c130787","unresolved":false,"context_lines":[{"line_number":1652,"context_line":"                \u0027context\u0027: self.context,"},{"line_number":1653,"context_line":"                \u0027network\u0027: mock.ANY,"},{"line_number":1654,"context_line":"            }"},{"line_number":1655,"context_line":"            self.notify.assert_called_with(\u0027network\u0027, \u0027after_update\u0027,"},{"line_number":1656,"context_line":"                plugin, **kwargs)"}],"source_content_type":"text/x-python","patch_set":2,"id":"ba3cc151_d67f8764","line":1655,"updated":"2015-06-30 19:26:34.000000000","message":"Not sure I follow why the change.","commit_id":"8a4605e857fcd6f7aa10aaca8e41ebef54dc636f"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"34a238c8b4728e1aa0778a2214f288247502482f","unresolved":false,"context_lines":[{"line_number":1652,"context_line":"                \u0027context\u0027: self.context,"},{"line_number":1653,"context_line":"                \u0027network\u0027: mock.ANY,"},{"line_number":1654,"context_line":"            }"},{"line_number":1655,"context_line":"            self.notify.assert_called_with(\u0027network\u0027, \u0027after_update\u0027,"},{"line_number":1656,"context_line":"                plugin, **kwargs)"}],"source_content_type":"text/x-python","patch_set":2,"id":"ba3cc151_864e9594","line":1655,"in_reply_to":"ba3cc151_d67f8764","updated":"2015-07-01 09:18:57.000000000","message":"I think before only one call happened, and now there are more calls, not only \"after_update\". But we don\u0027t care about those here?","commit_id":"8a4605e857fcd6f7aa10aaca8e41ebef54dc636f"},{"author":{"_account_id":7921,"name":"Mike Kolesnik","email":"mkolesni@redhat.com","username":"mkolesni"},"change_message_id":"525ff0202bdd361d33b1efe4d821c41a58ac81ea","unresolved":false,"context_lines":[{"line_number":1652,"context_line":"                \u0027context\u0027: self.context,"},{"line_number":1653,"context_line":"                \u0027network\u0027: mock.ANY,"},{"line_number":1654,"context_line":"            }"},{"line_number":1655,"context_line":"            self.notify.assert_called_with(\u0027network\u0027, \u0027after_update\u0027,"},{"line_number":1656,"context_line":"                plugin, **kwargs)"}],"source_content_type":"text/x-python","patch_set":2,"id":"ba3cc151_55027870","line":1655,"in_reply_to":"ba3cc151_d67f8764","updated":"2015-07-01 10:15:21.000000000","message":"assert_called_once_with makes sure that the notify object was called exactly once and with those exact parameters.\n\nSince we also notify on read this is not a good assertion anymore so instead we just check that it was called with those parameters.","commit_id":"8a4605e857fcd6f7aa10aaca8e41ebef54dc636f"}]}
