)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":7448,"name":"Carl Baldwin","email":"carl@ecbaldwin.net","username":"carl-baldwin"},"change_message_id":"2c989a852fca4b53b173f42e7b0cbb7bab5bfd77","unresolved":false,"context_lines":[{"line_number":13,"context_line":"multiple processes trying to read/write the same socket connection."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"It is also useful for a plugin to be able to do something in only"},{"line_number":16,"context_line":"one process, regardless of how many workers are forked. One example"},{"line_number":17,"context_line":"would be handling syncing from an external system to the neutron"},{"line_number":18,"context_line":"database."},{"line_number":19,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"fa32b979_3aa9dcdf","line":16,"updated":"2015-06-16 19:41:16.000000000","message":"How will this patch set facilitate this?","commit_id":"bed52b0b7972f482f17bf8e4ad24ee8810c89299"},{"author":{"_account_id":5756,"name":"Terry Wilson","email":"twilson@redhat.com","username":"otherwiseguy"},"change_message_id":"d50fa113f348f63f8c06b6ee231834904da9108a","unresolved":false,"context_lines":[{"line_number":13,"context_line":"multiple processes trying to read/write the same socket connection."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"It is also useful for a plugin to be able to do something in only"},{"line_number":16,"context_line":"one process, regardless of how many workers are forked. One example"},{"line_number":17,"context_line":"would be handling syncing from an external system to the neutron"},{"line_number":18,"context_line":"database."},{"line_number":19,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"fa32b979_d0f9af81","line":16,"in_reply_to":"fa32b979_3aa9dcdf","updated":"2015-06-16 20:37:05.000000000","message":"An example would be if a plugin or ml2 mech driver in the ml2 plugin case defined the get_processes() method and it returned [self.some_function, self.some_other_function], then two processes would be spawned executing those two functions.","commit_id":"bed52b0b7972f482f17bf8e4ad24ee8810c89299"},{"author":{"_account_id":7448,"name":"Carl Baldwin","email":"carl@ecbaldwin.net","username":"carl-baldwin"},"change_message_id":"170e84ee04c12771e2d812094da4024c894682d6","unresolved":false,"context_lines":[{"line_number":13,"context_line":"multiple processes trying to read/write the same socket connection."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"It is also useful for a plugin to be able to do something in only"},{"line_number":16,"context_line":"one process, regardless of how many workers are forked. One example"},{"line_number":17,"context_line":"would be handling syncing from an external system to the neutron"},{"line_number":18,"context_line":"database."},{"line_number":19,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"fa32b979_9a32365d","line":16,"in_reply_to":"fa32b979_d0f9af81","updated":"2015-06-17 18:43:15.000000000","message":"Okay, that makes sense.  I was just in a different frame of mind.","commit_id":"bed52b0b7972f482f17bf8e4ad24ee8810c89299"},{"author":{"_account_id":7448,"name":"Carl Baldwin","email":"carl@ecbaldwin.net","username":"carl-baldwin"},"change_message_id":"2c989a852fca4b53b173f42e7b0cbb7bab5bfd77","unresolved":false,"context_lines":[{"line_number":22,"context_line":"   handling notification that forking has completed. In the"},{"line_number":23,"context_line":"   existing code, calling the notification in the Worker object\u0027s"},{"line_number":24,"context_line":"   start() method would happen twice in the case where both api"},{"line_number":25,"context_line":"   and rpc workers were 0, despite there being only one process."},{"line_number":26,"context_line":"2) Adds notification of forking via the callbacks mechanism."},{"line_number":27,"context_line":"   Plugins cans subscribe to resources.PROCESS, event.AFTER_CREATE"},{"line_number":28,"context_line":"   and do any post-fork initialization that needs to be done for"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"fa32b979_2ed202d3","line":25,"updated":"2015-06-16 19:41:16.000000000","message":"This seems like it might be kind of a big deal.  \u003d0 means everything was in the same process.  \u003d1 means that a worker would be spawned.  This means RPC and API will now be in separate processes by default.  They were both running in the same parent process with \u003d0.\n\nI think I\u0027d rather this come in a follow-on patch.  It didn\u0027t look like it was absolutely necessary to me.  Is it?\n\nThe follow on will let us do more testing on this part of the change on its own.","commit_id":"bed52b0b7972f482f17bf8e4ad24ee8810c89299"},{"author":{"_account_id":5756,"name":"Terry Wilson","email":"twilson@redhat.com","username":"otherwiseguy"},"change_message_id":"d50fa113f348f63f8c06b6ee231834904da9108a","unresolved":false,"context_lines":[{"line_number":22,"context_line":"   handling notification that forking has completed. In the"},{"line_number":23,"context_line":"   existing code, calling the notification in the Worker object\u0027s"},{"line_number":24,"context_line":"   start() method would happen twice in the case where both api"},{"line_number":25,"context_line":"   and rpc workers were 0, despite there being only one process."},{"line_number":26,"context_line":"2) Adds notification of forking via the callbacks mechanism."},{"line_number":27,"context_line":"   Plugins cans subscribe to resources.PROCESS, event.AFTER_CREATE"},{"line_number":28,"context_line":"   and do any post-fork initialization that needs to be done for"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"fa32b979_305edb76","line":25,"in_reply_to":"fa32b979_2ed202d3","updated":"2015-06-16 20:37:05.000000000","message":"It *can* ben done, but it is *a lot* messier. Instead of just emitting a notification in start(), you would have to check for the special case of both \u003d0 and then pass down a \u0027don\u0027t send a notification\u0027 flag through the tree of serve_rpc/serve_wsgi/RpcWorker/ApiWorker/PluginWorker stuff and hold off on sending that \"after fork\" notification (even though it is then poorly named). It is just really, really ugly.\n\nThis change *could* break things by changing the default. But, if it *does* break something, then that thing was already completely broken for api/rpc_workers !\u003d 0 and absolutely would need to be fixed. Otherwise, things are just kind of working by accident in only a very specific configuration.","commit_id":"bed52b0b7972f482f17bf8e4ad24ee8810c89299"},{"author":{"_account_id":7448,"name":"Carl Baldwin","email":"carl@ecbaldwin.net","username":"carl-baldwin"},"change_message_id":"170e84ee04c12771e2d812094da4024c894682d6","unresolved":false,"context_lines":[{"line_number":22,"context_line":"   handling notification that forking has completed. In the"},{"line_number":23,"context_line":"   existing code, calling the notification in the Worker object\u0027s"},{"line_number":24,"context_line":"   start() method would happen twice in the case where both api"},{"line_number":25,"context_line":"   and rpc workers were 0, despite there being only one process."},{"line_number":26,"context_line":"2) Adds notification of forking via the callbacks mechanism."},{"line_number":27,"context_line":"   Plugins cans subscribe to resources.PROCESS, event.AFTER_CREATE"},{"line_number":28,"context_line":"   and do any post-fork initialization that needs to be done for"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"fa32b979_a244acb6","line":25,"in_reply_to":"fa32b979_305edb76","updated":"2015-06-17 18:43:15.000000000","message":"I know that workers !\u003d 0 generally works because we\u0027re using it in the wild.  The question is whether there are tests in the gate that break with it.  These tests could be exposing something we just don\u0027t see in the wild or the tests might be broken.  Or, maybe we\u0027ve just turned a blind eye to a real problem!\n\nMy point is that we have seen instability when trying to set this to anything but the default in the gate and no one has ever stepped up to get to the bottom of the issue and get it fixed.  I\u0027m just a bit worried that if we tie this change to this then we will be forced to either put up the resources to fix the issues or revert this patch.  In the past, we have either reverted [1] or just not merged the change at all [2].\n\nI agree that we shouldn\u0027t be ignoring this issue.  It is just a matter of someone putting up the resources to get it worked out.\n\n [1] https://review.openstack.org/#/c/164363/\n [2] https://review.openstack.org/#/c/76021/","commit_id":"bed52b0b7972f482f17bf8e4ad24ee8810c89299"},{"author":{"_account_id":4395,"name":"Aaron Rosen","email":"aaronorosen@gmail.com","username":"arosen"},"change_message_id":"167a7375731502c86fe84fb9871758fe0e2d5b7f","unresolved":false,"context_lines":[{"line_number":18,"context_line":"database."},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"This patch does 3 things:"},{"line_number":21,"context_line":"1) Treats rpc_workers\u003d0 as \u003d 1. This simplifies the code for"},{"line_number":22,"context_line":"   handling notification that forking has completed. In the"},{"line_number":23,"context_line":"   existing code, calling the notification in the Worker object\u0027s"},{"line_number":24,"context_line":"   start() method would happen twice in the case where both api"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":5,"id":"fa32b979_cd6b18b8","line":21,"updated":"2015-06-17 22:59:47.000000000","message":"I wonder if it makes sense to handle rpc_workers the same as api_workers were the default is the number of processors? (Not saying we should do anything about that in this patch set).","commit_id":"0bff05f06e10d73b60a030e9bd5d9fb46ed01bf5"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"8076aba002c67c0f6bb7e226c17149dda2d8caa2","unresolved":false,"context_lines":[{"line_number":33,"context_line":"   to returning (). Plugins that need additional processes to spawn"},{"line_number":34,"context_line":"   should just return an iterable of functions that will be spawned"},{"line_number":35,"context_line":"   in there own process."},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"Closes-Bug: #1463129"},{"line_number":38,"context_line":"Change-Id: Ib99954678c2b4f32f486b537979d446aafbea07b"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":6,"id":"fa32b979_49990378","line":36,"updated":"2015-06-19 00:33:14.000000000","message":"This is going to require a DocImpact because of the change in number of neutron processes for the new required worker.","commit_id":"ccd67d45e222491f41b295b171326519a352a678"},{"author":{"_account_id":5756,"name":"Terry Wilson","email":"twilson@redhat.com","username":"otherwiseguy"},"change_message_id":"09ba04876cb317f3dbf60e20047a820c321c2f27","unresolved":false,"context_lines":[{"line_number":33,"context_line":"   to returning (). Plugins that need additional processes to spawn"},{"line_number":34,"context_line":"   should just return an iterable of functions that will be spawned"},{"line_number":35,"context_line":"   in there own process."},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"Closes-Bug: #1463129"},{"line_number":38,"context_line":"Change-Id: Ib99954678c2b4f32f486b537979d446aafbea07b"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":6,"id":"fa32b979_ca5ac550","line":36,"in_reply_to":"fa32b979_49990378","updated":"2015-06-19 16:38:41.000000000","message":"Done","commit_id":"ccd67d45e222491f41b295b171326519a352a678"},{"author":{"_account_id":105,"name":"Kyle Mestery","email":"mestery@mestery.com","username":"mestery"},"change_message_id":"5fc556edb303d012b5fac77c57e7b0f5457c9047","unresolved":false,"context_lines":[{"line_number":31,"context_line":"   every spawned process."},{"line_number":32,"context_line":"3) Adds core/service plugin calls to get_workers() which defaults"},{"line_number":33,"context_line":"   to returning (). Plugins that need additional processes to spawn"},{"line_number":34,"context_line":"   should just return an iterable of NeutronWorkersthat will be"},{"line_number":35,"context_line":"   spawned in their own process."},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"DocImpoact"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":8,"id":"ba3cc151_776f96c5","line":34,"updated":"2015-06-30 20:05:12.000000000","message":"Super nit: space after NeutronWorkers.","commit_id":"3d5e8a6b963fcee48c116461d2cf431e365a55fa"},{"author":{"_account_id":7448,"name":"Carl Baldwin","email":"carl@ecbaldwin.net","username":"carl-baldwin"},"change_message_id":"ea7ddcb43f074a92b08ca4a3b3a886bc1627a75e","unresolved":false,"context_lines":[{"line_number":34,"context_line":"   should just return an iterable of NeutronWorkers that will be"},{"line_number":35,"context_line":"   spawned in their own process."},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"DocImpoact"},{"line_number":38,"context_line":"Closes-Bug: #1463129"},{"line_number":39,"context_line":"Change-Id: Ib99954678c2b4f32f486b537979d446aafbea07b"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":12,"id":"ba3cc151_82388fd4","line":37,"updated":"2015-07-08 17:51:44.000000000","message":"*DocImpact\n\nSeems like a small thing, but I think we should -1 for it since probably needs to be spelled right to serve its purpose.","commit_id":"48485632f887d360fd14f87c57425f2ee35c21b3"},{"author":{"_account_id":13734,"name":"Nell Jerram","email":"nell@tigera.io","username":"neiljerram"},"change_message_id":"9d491b4a7409ffc6a30c4bfd568f17910540ca96","unresolved":false,"context_lines":[{"line_number":26,"context_line":"   An earlier patch already changed the default api_workers to be"},{"line_number":27,"context_line":"   the number of processors."},{"line_number":28,"context_line":"2) Adds notification of forking via the callbacks mechanism."},{"line_number":29,"context_line":"   Plugins cans subscribe to resources.PROCESS, event.AFTER_CREATE"},{"line_number":30,"context_line":"   and do any post-fork initialization that needs to be done for"},{"line_number":31,"context_line":"   every spawned process."},{"line_number":32,"context_line":"3) Adds core/service plugin calls to get_workers() which defaults"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":14,"id":"da20952f_04a960df","line":29,"updated":"2015-08-27 16:34:26.000000000","message":"s/cans/can/","commit_id":"b228c29b00acb13405623e55b427bb8fba0d8a2c"},{"author":{"_account_id":5756,"name":"Terry Wilson","email":"twilson@redhat.com","username":"otherwiseguy"},"change_message_id":"772e5eb7137e61b5eeb2494acdaaad10fc926977","unresolved":false,"context_lines":[{"line_number":26,"context_line":"   An earlier patch already changed the default api_workers to be"},{"line_number":27,"context_line":"   the number of processors."},{"line_number":28,"context_line":"2) Adds notification of forking via the callbacks mechanism."},{"line_number":29,"context_line":"   Plugins cans subscribe to resources.PROCESS, event.AFTER_CREATE"},{"line_number":30,"context_line":"   and do any post-fork initialization that needs to be done for"},{"line_number":31,"context_line":"   every spawned process."},{"line_number":32,"context_line":"3) Adds core/service plugin calls to get_workers() which defaults"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":14,"id":"da20952f_52c4ec5d","line":29,"in_reply_to":"da20952f_04a960df","updated":"2015-08-28 14:24:44.000000000","message":"Done","commit_id":"b228c29b00acb13405623e55b427bb8fba0d8a2c"}],"neutron/callbacks/resources.py":[{"author":{"_account_id":748,"name":"Armando Migliaccio","email":"armamig@gmail.com","username":"armando-migliaccio"},"change_message_id":"ed9dd2a7450c40b8dd87591e3a7466b754f7181f","unresolved":false,"context_lines":[{"line_number":11,"context_line":"#    under the License."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"PORT \u003d \u0027port\u0027"},{"line_number":14,"context_line":"PROCESS \u003d \u0027process\u0027"},{"line_number":15,"context_line":"ROUTER \u003d \u0027router\u0027"},{"line_number":16,"context_line":"ROUTER_GATEWAY \u003d \u0027router_gateway\u0027"},{"line_number":17,"context_line":"ROUTER_INTERFACE \u003d \u0027router_interface\u0027"}],"source_content_type":"text/x-python","patch_set":13,"id":"da20952f_9908bb2a","line":14,"updated":"2015-08-26 15:44:05.000000000","message":"after [1] you no longer need these.\n\n[1] https://review.openstack.org/#/c/211798/","commit_id":"77796d464f231e0aa6de6aac0db8fb2c4e4fb7bf"},{"author":{"_account_id":748,"name":"Armando Migliaccio","email":"armamig@gmail.com","username":"armando-migliaccio"},"change_message_id":"15dc3242fe6bf97e5860852822c94561aef07111","unresolved":false,"context_lines":[{"line_number":12,"context_line":""},{"line_number":13,"context_line":"# String literals representing core resources."},{"line_number":14,"context_line":"PORT \u003d \u0027port\u0027"},{"line_number":15,"context_line":"PROCESS \u003d \u0027process\u0027"},{"line_number":16,"context_line":"ROUTER \u003d \u0027router\u0027"},{"line_number":17,"context_line":"ROUTER_GATEWAY \u003d \u0027router_gateway\u0027"},{"line_number":18,"context_line":"ROUTER_INTERFACE \u003d \u0027router_interface\u0027"}],"source_content_type":"text/x-python","patch_set":14,"id":"da20952f_434bc587","line":15,"updated":"2015-08-27 19:47:20.000000000","message":"PROCESS is not really a *core* resource, not sure this is the best place to capture this string literal.","commit_id":"b228c29b00acb13405623e55b427bb8fba0d8a2c"},{"author":{"_account_id":5756,"name":"Terry Wilson","email":"twilson@redhat.com","username":"otherwiseguy"},"change_message_id":"772e5eb7137e61b5eeb2494acdaaad10fc926977","unresolved":false,"context_lines":[{"line_number":12,"context_line":""},{"line_number":13,"context_line":"# String literals representing core resources."},{"line_number":14,"context_line":"PORT \u003d \u0027port\u0027"},{"line_number":15,"context_line":"PROCESS \u003d \u0027process\u0027"},{"line_number":16,"context_line":"ROUTER \u003d \u0027router\u0027"},{"line_number":17,"context_line":"ROUTER_GATEWAY \u003d \u0027router_gateway\u0027"},{"line_number":18,"context_line":"ROUTER_INTERFACE \u003d \u0027router_interface\u0027"}],"source_content_type":"text/x-python","patch_set":14,"id":"da20952f_b28228ff","line":15,"in_reply_to":"da20952f_3e802846","updated":"2015-08-28 14:24:44.000000000","message":"Since this spans multiple modules and subscriptions are done from plugins/mech drivers it seems like making this a core resource makes since.","commit_id":"b228c29b00acb13405623e55b427bb8fba0d8a2c"},{"author":{"_account_id":748,"name":"Armando Migliaccio","email":"armamig@gmail.com","username":"armando-migliaccio"},"change_message_id":"f829317e62e47928ffcb172fa8a62d41a79c57cb","unresolved":false,"context_lines":[{"line_number":12,"context_line":""},{"line_number":13,"context_line":"# String literals representing core resources."},{"line_number":14,"context_line":"PORT \u003d \u0027port\u0027"},{"line_number":15,"context_line":"PROCESS \u003d \u0027process\u0027"},{"line_number":16,"context_line":"ROUTER \u003d \u0027router\u0027"},{"line_number":17,"context_line":"ROUTER_GATEWAY \u003d \u0027router_gateway\u0027"},{"line_number":18,"context_line":"ROUTER_INTERFACE \u003d \u0027router_interface\u0027"}],"source_content_type":"text/x-python","patch_set":14,"id":"da20952f_3e802846","line":15,"in_reply_to":"da20952f_434bc587","updated":"2015-08-27 19:51:26.000000000","message":"umm...I am having second thoughts......\n\n/me ponders...","commit_id":"b228c29b00acb13405623e55b427bb8fba0d8a2c"}],"neutron/manager.py":[{"author":{"_account_id":748,"name":"Armando Migliaccio","email":"armamig@gmail.com","username":"armando-migliaccio"},"change_message_id":"b67f1836087642b5e461b32b4372bd46ad6311d5","unresolved":false,"context_lines":[{"line_number":247,"context_line":"        return dict((x, weakref.proxy(y))"},{"line_number":248,"context_line":"                    for x, y in six.iteritems(service_plugins))"},{"line_number":249,"context_line":""},{"line_number":250,"context_line":"    @classmethod"},{"line_number":251,"context_line":"    def get_unique_service_plugins(cls):"},{"line_number":252,"context_line":"        service_plugins \u003d cls.get_instance().service_plugins"},{"line_number":253,"context_line":"        return tuple(weakref.proxy(x) for x in set(service_plugins.values()))"}],"source_content_type":"text/x-python","patch_set":16,"id":"da20952f_770763ca","line":250,"updated":"2015-08-28 23:29:02.000000000","message":"silly question: but why this a classmethod at all?","commit_id":"696fc68515ce55c01de3d0de24c89115e018e7bb"},{"author":{"_account_id":5756,"name":"Terry Wilson","email":"twilson@redhat.com","username":"otherwiseguy"},"change_message_id":"5bd03c560b0c1b98ec9c8e9e6498c0e7d9ee6489","unresolved":false,"context_lines":[{"line_number":247,"context_line":"        return dict((x, weakref.proxy(y))"},{"line_number":248,"context_line":"                    for x, y in six.iteritems(service_plugins))"},{"line_number":249,"context_line":""},{"line_number":250,"context_line":"    @classmethod"},{"line_number":251,"context_line":"    def get_unique_service_plugins(cls):"},{"line_number":252,"context_line":"        service_plugins \u003d cls.get_instance().service_plugins"},{"line_number":253,"context_line":"        return tuple(weakref.proxy(x) for x in set(service_plugins.values()))"}],"source_content_type":"text/x-python","patch_set":16,"id":"da20952f_d0187dd5","line":250,"in_reply_to":"da20952f_770763ca","updated":"2015-08-31 15:34:46.000000000","message":"The method doesn\u0027t use any instance-specific data and theoretically someone could subclass NeutronManager (omg, why?) and this would ensure that the right get_instance call was made?","commit_id":"696fc68515ce55c01de3d0de24c89115e018e7bb"}],"neutron/neutron_plugin_base_v2.py":[{"author":{"_account_id":7448,"name":"Carl Baldwin","email":"carl@ecbaldwin.net","username":"carl-baldwin"},"change_message_id":"2c989a852fca4b53b173f42e7b0cbb7bab5bfd77","unresolved":false,"context_lines":[{"line_number":391,"context_line":"                NeutronPluginBaseV2.start_rpc_listeners)"},{"line_number":392,"context_line":""},{"line_number":393,"context_line":"    def get_processes(self):"},{"line_number":394,"context_line":"        \"\"\"Returns a list of functions to run as a seperate process\"\"\""},{"line_number":395,"context_line":"        return ()"}],"source_content_type":"text/x-python","patch_set":2,"id":"fa32b979_ee7dfa1c","line":394,"updated":"2015-06-16 19:41:16.000000000","message":"nit:  Not a list, but that\u0027s probably okay.","commit_id":"bed52b0b7972f482f17bf8e4ad24ee8810c89299"},{"author":{"_account_id":5756,"name":"Terry Wilson","email":"twilson@redhat.com","username":"otherwiseguy"},"change_message_id":"d50fa113f348f63f8c06b6ee231834904da9108a","unresolved":false,"context_lines":[{"line_number":391,"context_line":"                NeutronPluginBaseV2.start_rpc_listeners)"},{"line_number":392,"context_line":""},{"line_number":393,"context_line":"    def get_processes(self):"},{"line_number":394,"context_line":"        \"\"\"Returns a list of functions to run as a seperate process\"\"\""},{"line_number":395,"context_line":"        return ()"}],"source_content_type":"text/x-python","patch_set":2,"id":"fa32b979_f02153b5","line":394,"in_reply_to":"fa32b979_ee7dfa1c","updated":"2015-06-16 20:37:05.000000000","message":"Yeah, I should reword it to \u0027iterable\u0027 or \u0027collection\u0027.","commit_id":"bed52b0b7972f482f17bf8e4ad24ee8810c89299"},{"author":{"_account_id":261,"name":"Salvatore Orlando","email":"salv.orlando@gmail.com","username":"salvatore-orlando"},"change_message_id":"5d4fb6840f0deb1def01cc2b0fff31759ba6745a","unresolved":false,"context_lines":[{"line_number":391,"context_line":"                NeutronPluginBaseV2.start_rpc_listeners)"},{"line_number":392,"context_line":""},{"line_number":393,"context_line":"    def get_processes(self):"},{"line_number":394,"context_line":"        \"\"\"Returns a collection of functions to run as seperate processes\"\"\""},{"line_number":395,"context_line":"        return ()"}],"source_content_type":"text/x-python","patch_set":6,"id":"fa32b979_737dbfb0","line":394,"updated":"2015-06-19 13:48:22.000000000","message":"nit... typo: separate","commit_id":"ccd67d45e222491f41b295b171326519a352a678"},{"author":{"_account_id":5756,"name":"Terry Wilson","email":"twilson@redhat.com","username":"otherwiseguy"},"change_message_id":"09ba04876cb317f3dbf60e20047a820c321c2f27","unresolved":false,"context_lines":[{"line_number":391,"context_line":"                NeutronPluginBaseV2.start_rpc_listeners)"},{"line_number":392,"context_line":""},{"line_number":393,"context_line":"    def get_processes(self):"},{"line_number":394,"context_line":"        \"\"\"Returns a collection of functions to run as seperate processes\"\"\""},{"line_number":395,"context_line":"        return ()"}],"source_content_type":"text/x-python","patch_set":6,"id":"fa32b979_25fe0206","line":394,"in_reply_to":"fa32b979_737dbfb0","updated":"2015-06-19 16:38:41.000000000","message":"Done","commit_id":"ccd67d45e222491f41b295b171326519a352a678"},{"author":{"_account_id":9970,"name":"John Kasperski","email":"jckasper@linux.vnet.ibm.com","username":"jckasper"},"change_message_id":"544bf65721832c4df30f5753fd1d8fbab6d97723","unresolved":false,"context_lines":[{"line_number":390,"context_line":"        return (self.__class__.start_rpc_listeners !\u003d"},{"line_number":391,"context_line":"                NeutronPluginBaseV2.start_rpc_listeners)"},{"line_number":392,"context_line":""},{"line_number":393,"context_line":"    def get_workers(self):"},{"line_number":394,"context_line":"        \"\"\"Returns a collection of NeutronWorkers\"\"\""},{"line_number":395,"context_line":"        return ()"}],"source_content_type":"text/x-python","patch_set":11,"id":"ba3cc151_a0f836c4","line":393,"updated":"2015-07-01 22:22:46.000000000","message":"Should this be declared as abstractmethod instead?   Additional comment (similar to other routines in this module) describing purpose of this method ?","commit_id":"bdfa9c6854e6b6f8a725a7ca66f39759fd299e9a"},{"author":{"_account_id":5756,"name":"Terry Wilson","email":"twilson@redhat.com","username":"otherwiseguy"},"change_message_id":"b566fb206e6a208e3eb931c461c20c92c91d3937","unresolved":false,"context_lines":[{"line_number":390,"context_line":"        return (self.__class__.start_rpc_listeners !\u003d"},{"line_number":391,"context_line":"                NeutronPluginBaseV2.start_rpc_listeners)"},{"line_number":392,"context_line":""},{"line_number":393,"context_line":"    def get_workers(self):"},{"line_number":394,"context_line":"        \"\"\"Returns a collection of NeutronWorkers\"\"\""},{"line_number":395,"context_line":"        return ()"}],"source_content_type":"text/x-python","patch_set":11,"id":"ba3cc151_8e08a7db","line":393,"in_reply_to":"ba3cc151_a0f836c4","updated":"2015-07-02 19:28:46.000000000","message":"No. We don\u0027t want to force everyone to override it because it is not always necessary and we are providing a default here with returning ().","commit_id":"bdfa9c6854e6b6f8a725a7ca66f39759fd299e9a"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"e85c879537966ddb4210b66e157e85a1c00cc93d","unresolved":false,"context_lines":[{"line_number":392,"context_line":""},{"line_number":393,"context_line":"    def get_workers(self):"},{"line_number":394,"context_line":"        \"\"\"Returns a collection of NeutronWorkers\"\"\""},{"line_number":395,"context_line":"        return ()"}],"source_content_type":"text/x-python","patch_set":14,"id":"da20952f_5e7abcf2","line":395,"updated":"2015-08-27 20:14:16.000000000","message":"is this an insult towards Neutron implying that nobody is working? ;)\n\n\nMore seriously, can be just a bit more specific here? (e.g. \"returns a collection of instances that should be subclasses of the NeutronWorker class defined in neutron.worker\".)","commit_id":"b228c29b00acb13405623e55b427bb8fba0d8a2c"},{"author":{"_account_id":5756,"name":"Terry Wilson","email":"twilson@redhat.com","username":"otherwiseguy"},"change_message_id":"772e5eb7137e61b5eeb2494acdaaad10fc926977","unresolved":false,"context_lines":[{"line_number":392,"context_line":""},{"line_number":393,"context_line":"    def get_workers(self):"},{"line_number":394,"context_line":"        \"\"\"Returns a collection of NeutronWorkers\"\"\""},{"line_number":395,"context_line":"        return ()"}],"source_content_type":"text/x-python","patch_set":14,"id":"da20952f_b29f8802","line":395,"in_reply_to":"da20952f_5e7abcf2","updated":"2015-08-28 14:24:44.000000000","message":"Done","commit_id":"b228c29b00acb13405623e55b427bb8fba0d8a2c"}],"neutron/plugins/ml2/managers.py":[{"author":{"_account_id":7448,"name":"Carl Baldwin","email":"carl@ecbaldwin.net","username":"carl-baldwin"},"change_message_id":"2c989a852fca4b53b173f42e7b0cbb7bab5bfd77","unresolved":false,"context_lines":[{"line_number":719,"context_line":"        for driver in self.ordered_mech_drivers:"},{"line_number":720,"context_line":"            for proc in getattr(driver.obj, \u0027get_processes\u0027, tuple)():"},{"line_number":721,"context_line":"                procs.append(proc)"},{"line_number":722,"context_line":"        return procs"},{"line_number":723,"context_line":""},{"line_number":724,"context_line":""},{"line_number":725,"context_line":"class ExtensionManager(stevedore.named.NamedExtensionManager):"}],"source_content_type":"text/x-python","patch_set":2,"id":"fa32b979_6e056a78","line":722,"updated":"2015-06-16 19:41:16.000000000","message":"nit:  To get really pedant, you could convert to a tuple to match the type in the base class.\n\n  return tuple(procs)","commit_id":"bed52b0b7972f482f17bf8e4ad24ee8810c89299"},{"author":{"_account_id":5756,"name":"Terry Wilson","email":"twilson@redhat.com","username":"otherwiseguy"},"change_message_id":"d50fa113f348f63f8c06b6ee231834904da9108a","unresolved":false,"context_lines":[{"line_number":719,"context_line":"        for driver in self.ordered_mech_drivers:"},{"line_number":720,"context_line":"            for proc in getattr(driver.obj, \u0027get_processes\u0027, tuple)():"},{"line_number":721,"context_line":"                procs.append(proc)"},{"line_number":722,"context_line":"        return procs"},{"line_number":723,"context_line":""},{"line_number":724,"context_line":""},{"line_number":725,"context_line":"class ExtensionManager(stevedore.named.NamedExtensionManager):"}],"source_content_type":"text/x-python","patch_set":2,"id":"fa32b979_d078cfc6","line":722,"in_reply_to":"fa32b979_6e056a78","updated":"2015-06-16 20:37:05.000000000","message":"The only really important thing is that it is iterable. I\u0027m not a huge fan of duck-typing, but if I\u0027m writing Python code I\u0027ll happily use it instead of doing a type conversion with O(n) (even if mostly n\u003d\u003d1). :)","commit_id":"bed52b0b7972f482f17bf8e4ad24ee8810c89299"},{"author":{"_account_id":7448,"name":"Carl Baldwin","email":"carl@ecbaldwin.net","username":"carl-baldwin"},"change_message_id":"170e84ee04c12771e2d812094da4024c894682d6","unresolved":false,"context_lines":[{"line_number":719,"context_line":"        for driver in self.ordered_mech_drivers:"},{"line_number":720,"context_line":"            for proc in getattr(driver.obj, \u0027get_processes\u0027, tuple)():"},{"line_number":721,"context_line":"                procs.append(proc)"},{"line_number":722,"context_line":"        return procs"},{"line_number":723,"context_line":""},{"line_number":724,"context_line":""},{"line_number":725,"context_line":"class ExtensionManager(stevedore.named.NamedExtensionManager):"}],"source_content_type":"text/x-python","patch_set":2,"id":"fa32b979_3c01a705","line":722,"in_reply_to":"fa32b979_d078cfc6","updated":"2015-06-17 18:43:15.000000000","message":"You do realize that N is the number of external processes that will be spawned, right?  If you try scaling that to a number that makes this O(N) matter in the slightest bit, you\u0027ve got bigger problems on your hands.  Besides, the complexity of this method is already O(N) so you\u0027re just talking about a constant factor.  Can we agree that performance is not a factor here and we shouldn\u0027t waste time discussing it in this context?\n\nI was thinking more about the general practice of returning a mutable list over returning an immutable tuple.  Also, being consistent.  It is a nit and I never require action on my nits.","commit_id":"bed52b0b7972f482f17bf8e4ad24ee8810c89299"},{"author":{"_account_id":7448,"name":"Carl Baldwin","email":"carl@ecbaldwin.net","username":"carl-baldwin"},"change_message_id":"ea7ddcb43f074a92b08ca4a3b3a886bc1627a75e","unresolved":false,"context_lines":[{"line_number":718,"context_line":"        workers \u003d []"},{"line_number":719,"context_line":"        for driver in self.ordered_mech_drivers:"},{"line_number":720,"context_line":"            for worker in getattr(driver.obj, \u0027get_workers\u0027, tuple)():"},{"line_number":721,"context_line":"                workers.append(worker)"},{"line_number":722,"context_line":"        return workers"},{"line_number":723,"context_line":""},{"line_number":724,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"ba3cc151_a2227352","line":721,"updated":"2015-07-08 17:51:44.000000000","message":"nit:  I think this works:\n\n  workers +\u003d getattr(driver.obj, \u0027get_workers\u0027, tuple)()","commit_id":"48485632f887d360fd14f87c57425f2ee35c21b3"},{"author":{"_account_id":748,"name":"Armando Migliaccio","email":"armamig@gmail.com","username":"armando-migliaccio"},"change_message_id":"b67f1836087642b5e461b32b4372bd46ad6311d5","unresolved":false,"context_lines":[{"line_number":752,"context_line":"    def get_workers(self):"},{"line_number":753,"context_line":"        workers \u003d []"},{"line_number":754,"context_line":"        for driver in self.ordered_mech_drivers:"},{"line_number":755,"context_line":"            for worker in getattr(driver.obj, \u0027get_workers\u0027, tuple)():"},{"line_number":756,"context_line":"                workers.append(worker)"},{"line_number":757,"context_line":"        return workers"},{"line_number":758,"context_line":""}],"source_content_type":"text/x-python","patch_set":16,"id":"da20952f_57e01ffa","line":755,"updated":"2015-08-28 23:29:02.000000000","message":"drivers are not plugins...why are we introspecting this way? Should we not extend the mech driver API?","commit_id":"696fc68515ce55c01de3d0de24c89115e018e7bb"},{"author":{"_account_id":5756,"name":"Terry Wilson","email":"twilson@redhat.com","username":"otherwiseguy"},"change_message_id":"5bd03c560b0c1b98ec9c8e9e6498c0e7d9ee6489","unresolved":false,"context_lines":[{"line_number":752,"context_line":"    def get_workers(self):"},{"line_number":753,"context_line":"        workers \u003d []"},{"line_number":754,"context_line":"        for driver in self.ordered_mech_drivers:"},{"line_number":755,"context_line":"            for worker in getattr(driver.obj, \u0027get_workers\u0027, tuple)():"},{"line_number":756,"context_line":"                workers.append(worker)"},{"line_number":757,"context_line":"        return workers"},{"line_number":758,"context_line":""}],"source_content_type":"text/x-python","patch_set":16,"id":"da20952f_d33de78f","line":755,"in_reply_to":"da20952f_57e01ffa","updated":"2015-08-31 15:34:46.000000000","message":"Drivers aren\u0027t plugins, but mech drivers are what would need to provide workers, and multiple mech drivers could be loaded so essentially each one needs to be able to return workers.\n\nI\u0027ll go ahead and add get_workers to the mech driver class with a default return value of (). Not sure why I didn\u0027t do that before. :)","commit_id":"696fc68515ce55c01de3d0de24c89115e018e7bb"},{"author":{"_account_id":748,"name":"Armando Migliaccio","email":"armamig@gmail.com","username":"armando-migliaccio"},"change_message_id":"6c74971070c8cc278acc54fe024c3f8bd57c4b2c","unresolved":false,"context_lines":[{"line_number":752,"context_line":"    def get_workers(self):"},{"line_number":753,"context_line":"        workers \u003d []"},{"line_number":754,"context_line":"        for driver in self.ordered_mech_drivers:"},{"line_number":755,"context_line":"            workers +\u003d driver.obj.get_workers()"},{"line_number":756,"context_line":"        return workers"},{"line_number":757,"context_line":""},{"line_number":758,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"da20952f_c252ea34","line":755,"updated":"2015-08-31 17:52:04.000000000","message":"Do you expect workers to change throughout the lifetime of the driver? If not perhaps this could be done upfront rather than building the list every time; anyhoo it\u0027s a nit at this point.","commit_id":"a1c494700eb0d8150b4b76099cc7b7b7c3c0294e"}],"neutron/server/__init__.py":[{"author":{"_account_id":261,"name":"Salvatore Orlando","email":"salv.orlando@gmail.com","username":"salvatore-orlando"},"change_message_id":"5d4fb6840f0deb1def01cc2b0fff31759ba6745a","unresolved":false,"context_lines":[{"line_number":56,"context_line":"            rpc_thread.link(lambda gt: api_thread.kill())"},{"line_number":57,"context_line":"            api_thread.link(lambda gt: rpc_thread.kill())"},{"line_number":58,"context_line":""},{"line_number":59,"context_line":"        service.run_plugin_processes()"},{"line_number":60,"context_line":"        pool.waitall()"},{"line_number":61,"context_line":"    except KeyboardInterrupt:"},{"line_number":62,"context_line":"        pass"}],"source_content_type":"text/x-python","patch_set":6,"id":"fa32b979_6e3074e9","line":59,"updated":"2015-06-19 13:48:22.000000000","message":"is this after the fork? (from what I recall, it should)","commit_id":"ccd67d45e222491f41b295b171326519a352a678"},{"author":{"_account_id":5756,"name":"Terry Wilson","email":"twilson@redhat.com","username":"otherwiseguy"},"change_message_id":"09ba04876cb317f3dbf60e20047a820c321c2f27","unresolved":false,"context_lines":[{"line_number":56,"context_line":"            rpc_thread.link(lambda gt: api_thread.kill())"},{"line_number":57,"context_line":"            api_thread.link(lambda gt: rpc_thread.kill())"},{"line_number":58,"context_line":""},{"line_number":59,"context_line":"        service.run_plugin_processes()"},{"line_number":60,"context_line":"        pool.waitall()"},{"line_number":61,"context_line":"    except KeyboardInterrupt:"},{"line_number":62,"context_line":"        pass"}],"source_content_type":"text/x-python","patch_set":6,"id":"fa32b979_e59d7a0b","line":59,"in_reply_to":"fa32b979_6e3074e9","updated":"2015-06-19 16:38:41.000000000","message":"This is still happening in the parent process in concert with the other api/rpc worker forking. But there won\u0027t be any workers actually running in the parent process. ProcessLauncher will handle all of the forking stuff, and if the plugin needs to do certain things after forking, it needs to subscribe to the PROCESS AFTER_CREATE event and do those things there.\n\nRight now:\n\nmech_driver.initialize(): happens in parent process before *any* forking...but just because get_plugin() happens to be called somewhere before any forking happens. I\u0027d much rather *eventually* come up with something that was less chaotic, but that is going to take a lot more time and thought.\n\nPROCESS.AFTER_CREATE: Most like the subscription will happen in the plugin intialize(), forking copies it, and after fork() is called, the Worker.start() method is called which will do the notification and the callback will be called and post-fork initialization that you want done for *every* process is done.\n\nget_processes(): List of functions that ProcessLauncher just launches as processes. fork() is called on each of these from the parent process, so the parent is copied on the fork and PluginWorker.start() is called, which again will emit the notification and run the callback.\n\nBUT, it is also possible to define a function completely outside of the plugin class/mech driver and do whatever initialization one wants and not rely on what happens to be copied over in the fork.\n\nIt may also be a good idea to pass in to the callback what kind of service is being started, just to make it easy to make PluginWorkers to have very different post-fork initializations, etc.","commit_id":"ccd67d45e222491f41b295b171326519a352a678"},{"author":{"_account_id":9970,"name":"John Kasperski","email":"jckasper@linux.vnet.ibm.com","username":"jckasper"},"change_message_id":"544bf65721832c4df30f5753fd1d8fbab6d97723","unresolved":false,"context_lines":[{"line_number":52,"context_line":"        else:"},{"line_number":53,"context_line":"            rpc_thread \u003d pool.spawn(neutron_rpc.wait)"},{"line_number":54,"context_line":""},{"line_number":55,"context_line":"            # api and rpc should die together.  When one dies, kill the other."},{"line_number":56,"context_line":"            rpc_thread.link(lambda gt: api_thread.kill())"},{"line_number":57,"context_line":"            api_thread.link(lambda gt: rpc_thread.kill())"},{"line_number":58,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"ba3cc151_00bc82da","side":"PARENT","line":55,"updated":"2015-07-01 22:22:46.000000000","message":"why was comment removed.  seems like it still applies","commit_id":"c0edc6d21d04cbffba4461c5ec950b1743204b84"},{"author":{"_account_id":5756,"name":"Terry Wilson","email":"twilson@redhat.com","username":"otherwiseguy"},"change_message_id":"b566fb206e6a208e3eb931c461c20c92c91d3937","unresolved":false,"context_lines":[{"line_number":52,"context_line":"        else:"},{"line_number":53,"context_line":"            rpc_thread \u003d pool.spawn(neutron_rpc.wait)"},{"line_number":54,"context_line":""},{"line_number":55,"context_line":"            # api and rpc should die together.  When one dies, kill the other."},{"line_number":56,"context_line":"            rpc_thread.link(lambda gt: api_thread.kill())"},{"line_number":57,"context_line":"            api_thread.link(lambda gt: rpc_thread.kill())"},{"line_number":58,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"ba3cc151_4edcdf45","side":"PARENT","line":55,"in_reply_to":"ba3cc151_00bc82da","updated":"2015-07-02 19:28:46.000000000","message":"Oops, meant to move it down. Must have dd\u0027d without p-ing. :p\n\nDone","commit_id":"c0edc6d21d04cbffba4461c5ec950b1743204b84"}],"neutron/service.py":[{"author":{"_account_id":4395,"name":"Aaron Rosen","email":"aaronorosen@gmail.com","username":"arosen"},"change_message_id":"167a7375731502c86fe84fb9871758fe0e2d5b7f","unresolved":false,"context_lines":[{"line_number":179,"context_line":"        rpc \u003d RpcWorker(plugin)"},{"line_number":180,"context_line":""},{"line_number":181,"context_line":"        if cfg.CONF.rpc_workers \u003c 1:"},{"line_number":182,"context_line":"            cfg.CONF.set_override(\u0027rpc_workers\u0027, 1)"},{"line_number":183,"context_line":"        # dispose the whole pool before os.fork, otherwise there will"},{"line_number":184,"context_line":"        # be shared DB connections in child processes which may cause"},{"line_number":185,"context_line":"        # DB errors."}],"source_content_type":"text/x-python","patch_set":5,"id":"fa32b979_2da2c4fd","line":182,"updated":"2015-06-17 22:59:47.000000000","message":"If you\u0027re doing this here I don\u0027t think you really need to change the default to 1 right? \n\nWe should also update this to 1 if so: \nhttps://github.com/openstack/neutron/blob/master/etc/neutron.conf#L302","commit_id":"0bff05f06e10d73b60a030e9bd5d9fb46ed01bf5"},{"author":{"_account_id":5756,"name":"Terry Wilson","email":"twilson@redhat.com","username":"otherwiseguy"},"change_message_id":"851c001c8fea800bea3275d6a64028b8d5a1076d","unresolved":false,"context_lines":[{"line_number":179,"context_line":"        rpc \u003d RpcWorker(plugin)"},{"line_number":180,"context_line":""},{"line_number":181,"context_line":"        if cfg.CONF.rpc_workers \u003c 1:"},{"line_number":182,"context_line":"            cfg.CONF.set_override(\u0027rpc_workers\u0027, 1)"},{"line_number":183,"context_line":"        # dispose the whole pool before os.fork, otherwise there will"},{"line_number":184,"context_line":"        # be shared DB connections in child processes which may cause"},{"line_number":185,"context_line":"        # DB errors."}],"source_content_type":"text/x-python","patch_set":5,"id":"fa32b979_edd37cd3","line":182,"in_reply_to":"fa32b979_2da2c4fd","updated":"2015-06-18 00:39:20.000000000","message":"Well, someone could still have:\n\nrpc_workers \u003d 0\n\nactually in the config as opposed to nothing. Yeah, definitely need to update the config file.","commit_id":"0bff05f06e10d73b60a030e9bd5d9fb46ed01bf5"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"e85c879537966ddb4210b66e157e85a1c00cc93d","unresolved":false,"context_lines":[{"line_number":112,"context_line":"def start_plugin_workers():"},{"line_number":113,"context_line":"    launchers \u003d []"},{"line_number":114,"context_line":"    # NOTE(twilson) get_service_plugins also returns the core plugin"},{"line_number":115,"context_line":"    for plugin in manager.NeutronManager.get_service_plugins().values():"},{"line_number":116,"context_line":"        # TODO(twilson) Instead of defaulting here, come up with a good way to"},{"line_number":117,"context_line":"        # share a common get_workers default between NeutronPluginBaseV2 and"},{"line_number":118,"context_line":"        # ServicePluginBase"}],"source_content_type":"text/x-python","patch_set":14,"id":"da20952f_592736b6","line":115,"updated":"2015-08-27 20:14:16.000000000","message":"You will need to dedup this list. In a monolithic plugin that implements several services, it will show up here multiple times.[1] I doubt we want to launch the workers multiple times.\n\n1. https://github.com/openstack/neutron/blob/9ed4be7559b1b611b35b505a786c3511dccac58f/neutron/manager.py#L156-L167","commit_id":"b228c29b00acb13405623e55b427bb8fba0d8a2c"},{"author":{"_account_id":5756,"name":"Terry Wilson","email":"twilson@redhat.com","username":"otherwiseguy"},"change_message_id":"772e5eb7137e61b5eeb2494acdaaad10fc926977","unresolved":false,"context_lines":[{"line_number":112,"context_line":"def start_plugin_workers():"},{"line_number":113,"context_line":"    launchers \u003d []"},{"line_number":114,"context_line":"    # NOTE(twilson) get_service_plugins also returns the core plugin"},{"line_number":115,"context_line":"    for plugin in manager.NeutronManager.get_service_plugins().values():"},{"line_number":116,"context_line":"        # TODO(twilson) Instead of defaulting here, come up with a good way to"},{"line_number":117,"context_line":"        # share a common get_workers default between NeutronPluginBaseV2 and"},{"line_number":118,"context_line":"        # ServicePluginBase"}],"source_content_type":"text/x-python","patch_set":14,"id":"da20952f_f8ff1fff","line":115,"in_reply_to":"da20952f_592736b6","updated":"2015-08-28 14:24:44.000000000","message":"Nice catch. Done.","commit_id":"b228c29b00acb13405623e55b427bb8fba0d8a2c"},{"author":{"_account_id":5756,"name":"Terry Wilson","email":"twilson@redhat.com","username":"otherwiseguy"},"change_message_id":"772e5eb7137e61b5eeb2494acdaaad10fc926977","unresolved":false,"context_lines":[{"line_number":165,"context_line":"def serve_rpc():"},{"line_number":166,"context_line":"    plugin \u003d manager.NeutronManager.get_plugin()"},{"line_number":167,"context_line":""},{"line_number":168,"context_line":"    if cfg.CONF.rpc_workers \u003c 1:"},{"line_number":169,"context_line":"        cfg.CONF.set_override(\u0027rpc_workers\u0027, 1)"},{"line_number":170,"context_line":""},{"line_number":171,"context_line":"    # If 0 \u003c rpc_workers then start_rpc_listeners would be called in a"}],"source_content_type":"text/x-python","patch_set":14,"id":"da20952f_98e38305","line":168,"updated":"2015-08-28 14:24:44.000000000","message":"It should be noted that this being here before the rpc_workers_supported() check below means that plugins *must* define start_rpc_listeners(). This may be desirable in that \"there\u0027s one way to do it\" kind of way. But it deserves to be stared at.","commit_id":"b228c29b00acb13405623e55b427bb8fba0d8a2c"},{"author":{"_account_id":748,"name":"Armando Migliaccio","email":"armamig@gmail.com","username":"armando-migliaccio"},"change_message_id":"b67f1836087642b5e461b32b4372bd46ad6311d5","unresolved":false,"context_lines":[{"line_number":116,"context_line":"        # TODO(twilson) Instead of defaulting here, come up with a good way to"},{"line_number":117,"context_line":"        # share a common get_workers default between NeutronPluginBaseV2 and"},{"line_number":118,"context_line":"        # ServicePluginBase"},{"line_number":119,"context_line":"        for plugin_worker in getattr(plugin, \u0027get_workers\u0027, tuple)():"},{"line_number":120,"context_line":"            launcher \u003d common_service.ProcessLauncher(cfg.CONF)"},{"line_number":121,"context_line":"            launcher.launch_service(plugin_worker)"},{"line_number":122,"context_line":"            launchers.append(launcher)"}],"source_content_type":"text/x-python","patch_set":16,"id":"da20952f_d7442fb8","line":119,"updated":"2015-08-28 23:29:02.000000000","message":"can\u0027t we add this method to ServicePluginBase too?","commit_id":"696fc68515ce55c01de3d0de24c89115e018e7bb"},{"author":{"_account_id":5756,"name":"Terry Wilson","email":"twilson@redhat.com","username":"otherwiseguy"},"change_message_id":"5bd03c560b0c1b98ec9c8e9e6498c0e7d9ee6489","unresolved":false,"context_lines":[{"line_number":116,"context_line":"        # TODO(twilson) Instead of defaulting here, come up with a good way to"},{"line_number":117,"context_line":"        # share a common get_workers default between NeutronPluginBaseV2 and"},{"line_number":118,"context_line":"        # ServicePluginBase"},{"line_number":119,"context_line":"        for plugin_worker in getattr(plugin, \u0027get_workers\u0027, tuple)():"},{"line_number":120,"context_line":"            launcher \u003d common_service.ProcessLauncher(cfg.CONF)"},{"line_number":121,"context_line":"            launcher.launch_service(plugin_worker)"},{"line_number":122,"context_line":"            launchers.append(launcher)"}],"source_content_type":"text/x-python","patch_set":16,"id":"da20952f_93b68ff7","line":119,"in_reply_to":"da20952f_d7442fb8","updated":"2015-08-31 15:34:46.000000000","message":"I already did. The problem is that there are services out there that don\u0027t actually inherit from ServicePluginBase. So I added this getattr defaulting here just to avoid breaking those services.","commit_id":"696fc68515ce55c01de3d0de24c89115e018e7bb"},{"author":{"_account_id":7715,"name":"Hirofumi Ichihara","email":"ichihara.hirofumi@gmail.com","username":"Hirofumi-Ichihara"},"change_message_id":"46350fb680e339e9e5e9a7f856bc6976d83f7782","unresolved":false,"context_lines":[{"line_number":42,"context_line":"               help\u003d_(\u0027Seconds between running periodic tasks\u0027)),"},{"line_number":43,"context_line":"    cfg.IntOpt(\u0027api_workers\u0027,"},{"line_number":44,"context_line":"               help\u003d_(\u0027Number of separate API worker processes for service. \u0027"},{"line_number":45,"context_line":"                      \u0027If not specified, the default is equal to the number \u0027"},{"line_number":46,"context_line":"                      \u0027of CPUs available for best performance.\u0027)),"},{"line_number":47,"context_line":"    cfg.IntOpt(\u0027rpc_workers\u0027,"},{"line_number":48,"context_line":"               default\u003d1,"}],"source_content_type":"text/x-python","patch_set":17,"id":"da20952f_670bdad6","line":45,"updated":"2015-09-01 03:53:04.000000000","message":"nit: If not specified or \u003c 1,","commit_id":"a1c494700eb0d8150b4b76099cc7b7b7c3c0294e"}],"neutron/services/service_base.py":[{"author":{"_account_id":4395,"name":"Aaron Rosen","email":"aaronorosen@gmail.com","username":"arosen"},"change_message_id":"167a7375731502c86fe84fb9871758fe0e2d5b7f","unresolved":false,"context_lines":[{"line_number":41,"context_line":"        \"\"\""},{"line_number":42,"context_line":"        pass"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"    @abc.abstractmethod"},{"line_number":45,"context_line":"    def get_plugin_name(self):"},{"line_number":46,"context_line":"        \"\"\"Return a symbolic name for the plugin."},{"line_number":47,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"fa32b979_ad4a5424","side":"PARENT","line":44,"updated":"2015-06-17 22:59:47.000000000","message":"ditto","commit_id":"3b27f83964d44241dd03d680f79e14e7459db4da"},{"author":{"_account_id":4395,"name":"Aaron Rosen","email":"aaronorosen@gmail.com","username":"arosen"},"change_message_id":"167a7375731502c86fe84fb9871758fe0e2d5b7f","unresolved":false,"context_lines":[{"line_number":47,"context_line":"        Each service plugin should have a symbolic name. This name"},{"line_number":48,"context_line":"        will be used, for instance, by service definitions in service types"},{"line_number":49,"context_line":"        \"\"\""},{"line_number":50,"context_line":"        return None"},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"    @abc.abstractmethod"},{"line_number":53,"context_line":"    def get_plugin_description(self):"}],"source_content_type":"text/x-python","patch_set":5,"id":"fa32b979_cd3eb88a","line":50,"updated":"2015-06-17 22:59:47.000000000","message":"why?","commit_id":"0bff05f06e10d73b60a030e9bd5d9fb46ed01bf5"},{"author":{"_account_id":5756,"name":"Terry Wilson","email":"twilson@redhat.com","username":"otherwiseguy"},"change_message_id":"851c001c8fea800bea3275d6a64028b8d5a1076d","unresolved":false,"context_lines":[{"line_number":47,"context_line":"        Each service plugin should have a symbolic name. This name"},{"line_number":48,"context_line":"        will be used, for instance, by service definitions in service types"},{"line_number":49,"context_line":"        \"\"\""},{"line_number":50,"context_line":"        return None"},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"    @abc.abstractmethod"},{"line_number":53,"context_line":"    def get_plugin_description(self):"}],"source_content_type":"text/x-python","patch_set":5,"id":"fa32b979_a8aec2e3","line":50,"in_reply_to":"fa32b979_cd3eb88a","updated":"2015-06-18 00:39:20.000000000","message":"We need get_processes() in both core and service plugin base classes.\n\nOddly, only the metering service plugin inherits ServicePluginBase, but the other service plugins actually implement its interface...except get_plugin_name() which actually is never called *anywhere*.\n\nInstead of adding useless get_plugin_name() calls to all of the services, instead I remove the abstractmethod and return a default value.\n\nNow, you\u0027ll also notice that I didn\u0027t actually add ServicePluginBase to anything but l3_router_plugin\u0027s service class. Well, it turns out that all of the other in-tree service plugin classes actually inherit from NeutronDbPluginV2, which inherits from NeutronBasePluginV2 which already has get_processes() added so core plugins are handled...\n\nSo, basically, this is an area for future improvement...some more unified core/service plugin stuff.","commit_id":"0bff05f06e10d73b60a030e9bd5d9fb46ed01bf5"},{"author":{"_account_id":261,"name":"Salvatore Orlando","email":"salv.orlando@gmail.com","username":"salvatore-orlando"},"change_message_id":"5d4fb6840f0deb1def01cc2b0fff31759ba6745a","unresolved":false,"context_lines":[{"line_number":41,"context_line":"        \"\"\""},{"line_number":42,"context_line":"        pass"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"    @abc.abstractmethod"},{"line_number":45,"context_line":"    def get_plugin_name(self):"},{"line_number":46,"context_line":"        \"\"\"Return a symbolic name for the plugin."},{"line_number":47,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"fa32b979_ee71e4a9","side":"PARENT","line":44,"updated":"2015-06-19 13:48:22.000000000","message":"Why did you feel this change was needed?","commit_id":"3b27f83964d44241dd03d680f79e14e7459db4da"},{"author":{"_account_id":5756,"name":"Terry Wilson","email":"twilson@redhat.com","username":"otherwiseguy"},"change_message_id":"09ba04876cb317f3dbf60e20047a820c321c2f27","unresolved":false,"context_lines":[{"line_number":41,"context_line":"        \"\"\""},{"line_number":42,"context_line":"        pass"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"    @abc.abstractmethod"},{"line_number":45,"context_line":"    def get_plugin_name(self):"},{"line_number":46,"context_line":"        \"\"\"Return a symbolic name for the plugin."},{"line_number":47,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"fa32b979_a5af722a","side":"PARENT","line":44,"in_reply_to":"fa32b979_ee71e4a9","updated":"2015-06-19 16:38:41.000000000","message":"See: https://review.openstack.org/#/c/189391/5/neutron/services/service_base.py","commit_id":"3b27f83964d44241dd03d680f79e14e7459db4da"}],"neutron/worker.py":[{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"e85c879537966ddb4210b66e157e85a1c00cc93d","unresolved":false,"context_lines":[{"line_number":22,"context_line":""},{"line_number":23,"context_line":"    Subclasses will still need to add the other abstractmethods defined in"},{"line_number":24,"context_line":"    service.ServiceBase"},{"line_number":25,"context_line":"    \"\"\""},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"    def start(self):"},{"line_number":28,"context_line":"        registry.notify(resources.PROCESS, events.AFTER_CREATE, self.start)"}],"source_content_type":"text/x-python","patch_set":14,"id":"da20952f_d9c5868e","line":25,"updated":"2015-08-27 20:14:16.000000000","message":"Looking at this, it isn\u0027t super obvious how I would implement a worker as a plugin developer. Can you add something to the devref or at least explain in the docstring what the lifecycle of a worker is? (e.g. when is start called, what should a worker do when wait is called, etc)","commit_id":"b228c29b00acb13405623e55b427bb8fba0d8a2c"},{"author":{"_account_id":5756,"name":"Terry Wilson","email":"twilson@redhat.com","username":"otherwiseguy"},"change_message_id":"772e5eb7137e61b5eeb2494acdaaad10fc926977","unresolved":false,"context_lines":[{"line_number":22,"context_line":""},{"line_number":23,"context_line":"    Subclasses will still need to add the other abstractmethods defined in"},{"line_number":24,"context_line":"    service.ServiceBase"},{"line_number":25,"context_line":"    \"\"\""},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"    def start(self):"},{"line_number":28,"context_line":"        registry.notify(resources.PROCESS, events.AFTER_CREATE, self.start)"}],"source_content_type":"text/x-python","patch_set":14,"id":"da20952f_34cb3fa7","line":25,"in_reply_to":"da20952f_d9c5868e","updated":"2015-08-28 14:24:44.000000000","message":"Done","commit_id":"b228c29b00acb13405623e55b427bb8fba0d8a2c"},{"author":{"_account_id":748,"name":"Armando Migliaccio","email":"armamig@gmail.com","username":"armando-migliaccio"},"change_message_id":"6c74971070c8cc278acc54fe024c3f8bd57c4b2c","unresolved":false,"context_lines":[{"line_number":23,"context_line":"    Subclasses will still need to add the other abstractmethods defined in"},{"line_number":24,"context_line":"    service.ServiceBase. See oslo_service for more details."},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"    If a plugin needs to handle synchornization with the Neutron database and"},{"line_number":27,"context_line":"    do this only once instead of in every API worker, for instance, it would"},{"line_number":28,"context_line":"    define a NeutronWorker class and the plugin would have get_workers return"},{"line_number":29,"context_line":"    an array of NeutronWorker instnaces. For example:"}],"source_content_type":"text/x-python","patch_set":17,"id":"da20952f_25565006","line":26,"updated":"2015-08-31 17:52:04.000000000","message":"spelling nit","commit_id":"a1c494700eb0d8150b4b76099cc7b7b7c3c0294e"},{"author":{"_account_id":748,"name":"Armando Migliaccio","email":"armamig@gmail.com","username":"armando-migliaccio"},"change_message_id":"6c74971070c8cc278acc54fe024c3f8bd57c4b2c","unresolved":false,"context_lines":[{"line_number":26,"context_line":"    If a plugin needs to handle synchornization with the Neutron database and"},{"line_number":27,"context_line":"    do this only once instead of in every API worker, for instance, it would"},{"line_number":28,"context_line":"    define a NeutronWorker class and the plugin would have get_workers return"},{"line_number":29,"context_line":"    an array of NeutronWorker instnaces. For example:"},{"line_number":30,"context_line":"        class MyPlugin(...):"},{"line_number":31,"context_line":"            def get_workers(self):"},{"line_number":32,"context_line":"                return [MyPluginWorker()]"}],"source_content_type":"text/x-python","patch_set":17,"id":"da20952f_857abc86","line":29,"updated":"2015-08-31 17:52:04.000000000","message":"another spelling nit","commit_id":"a1c494700eb0d8150b4b76099cc7b7b7c3c0294e"}]}
