)]}'
{"id":"openstack%2Fopenstack-specs~153298","triplet_id":"openstack%2Fopenstack-specs~master~If00cda67a79c02aa3fbf413ba0105739567839c7","project":"openstack/openstack-specs","branch":"master","topic":"bp/greenio-executor","hashtags":[],"change_id":"If00cda67a79c02aa3fbf413ba0105739567839c7","subject":"Replace eventlet with asyncio","status":"ABANDONED","created":"2015-02-05 17:06:51.000000000","updated":"2015-04-30 14:59:06.000000000","total_comment_count":128,"unresolved_comment_count":0,"has_review_started":true,"meta_rev_id":"0448a2dedfb349af2fe33c043548e8f67dce40d7","_number":153298,"virtual_id_number":153298,"owner":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"actions":{},"labels":{"Verified":{"recommended":{"_account_id":3,"name":"Jenkins","username":"jenkins"},"all":[{"_account_id":9664,"name":"amrith","email":"amrith.kumar@gmail.com","username":"amrith"},{"value":1,"date":"2015-02-18 22:16:26.000000000","_account_id":3,"name":"Jenkins","username":"jenkins"},{"_account_id":100,"name":"Johannes Erdfelt","email":"johannes@erdfelt.com","username":"johannes.erdfelt"},{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},{"_account_id":1736,"name":"Ivan Kolodyazhny","email":"e0ne@e0ne.info","username":"e0ne"},{"date":"2015-02-19 02:13:06.000000000","_account_id":11816,"name":"mike bayer","display_name":"Mike Bayer","email":"mike_mp@zzzcomputing.com","username":"zzzeek","status":"Red Hat"},{"_account_id":2472,"name":"Doug Hellmann","email":"dhellmann@redhat.com","username":"doug-hellmann"},{"_account_id":13290,"name":"Oleksii Zamiatin","email":"ozamiatin@mirantis.com","username":"ozamiatin"},{"_account_id":4715,"name":"Angus Salkeld","email":"asalkeld@redhat.com","username":"asalkeld"},{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},{"date":"2015-02-19 00:42:06.000000000","_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},{"_account_id":8978,"name":"Marek Denis","email":"marek.denis+openstack@gmail.com","username":"marek-denis"},{"date":"2015-02-18 22:02:23.000000000","_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},{"date":"2015-02-26 15:31:39.000000000","_account_id":308,"name":"Thierry Carrez","email":"thierry@openstack.org","username":"ttx"},{"_account_id":10965,"name":"Magesh GV","email":"mageshgv@gmail.com","username":"mageshgv"},{"_account_id":1849,"name":"Joe Gordon","email":"joe.gordon0@gmail.com","username":"jogo"},{"_account_id":4190,"name":"lifeless","email":"robertc@robertcollins.net","username":"lifeless"},{"_account_id":9311,"name":"Tristan Cacqueray","email":"tdecacqu@redhat.com","username":"tristanC"}],"values":{"-2":"Fails","-1":"Doesn\u0027t seem to work"," 0":"No score","+1":"Works for me","+2":"Verified"},"description":"","value":1,"default_value":0,"optional":true},"Code-Review":{"disliked":{"_account_id":4190,"name":"lifeless","email":"robertc@robertcollins.net","username":"lifeless"},"all":[{"value":0,"permitted_voting_range":{"min":-1,"max":1},"_account_id":9664,"name":"amrith","email":"amrith.kumar@gmail.com","username":"amrith"},{"value":0,"permitted_voting_range":{"min":-1,"max":1},"_account_id":3,"name":"Jenkins","username":"jenkins"},{"value":0,"permitted_voting_range":{"min":-1,"max":1},"_account_id":100,"name":"Johannes Erdfelt","email":"johannes@erdfelt.com","username":"johannes.erdfelt"},{"value":0,"permitted_voting_range":{"min":-1,"max":1},"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},{"value":0,"permitted_voting_range":{"min":-1,"max":1},"_account_id":1736,"name":"Ivan Kolodyazhny","email":"e0ne@e0ne.info","username":"e0ne"},{"value":0,"permitted_voting_range":{"min":-1,"max":1},"_account_id":11816,"name":"mike bayer","display_name":"Mike Bayer","email":"mike_mp@zzzcomputing.com","username":"zzzeek","status":"Red Hat"},{"value":0,"permitted_voting_range":{"min":-1,"max":1},"_account_id":2472,"name":"Doug Hellmann","email":"dhellmann@redhat.com","username":"doug-hellmann"},{"value":0,"permitted_voting_range":{"min":-1,"max":1},"_account_id":13290,"name":"Oleksii Zamiatin","email":"ozamiatin@mirantis.com","username":"ozamiatin"},{"value":-1,"date":"2015-03-04 00:02:02.000000000","permitted_voting_range":{"min":-1,"max":1},"_account_id":4715,"name":"Angus Salkeld","email":"asalkeld@redhat.com","username":"asalkeld"},{"value":-1,"date":"2015-02-20 12:46:20.000000000","permitted_voting_range":{"min":-1,"max":1},"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},{"value":0,"permitted_voting_range":{"min":-1,"max":1},"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},{"value":0,"permitted_voting_range":{"min":-1,"max":1},"_account_id":8978,"name":"Marek Denis","email":"marek.denis+openstack@gmail.com","username":"marek-denis"},{"value":0,"permitted_voting_range":{"min":-1,"max":1},"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},{"value":0,"permitted_voting_range":{"min":-1,"max":1},"_account_id":308,"name":"Thierry Carrez","email":"thierry@openstack.org","username":"ttx"},{"value":0,"permitted_voting_range":{"min":-1,"max":1},"_account_id":10965,"name":"Magesh GV","email":"mageshgv@gmail.com","username":"mageshgv"},{"value":0,"permitted_voting_range":{"min":-1,"max":1},"_account_id":1849,"name":"Joe Gordon","email":"joe.gordon0@gmail.com","username":"jogo"},{"value":-1,"date":"2015-02-25 03:19:27.000000000","permitted_voting_range":{"min":-1,"max":1},"_account_id":4190,"name":"lifeless","email":"robertc@robertcollins.net","username":"lifeless"},{"value":0,"permitted_voting_range":{"min":-1,"max":1},"_account_id":9311,"name":"Tristan Cacqueray","email":"tdecacqu@redhat.com","username":"tristanC"}],"values":{"-2":"Do not merge","-1":"This patch needs further work before it can be merged"," 0":"No score","+1":"Looks good to me, but someone else must approve","+2":"Looks good to me (core reviewer)"},"description":"","value":-1,"default_value":0,"optional":true},"Workflow":{"all":[{"_account_id":9664,"name":"amrith","email":"amrith.kumar@gmail.com","username":"amrith"},{"_account_id":3,"name":"Jenkins","username":"jenkins"},{"_account_id":100,"name":"Johannes Erdfelt","email":"johannes@erdfelt.com","username":"johannes.erdfelt"},{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},{"date":"2015-03-18 18:36:09.000000000","_account_id":1736,"name":"Ivan Kolodyazhny","email":"e0ne@e0ne.info","username":"e0ne"},{"_account_id":11816,"name":"mike bayer","display_name":"Mike Bayer","email":"mike_mp@zzzcomputing.com","username":"zzzeek","status":"Red Hat"},{"_account_id":2472,"name":"Doug Hellmann","email":"dhellmann@redhat.com","username":"doug-hellmann"},{"_account_id":13290,"name":"Oleksii Zamiatin","email":"ozamiatin@mirantis.com","username":"ozamiatin"},{"_account_id":4715,"name":"Angus Salkeld","email":"asalkeld@redhat.com","username":"asalkeld"},{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},{"_account_id":8978,"name":"Marek Denis","email":"marek.denis+openstack@gmail.com","username":"marek-denis"},{"value":0,"permitted_voting_range":{"min":-1,"max":0},"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},{"_account_id":308,"name":"Thierry Carrez","email":"thierry@openstack.org","username":"ttx"},{"date":"2015-02-25 03:39:34.000000000","_account_id":10965,"name":"Magesh GV","email":"mageshgv@gmail.com","username":"mageshgv"},{"_account_id":1849,"name":"Joe Gordon","email":"joe.gordon0@gmail.com","username":"jogo"},{"_account_id":4190,"name":"lifeless","email":"robertc@robertcollins.net","username":"lifeless"},{"_account_id":9311,"name":"Tristan Cacqueray","email":"tdecacqu@redhat.com","username":"tristanC"}],"values":{"-1":"Work in progress"," 0":"Ready for reviews","+1":"Approved"},"description":"","default_value":0,"optional":true}},"removable_reviewers":[],"reviewers":{"REVIEWER":[{"_account_id":3,"name":"Jenkins","username":"jenkins"},{"_account_id":100,"name":"Johannes Erdfelt","email":"johannes@erdfelt.com","username":"johannes.erdfelt"},{"_account_id":308,"name":"Thierry Carrez","email":"thierry@openstack.org","username":"ttx"},{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},{"_account_id":1736,"name":"Ivan Kolodyazhny","email":"e0ne@e0ne.info","username":"e0ne"},{"_account_id":1849,"name":"Joe Gordon","email":"joe.gordon0@gmail.com","username":"jogo"},{"_account_id":2472,"name":"Doug Hellmann","email":"dhellmann@redhat.com","username":"doug-hellmann"},{"_account_id":4190,"name":"lifeless","email":"robertc@robertcollins.net","username":"lifeless"},{"_account_id":4715,"name":"Angus Salkeld","email":"asalkeld@redhat.com","username":"asalkeld"},{"_account_id":8978,"name":"Marek Denis","email":"marek.denis+openstack@gmail.com","username":"marek-denis"},{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},{"_account_id":9311,"name":"Tristan Cacqueray","email":"tdecacqu@redhat.com","username":"tristanC"},{"_account_id":9664,"name":"amrith","email":"amrith.kumar@gmail.com","username":"amrith"},{"_account_id":10965,"name":"Magesh GV","email":"mageshgv@gmail.com","username":"mageshgv"},{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},{"_account_id":11816,"name":"mike bayer","display_name":"Mike Bayer","email":"mike_mp@zzzcomputing.com","username":"zzzeek","status":"Red Hat"},{"_account_id":13290,"name":"Oleksii Zamiatin","email":"ozamiatin@mirantis.com","username":"ozamiatin"}]},"pending_reviewers":{},"reviewer_updates":[{"updated":"2015-02-06 10:47:22.000000000","updated_by":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"reviewer":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"state":"REVIEWER"},{"updated":"2015-02-11 02:11:40.000000000","updated_by":{"_account_id":9311,"name":"Tristan Cacqueray","email":"tdecacqu@redhat.com","username":"tristanC"},"reviewer":{"_account_id":9311,"name":"Tristan Cacqueray","email":"tdecacqu@redhat.com","username":"tristanC"},"state":"REVIEWER"},{"updated":"2015-02-11 06:54:01.000000000","updated_by":{"_account_id":8978,"name":"Marek Denis","email":"marek.denis+openstack@gmail.com","username":"marek-denis"},"reviewer":{"_account_id":8978,"name":"Marek Denis","email":"marek.denis+openstack@gmail.com","username":"marek-denis"},"state":"REVIEWER"},{"updated":"2015-02-11 08:36:31.000000000","updated_by":{"_account_id":13290,"name":"Oleksii Zamiatin","email":"ozamiatin@mirantis.com","username":"ozamiatin"},"reviewer":{"_account_id":13290,"name":"Oleksii Zamiatin","email":"ozamiatin@mirantis.com","username":"ozamiatin"},"state":"REVIEWER"},{"updated":"2015-02-11 16:05:14.000000000","updated_by":{"_account_id":9664,"name":"amrith","email":"amrith.kumar@gmail.com","username":"amrith"},"reviewer":{"_account_id":9664,"name":"amrith","email":"amrith.kumar@gmail.com","username":"amrith"},"state":"REVIEWER"},{"updated":"2015-02-11 16:53:45.000000000","updated_by":{"_account_id":100,"name":"Johannes Erdfelt","email":"johannes@erdfelt.com","username":"johannes.erdfelt"},"reviewer":{"_account_id":100,"name":"Johannes Erdfelt","email":"johannes@erdfelt.com","username":"johannes.erdfelt"},"state":"REVIEWER"},{"updated":"2015-02-16 23:29:54.000000000","updated_by":{"_account_id":2472,"name":"Doug Hellmann","email":"dhellmann@redhat.com","username":"doug-hellmann"},"reviewer":{"_account_id":2472,"name":"Doug Hellmann","email":"dhellmann@redhat.com","username":"doug-hellmann"},"state":"REVIEWER"},{"updated":"2015-02-17 18:57:21.000000000","updated_by":{"_account_id":1849,"name":"Joe Gordon","email":"joe.gordon0@gmail.com","username":"jogo"},"reviewer":{"_account_id":1849,"name":"Joe Gordon","email":"joe.gordon0@gmail.com","username":"jogo"},"state":"REVIEWER"},{"updated":"2015-02-18 22:16:26.000000000","updated_by":{"_account_id":3,"name":"Jenkins","username":"jenkins"},"reviewer":{"_account_id":3,"name":"Jenkins","username":"jenkins"},"state":"REVIEWER"},{"updated":"2015-02-19 00:42:06.000000000","updated_by":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"reviewer":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"state":"REVIEWER"},{"updated":"2015-02-19 02:13:06.000000000","updated_by":{"_account_id":11816,"name":"mike bayer","display_name":"Mike Bayer","email":"mike_mp@zzzcomputing.com","username":"zzzeek","status":"Red Hat"},"reviewer":{"_account_id":11816,"name":"mike bayer","display_name":"Mike Bayer","email":"mike_mp@zzzcomputing.com","username":"zzzeek","status":"Red Hat"},"state":"REVIEWER"},{"updated":"2015-02-20 12:46:20.000000000","updated_by":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"reviewer":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"state":"REVIEWER"},{"updated":"2015-02-25 03:19:27.000000000","updated_by":{"_account_id":4190,"name":"lifeless","email":"robertc@robertcollins.net","username":"lifeless"},"reviewer":{"_account_id":4190,"name":"lifeless","email":"robertc@robertcollins.net","username":"lifeless"},"state":"REVIEWER"},{"updated":"2015-02-25 03:39:34.000000000","updated_by":{"_account_id":10965,"name":"Magesh GV","email":"mageshgv@gmail.com","username":"mageshgv"},"reviewer":{"_account_id":10965,"name":"Magesh GV","email":"mageshgv@gmail.com","username":"mageshgv"},"state":"REVIEWER"},{"updated":"2015-02-26 15:31:39.000000000","updated_by":{"_account_id":308,"name":"Thierry Carrez","email":"thierry@openstack.org","username":"ttx"},"reviewer":{"_account_id":308,"name":"Thierry Carrez","email":"thierry@openstack.org","username":"ttx"},"state":"REVIEWER"},{"updated":"2015-03-04 00:02:02.000000000","updated_by":{"_account_id":4715,"name":"Angus Salkeld","email":"asalkeld@redhat.com","username":"asalkeld"},"reviewer":{"_account_id":4715,"name":"Angus Salkeld","email":"asalkeld@redhat.com","username":"asalkeld"},"state":"REVIEWER"},{"updated":"2015-03-18 18:36:09.000000000","updated_by":{"_account_id":1736,"name":"Ivan Kolodyazhny","email":"e0ne@e0ne.info","username":"e0ne"},"reviewer":{"_account_id":1736,"name":"Ivan Kolodyazhny","email":"e0ne@e0ne.info","username":"e0ne"},"state":"REVIEWER"}],"messages":[{"id":"fb4e7b10cfdd7f7ca9e94a9d90ab42938a4ac135","author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"date":"2015-02-05 17:06:51.000000000","message":"Uploaded patch set 1.","accounts_in_message":[],"_revision_number":1},{"id":"1fdd1c103bb14e80b3956cb9650cb15c8f551ada","author":{"_account_id":3,"name":"Jenkins","username":"jenkins"},"date":"2015-02-05 17:06:53.000000000","message":"Patch Set 1: Verified+1\n\nBuild succeeded (check pipeline).\n\n- noop http://logs.openstack.org/98/153298/1/check/noop/2c1f46b/ : SUCCESS","accounts_in_message":[],"_revision_number":1},{"id":"b85f2d3d18ad49bf3a29bff89dc98fc0f77a7a0b","author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"date":"2015-02-05 17:07:03.000000000","message":"Patch Set 1: Workflow-1","accounts_in_message":[],"_revision_number":1},{"id":"19559799fdfddaa5c498dd91e7b765acf5e43a92","author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"date":"2015-02-05 17:27:42.000000000","message":"Patch Set 1:\n\n(1 comment)","accounts_in_message":[],"_revision_number":1},{"id":"fef8e02583579a926bdc83aea0bf3cde5b9ce99b","author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"date":"2015-02-06 10:47:22.000000000","message":"Patch Set 1:\n\n(1 comment)\n\nThis is a very good plan, thanks Victor.","accounts_in_message":[],"_revision_number":1},{"id":"05907a80882516cbde3f137e83fe07bc710d0c2f","author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"date":"2015-02-06 11:34:19.000000000","message":"Patch Set 1:\n\n(1 comment)","accounts_in_message":[],"_revision_number":1},{"id":"5d33a77f39132079be9b01cc9e55d8254cf0b1a2","author":{"_account_id":1849,"name":"Joe Gordon","email":"joe.gordon0@gmail.com","username":"jogo"},"date":"2015-02-06 21:51:37.000000000","message":"Patch Set 1:\n\n(4 comments)\n\na few inline concerns","accounts_in_message":[],"_revision_number":1},{"id":"e7a9136b379c4236ff8e5b9cb28a288bea107d51","author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"date":"2015-02-06 23:33:54.000000000","message":"Patch Set 1:\n\n(12 comments)\n\nI\u0027m still sorta iffy on this; I understand the desire to do it but I keep on coming back to the question in the back of my mind, in that \u0027are we getting the most bang for the buck by doing this\u0027? Is it ready? ...\n\nNow I know that\u0027s hard to quantify (since my definition of bang for the buck is different than others); but knowing the state of openstack it almost feels like we should be a little bit wiser about spending our reviewer, committer ... time on something that adds a little more value to the whole code-base...","accounts_in_message":[],"_revision_number":1},{"id":"fddde51e56d7e6a612609d59a189ba3a2f44a2fe","author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"date":"2015-02-06 23:35:21.000000000","message":"Patch Set 1:\n\n(1 comment)","accounts_in_message":[],"_revision_number":1},{"id":"efdab6de0bbd6f772aae789d6c6d17a8ff8e1c52","author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"date":"2015-02-07 00:35:23.000000000","message":"Patch Set 1:\n\n(1 comment)","accounts_in_message":[],"_revision_number":1},{"id":"698e2a3136f82cc4651b20d7f027c6dcebb27792","author":{"_account_id":11816,"name":"mike bayer","display_name":"Mike Bayer","email":"mike_mp@zzzcomputing.com","username":"zzzeek","status":"Red Hat"},"date":"2015-02-07 00:50:34.000000000","message":"Patch Set 1: Code-Review-1\n\n(2 comments)\n\nIn the past, I\u0027ve done detailed research on how database code, libraries, and in particular SQLAlchemy Core and ORM would be made to work with explicit async scenarios such as Twisted.  While I was very hopeful that something would be possible, it became clear that database libraries are incompatible with async systems on many levels, and that to create database abstraction layers which are would mean the production of code that is vastly less efficient and more complex in the context of Python, which despite the niceness of the \"yield from\" trick, really lacks native asynchronous structures as nicely as a system which does, such as Go.    So I don\u0027t have much choice but to oppose any efforts towards moving Openstack applications, either legacy or new, which are database-centric towards explicit async programming.   Applications that aren\u0027t relational database centric, such as Ceilometer with MongoDB, I don\u0027t care.  Go crazy with those.","accounts_in_message":[],"_revision_number":1},{"id":"6f119e8d0b6d7f023a01b1c290608b87797ba639","author":{"_account_id":11816,"name":"mike bayer","display_name":"Mike Bayer","email":"mike_mp@zzzcomputing.com","username":"zzzeek","status":"Red Hat"},"date":"2015-02-07 00:54:35.000000000","message":"Patch Set 1:\n\n(1 comment)","accounts_in_message":[],"_revision_number":1},{"id":"f81484c5c25be99f77706120fe1d75accd342141","author":{"_account_id":11816,"name":"mike bayer","display_name":"Mike Bayer","email":"mike_mp@zzzcomputing.com","username":"zzzeek","status":"Red Hat"},"date":"2015-02-07 01:15:30.000000000","message":"Patch Set 1:\n\n(3 comments)","accounts_in_message":[],"_revision_number":1},{"id":"d927c4bf0d3d9021af78d6e1b2ccdf64f1d002f7","author":{"_account_id":11816,"name":"mike bayer","display_name":"Mike Bayer","email":"mike_mp@zzzcomputing.com","username":"zzzeek","status":"Red Hat"},"date":"2015-02-07 23:06:29.000000000","message":"Patch Set 1: -Code-Review","accounts_in_message":[],"_revision_number":1},{"id":"a9b124786426fed5e4a97ae3030136d405dba727","author":{"_account_id":11816,"name":"mike bayer","display_name":"Mike Bayer","email":"mike_mp@zzzcomputing.com","username":"zzzeek","status":"Red Hat"},"date":"2015-02-08 01:19:29.000000000","message":"Patch Set 1:\n\nI\u0027ve spent today looking into asyncio specifically.   The situation here is definitely much better than twisted, as you can port code that is synchronous to async with this approach much more easily, b.c. you still have return values and exception catching in largely the same way (of course with a lot more machinery on top to make it work).  I am hoping that the amount of code that has to change will be lots smaller, particularly that you do have at least a shot at having a lot more intermediary functions being agnostic of whether they are invoked async or not.\n\nObviously I want SQLAlchemy to have an answer for asyncio, now that this specific implementation has been now \"blessed\", and I\u0027ve begun working on the event and pool system first, this is mostly straightforward.   I would expect that all the folks working on SQLAlchemy-like systems such as aiopg would be willing to step up and provide support for these systems, as they have an interest in this story being available; support would be very helpful as these systems necessarily have to live separately from SQLA core proper (though not as far away as aiopg).\n\nThis is for pure asyncio that has \"yield from\", so it\u0027s python 3 only.   It also would have to provide an adapter to throw most DBAPIs into a thread pool.  This won\u0027t perform terrifically as I anticipate the overhead of movement in/out of the thread pool for every DBAPI call will be significant.   aiopg is one of the current examples of a truly async psycopg2-based DBAPI, though there are many aspects of its implementation I don\u0027t agree with.","accounts_in_message":[],"_revision_number":1},{"id":"424dddfa3a16db62a02872bc2637e325ce426a50","author":{"_account_id":11816,"name":"mike bayer","display_name":"Mike Bayer","email":"mike_mp@zzzcomputing.com","username":"zzzeek","status":"Red Hat"},"date":"2015-02-08 05:47:20.000000000","message":"Patch Set 1:\n\n(1 comment)","accounts_in_message":[],"_revision_number":1},{"id":"0201fccb439d25b19371ef64bfeee1de6fad7e06","author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"date":"2015-02-09 17:05:25.000000000","message":"Patch Set 1:\n\n(19 comments)","accounts_in_message":[],"_revision_number":1},{"id":"276685e204148e4450623144efde2e6326f67603","author":{"_account_id":11816,"name":"mike bayer","display_name":"Mike Bayer","email":"mike_mp@zzzcomputing.com","username":"zzzeek","status":"Red Hat"},"date":"2015-02-09 18:15:45.000000000","message":"Patch Set 1:\n\n(5 comments)","accounts_in_message":[],"_revision_number":1},{"id":"89af5e2c644b8c55dada1ac688775be87aa94a3f","author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"date":"2015-02-09 18:47:20.000000000","message":"Patch Set 1:\n\n(7 comments)\n\nMight also be worthwhile to link to https://wiki.openstack.org/wiki/UnifiedServiceArchitecture#eventlet_vs_Twisted (don\u0027t think I saw it linked to); which has some historical info that might be relevant to this.","accounts_in_message":[],"_revision_number":1},{"id":"4fc34a8614de7021b2176f2cef120dc9ea63662d","author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"date":"2015-02-09 22:58:40.000000000","message":"Patch Set 1:\n\n(4 comments)","accounts_in_message":[],"_revision_number":1},{"id":"5f73154e9b751aaf29c8ba2913bd2bdf87daee7b","author":{"_account_id":1849,"name":"Joe Gordon","email":"joe.gordon0@gmail.com","username":"jogo"},"date":"2015-02-10 01:18:58.000000000","message":"Patch Set 1:\n\n(2 comments)","accounts_in_message":[],"_revision_number":1},{"id":"8e8d47bec7d4467ad1dbeb0bf533bd2e25354e8e","author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"date":"2015-02-10 23:54:47.000000000","message":"Uploaded patch set 2.","accounts_in_message":[],"_revision_number":2},{"id":"bcc1896d4a8bc3a18f084dfd8d84d610f4cdbd35","author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"date":"2015-02-10 23:58:37.000000000","message":"Patch Set 1:\n\n(1 comment)","accounts_in_message":[],"_revision_number":1},{"id":"3785b438df047ae42cc3853132405d64cf2f6df7","author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"date":"2015-02-11 00:00:42.000000000","message":"Patch Set 2:\n\nI posted a second version of the spec. I tried to take in account all comments posted on the first draft. It is no more a draft, you can now review it.","accounts_in_message":[],"_revision_number":2},{"id":"8e0ef8f2f417ecad6347bd0d23261c25bec11eae","author":{"_account_id":3,"name":"Jenkins","username":"jenkins"},"date":"2015-02-11 00:06:06.000000000","message":"Patch Set 2: Verified+1\n\nBuild succeeded (check pipeline).\n\n- gate-openstack-specs-docs http://docs-draft.openstack.org/98/153298/2/check/gate-openstack-specs-docs/450823a//doc/build/html/ : SUCCESS in 1m 55s","accounts_in_message":[],"_revision_number":2},{"id":"b9074794df6c1f2632869f7c31b84d83b1845f08","author":{"_account_id":11816,"name":"mike bayer","display_name":"Mike Bayer","email":"mike_mp@zzzcomputing.com","username":"zzzeek","status":"Red Hat"},"date":"2015-02-11 00:44:57.000000000","message":"Patch Set 1:\n\n(1 comment)","accounts_in_message":[],"_revision_number":1},{"id":"bb0bd86a37399d2f44bb75a41a286559ff991bf1","author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"date":"2015-02-11 01:20:04.000000000","message":"Patch Set 2:\n\n(3 comments)","accounts_in_message":[],"_revision_number":2},{"id":"f49652d6127e7ec855dd7fe465cac1bcb021569f","author":{"_account_id":13290,"name":"Oleksii Zamiatin","email":"ozamiatin@mirantis.com","username":"ozamiatin"},"date":"2015-02-11 08:36:31.000000000","message":"Patch Set 2: Code-Review+1","accounts_in_message":[],"_revision_number":2},{"id":"9696bd3792ff8fd8b5811645352b5389933b50bd","author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"date":"2015-02-11 10:35:11.000000000","message":"Patch Set 2:\n\n(1 comment)","accounts_in_message":[],"_revision_number":2},{"id":"c396ea76642b952d3d23393debea0fa147367d22","author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"date":"2015-02-11 11:17:09.000000000","message":"Patch Set 2:\n\n(1 comment)","accounts_in_message":[],"_revision_number":2},{"id":"3e0e9a58d8e381b315ef66088befcd65ef1cc749","author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"date":"2015-02-11 14:27:42.000000000","message":"Patch Set 1:\n\n(1 comment)","accounts_in_message":[],"_revision_number":1},{"id":"ad8c1f5c836a798e342bc05c272bfc2383d6ee38","author":{"_account_id":100,"name":"Johannes Erdfelt","email":"johannes@erdfelt.com","username":"johannes.erdfelt"},"date":"2015-02-11 16:53:45.000000000","message":"Patch Set 2: Code-Review-1\n\n(2 comments)\n\nI\u0027m not familiar with ceilometer design or implementation, but at least from the perspective of Nova, asyncio is a step backwards.\n\nI\u0027m -1 mostly because this can\u0027t be a solution for all of OpenStack.","accounts_in_message":[],"_revision_number":2},{"id":"59bb5b32250a238d56f6a47a4eac2e20dce80f5c","author":{"_account_id":9664,"name":"amrith","email":"amrith.kumar@gmail.com","username":"amrith"},"date":"2015-02-11 17:33:59.000000000","message":"Patch Set 2: Code-Review-1\n\n(3 comments)\n\nI\u0027m reviewing this -1 because of the underlying change here to require a conscious switch from synchronous to the explicitly asynchronous programming model.\n\nCode that is written to be synchronous is easier to read and debug and much simpler to design. It is also (often) very hard to scale. Writing a truly asynchronous application is much more complex at all levels, to design well, to write, to understand, to debug, and to maintain. But it is so much more efficient and there is great attraction to doing this.\n\nI\u0027ve used asyncio (not with python but in C/C++) and I like it. But it is very hard to get right.\n\nOn the other hand, I entirely see the issues with eventlet; they have been a nightmare to debug (in trove) and I\u0027d very much like to get to the bottom of some issues with it still.\n\nThat said, I\u0027m hoping we can find a solution that will allow the programming model to remain synchronous with whatever magic under the covers and abstracted from the openstack tier.\n\nThe cost and complexity that this change (especially the let\u0027s part with eventlet) will impose on the existing code base strikes me as a huge tax.","accounts_in_message":[],"_revision_number":2},{"id":"adc58dca2ec7e5b6c11dd919869499f529d42c2e","author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"date":"2015-02-12 07:04:22.000000000","message":"Patch Set 2:\n\n(2 comments)","accounts_in_message":[],"_revision_number":2},{"id":"b480526169cfbf076bcef4e65ac766f05a1de834","author":{"_account_id":9555,"name":"Matthew Booth","email":"mbooth@redhat.com","username":"MatthewBooth"},"date":"2015-02-12 10:00:31.000000000","message":"Patch Set 2:\n\n(3 comments)\n\nIs performance relevant to this discussion? My expectation (which is admittedly not supported by data) is that the cpu-bound processing of Nova is insignificant. As long as Nova can ensure the host remains IO bound, it\u0027s achieving maximum performance. Do we have any evidence that it\u0027s not doing this?\n\nIf not, then we can simplify this discussion to which is easier to write correct code for.","accounts_in_message":[],"_revision_number":2},{"id":"d8b7fee4d6a0a41bb077abc9bc62cb09f2912b4d","author":{"_account_id":9555,"name":"Matthew Booth","email":"mbooth@redhat.com","username":"MatthewBooth"},"date":"2015-02-12 10:13:46.000000000","message":"Patch Set 2:\n\n(1 comment)","accounts_in_message":[],"_revision_number":2},{"id":"4e9647e2f5c51443a9efd8ec91aee20c7fa6616c","author":{"_account_id":11816,"name":"mike bayer","display_name":"Mike Bayer","email":"mike_mp@zzzcomputing.com","username":"zzzeek","status":"Red Hat"},"date":"2015-02-12 15:29:15.000000000","message":"Patch Set 2:\n\n(1 comment)","accounts_in_message":[],"_revision_number":2},{"id":"cd06864659e4acb70f3aa902c27c535a66f79f19","author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"date":"2015-02-12 17:18:44.000000000","message":"Patch Set 2:\n\n(1 comment)","accounts_in_message":[],"_revision_number":2},{"id":"d9604450b30c35f8d49b893db95a13ea789990da","author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"date":"2015-02-13 15:04:50.000000000","message":"Patch Set 2:\n\n(8 comments)","accounts_in_message":[],"_revision_number":2},{"id":"925ad20de1932b94fc1d2c7f2edffb8cde3f8d4b","author":{"_account_id":11816,"name":"mike bayer","display_name":"Mike Bayer","email":"mike_mp@zzzcomputing.com","username":"zzzeek","status":"Red Hat"},"date":"2015-02-13 16:39:15.000000000","message":"Patch Set 2:\n\n(1 comment)","accounts_in_message":[],"_revision_number":2},{"id":"1b89895122a399dbf698c9168e44555c7c6c80bb","author":{"_account_id":4190,"name":"lifeless","email":"robertc@robertcollins.net","username":"lifeless"},"date":"2015-02-16 22:25:29.000000000","message":"Patch Set 2:\n\nOn performance, Joe Gordon (amongst others) has done some profiling of basic operations, and IIRC Nova API performance is currently shockingly poor, but we don\u0027t know where the issue is yet. So performance certainly is relevant (but not dominating).","accounts_in_message":[],"_revision_number":2},{"id":"2743f58e8b8ab810a19fd8ea1d8c6592039d7fe5","author":{"_account_id":2472,"name":"Doug Hellmann","email":"dhellmann@redhat.com","username":"doug-hellmann"},"date":"2015-02-16 23:29:54.000000000","message":"Patch Set 2: Code-Review-1\n\n(2 comments)\n\nI wonder if we\u0027re starting out with invalid assumptions. Reading over\nthe old UnifiedServiceArchitecture page in the wiki, it\u0027s not clear to\nme why we felt we needed to use any special I/O handling at the\nbeginning of the project. This spec continues with the assumption,\nsubstituting one tool and programming style for another.\n\nMy understanding is that asynchronous I/O techniques are usually\napplied where an application is I/O-bound on several inputs or\noutputs, or wants to work with many many sockets -- possibly more than\nthe supported number of concurrent threads that could be managed\nreasonably (assuming the usual model of one thread per socket). Do we\nhave any components that scale that way?  Even Ceilometer, which sends\nmany messages about the stats it collects and consumes all of the\nnotifications generated by the other services and is therefore\nprobably the busiest user of the message bus, has been reported to be\nCPU-bound rather than I/O-bound (either on itself, or the database)\nand really only needs a few sockets to listen to messages and talk to\nthe database.\n\nThe vast majority of our services either run as a WSGI app or\ncommunicate with the database. Some do both. Only a few agents do\nneither. Any tool we choose, therefore, should work for those cases.\n\nWeb servers are the obvious place where we wouldn\u0027t be able to predict\nthe number of incoming requests, and where we might have a large\nnumber of simultaneous socket connections. That makes them seem like a\ngood fit for asyncio. However, we\u0027ve built all of our services as WSGI\napps, and so the fact that asyncio does not support WSGI (or vice\nversa, depending on your perspective) is a problem.  Would we be\nbetter served (pun not intended) to rely on stable production-ready\nWSGI containers, and horizontal scaling, rather than picking up some\nof the newer tools associated with asyncio?\n\nThe database driver is the other place where we do a lot of I/O and\nmight benefit from async, rather than blocking, I/O. However,\nSQLAlchemy does not yet support asyncio (or vice versa).  While the\nCeilometer team might feel comfortable switching to an asyncio-based\nMongo driver, if there are no other such options for the rest of the\nOpenStack services then we need a better picture for how we are\nsupposed to proceed before agreeing to go down this path.\n\nIf asyncio does not work together with WSGI or SQLAlchemy, then we\nhave two large blocking issues with adopting asyncio completely. We\ncould consider using it only where possible, but would we see enough\nbenefit in terms of performance or throughput in the few apps where we\ncould use asyncio to warrant the amount of work it would take to\nmodify them and support both models simultaneously?\n\nWe also have to consider how that would affect maintenance of all of\nour libraries (service clients, Oslo, and third-party). We already\nhave some places where we have to test Oslo libraries separately with,\nand without, eventlet. I don\u0027t think we want to have to do that for a\nthird option.\n\nThere are a few other practical considerations to a shift as big as\nproposed here.\n\nFor example, discussing whether threading or asyncio is \"easier\" to\nuse is largely subjective. When eventlet was selected the developer\npool was significantly smaller than it is now, and I\u0027m not sure\neveryone agreed completely on the choice at the time. We\u0027re unlikely\nto find the community agreeing completely on that point today, so we\nneed to look seriously at the amount of work involved in any change\nthis big, and weigh that cost against the benefits.\n\nGiven the issues with libraries supporting asyncio, a more objective\nquestion is \"How many of the tools and libraries we are already using\nsupport the proposed approach?\" For example, we have encountered some\nlibraries that do not work well with eventlet, and we have pointed to\ncases where techniques and libraries we use do not work with\nasyncio. Do we rely on any libraries that are not thread-safe?\n\nA common complaint with threading is deadlocks due to accessing global\nstate. From what I\u0027ve seen, most of our global state is kept in the\ndatabase, rather than in-memory data structures, because we\u0027re already\ndealing with distributed services and \"eventual consistency\". How\noften do we keep global state in memory in an application in a way\nthat would be affected by concurrency changes -- where would we need\nto add new locking code if we switch to threads, for example?\n\nWe have several places where we use green threads, often explicitly,\nand rely on eventlet\u0027s to patch the threading module so the locking\nclasses work. Assuming that code is correct now, would we expect it to\nfunction correctly under regular threads (if we do not let eventlet\nmonkey patch)?\n\nAnother consideration is how much we would need to change the\napplication code. One reason eventlet was appealing was that code\nusing eventlet looks synchronous, even though it often ends up running\ndifferently when executed. Explicit async code needs to be changed in\na few ways, as you describe in the spec. Would we need to make similar\nchanges for threading? For example, we might need to add locks in\nplaces where eventlet is protecting us today. Is there any way to\npredict what other changes might be needed, without doing a full\nanalysis of the OpenStack code base (which I\u0027m definitely not asking\nfor)?\n\nTo sum up: I\u0027m not sure we need to worry as much about asynchronous\nI/O as we are. If I remember correctly, we originally started\ndiscussing asyncio as an alternative to eventlet in the context of\nporting OpenStack, and especially oslo.messaging, to Python 3, rather\nthan doing it for its own sake. While eventlet\u0027s support for Python 3\nis improving, it\u0027s not 100% yet, and that is not the only motivation\nwe have for dropping it. Perhaps we should reframe this discussion in\nterms of \"moving away from eventlet\" instead of \"moving to\" a specific\nsolution to give more attention to some of the alternatives in light\nof the practical considerations I\u0027ve mentioned above.","accounts_in_message":[],"_revision_number":2},{"id":"3d26bee115c8bfba12df5f9d088d2abba6c4c6ba","author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"date":"2015-02-17 14:02:59.000000000","message":"Patch Set 2:\n\n\"The database driver is the other place where we do a lot of I/O and might benefit from async, rather than blocking, I/O. However, SQLAlchemy does not yet support asyncio (or vice versa).\"\n\nAccording to Mike\u0027s benchmark, it\u0027s faster to run DB queries in threads than running them asynchronously using asyncio:\nhttp://techspot.zzzeek.org/2015/02/15/asynchronous-python-and-databases/\n\nI propose to *combine* the nice asyncio syntax for coroutines with a pool of threads for DB queries (using loop.run_in_executor()). In this case, SQLAchemy doesn\u0027t have to be modified at all.\n\nAs any other blocking functions called with loop.run_in_executor(). I suggest this option for any function which may block the event loop for \"too long\" (ex: more than 1 ms), especially I/O operations.\n\n\n\"If asyncio does not work together with WSGI or SQLAlchemy, then we have two large blocking issues with adopting asyncio completely.\"\n\nI chose to put WSGI outside the spec. There *are* solutions to use WSGI with asyncio, but they require hacks like monkey-patching, or modifying the code (I don\u0027t know how exactly, sorry). I prefer to focus first on asyncio, to check if it fits into OpenStack, so then see if it\u0027s worth to investigate the WSGI issue.\n\n\"We could consider using it only where possible, but would we see enough benefit in terms of performance or throughput in the few apps where we could use asyncio to warrant the amount of work it would take to modify them and support both models simultaneously?\"\n\nPerformances are not my primary motivation, it\u0027s more to have more reliable code with a nice syntax. If the code runs faster, it would be a nice side effect. According to comments, OpenStack doesn\u0027t fit into the asyncio ideal use case (a lot of idle sockets like web sockets) where asyncio can be expected to be much faster. By the way, asyncio is based on an event loop, as eventlet. So there is no huge difference between eventlet and asyncio in term of internal design. It\u0027s more differences in the way to use them.\n\n\n\"We also have to consider how that would affect maintenance of all of our libraries (service clients, Oslo, and third-party). We already have some places where we have to test Oslo libraries separately with, and without, eventlet. I don\u0027t think we want to have to do that for a third option.\"\n\nI understood that most OpenStack people want to replace eventlet with something else. Somewhere, we have to invest energy to fix the eventlet issue, no? I don\u0027t understand the logic. \n\nIn short, you choose to keep eventlet with its known issues?\n\neventlet looks to be an expensive technical debt in OpenStack, no?\n\n\n\"we need to look seriously at the amount of work involved in any change this big, and weigh that cost against the benefits.\"\n\nIn most comments, I read something like *all* OpenStack code must be fully rewritten from scratch to put \"yield from\" *everywhere*.\n\nI checked asyncio source code. asyncio must use yield-from everywhere since all code must be asynchronous (which is not the case for OpenStack where blocking function calls are acceptable).\n\nThe development version of asyncio has 11,006 lines. Only 94 lines contains \"yield from\": 0.8%. (To be honest, I had to double check. I was surprised by this low number :-))\n\n\n\u003e \"How many of the tools and libraries we are already using support the proposed approach?\"\n\u003e For example, we have encountered some libraries that do not work well with eventlet,\n\u003e and we have pointed to cases where techniques and libraries we use do not work with asyncio.\n\nRemember that OpenStack uses eventlet with monkey-patching. A very few number libraries are prepared for monkey-patching. I\u0027m suprised that it works so well :-) As I wrote in the spec, most eventlet issues come from the monkey-patching, not from asynchronous programming (green threads).\n\n\n\u003e Do we rely on any libraries that are not thread-safe?\n\nThe principle of asyncio is to run all code in a single thread. In this case, no lock is needed ;-)\n\n*If* you choose to run code in a dedicated (pool of) thread(s), you control which functions are called in a thread. If needed, you may put locks on functions which are not thread-safe.\n\nLater, you may enhance these libraries to add a builtin ayncio support, or make them thread-safe, if you like.\n\nAgain, we don\u0027t know which libraries *must* be called in threads for performances. So it\u0027s difficult to estimate the amount of work to use them correctly.\n\n\n\u003e where would we need to add new locking code if we switch to threads, for example?\n\nI cannot answer. I don\u0027t know if locks are missing.\n\nI hope that no new lock is need ;-) I\u0027m not sure that all issues will be seen with asyncio if most of the code run in a single thread.\n\n\n\u003e We have several places where we use green threads, often explicitly, and rely on eventlet\u0027s to patch the threading module so the locking classes work. Assuming that code is correct now, would we expect it to function correctly under regular threads (if we do not let eventlet monkey patch)?\n\nI have the same question. I expect some issues from @oslo_concurrency.lock_utils.lock or @oslo_concurrency.lock_utils.synchronized. I\u0027m not sure that these decorators were already well tested with native threads. If there are issues with these two decorators, I expect that it should be easy to fix them.\n\nI checked ceilometer: lockutils doesn\u0027t look to be used. ceilometer/openstack/common/lockutils.py exists, but I don\u0027t see it used outside tests.\n\n\n\u003e Another consideration is how much we would need to change the application code. One reason eventlet was appealing was that code using eventlet looks synchronous, even though it often ends up running differently when executed.\n\nIf you take blocking code and run it in asyncio: it just works. Blocking functions will block a few milliseconds, that\u0027s all.\n\nIf you want better performances, enable asyncio debug mode: it will warn you if a function blocks longer than 100 ms. You can tune the threshold (100 ms) to detect more blocking calls.\n\nSee:\nhttps://docs.python.org/dev/library/asyncio-dev.html#debug-mode-of-asyncio\nand\nhttps://docs.python.org/dev/library/asyncio-dev.html#handle-blocking-functions-correctly\n\n\n\u003e Explicit async code needs to be changed in a few ways, as you describe in the spec.\n\u003e Would we need to make similar changes for threading?\n\u003e For example, we might need to add locks in places where eventlet is protecting us\n\u003e today.\n\nHum, I\u0027m not aware of eventlet protections. What are these protections? What I understood is that basically green threads are similar to threads: a green thread can be interrupted anywhere. So code running in green threads must be \"thread-safe\" (green thread safe? :-)). Concurrency issues already exist with eventlet.\n\nSo I understand that existing race conditions were already fixed. No?\n\nasyncio may \"hide\" more issues than eventlet since there are less places where your code may be interrupted (ex: at exactly 94 lines in asyncio). I don\u0027t know if it\u0027s correct to say that asyncio hides issues, since there are no more issues.\n\nWell, let\u0027s take a dummy example:\n\n    def unsafe_method(self):\n        unique_id \u003d self.data[\u0027id\u0027]\n        maybe_async_func()\n        self.data[\u0027id\u0027] +\u003d 1\n        return unique_id\n\nUsing eventlet, you don\u0027t know if maybe_async_func() may pause unsafe_method(), in which case unsafe_method() can be called again from a different green thread \u003d\u003e race condition.\n\n\nUnsafe asyncio version:\n\n    def unsafe_method(self):\n        unique_id \u003d self.data[\u0027id\u0027]\n        yield from always_async_func()\n        self.data[\u0027id\u0027] +\u003d 1\n        return unique_id\n\n\u003d\u003e there is an obvious race condition: \"yield from\" interrupts unsafe_method(), so you may get the same identifier twice. You need a lock to protect self.data or write the code differently (ex: increment id before calling the second function).\n\nUsing asyncio, you must use \"yield from\" if the second function is asynchronous. There is not \"maybe\" async function. A function is always or never asynchronous.\n\nNow, let\u0027s say that the second function is not asynchronous:\n\n    def unsafe_method(self):\n        unique_id \u003d self.data[\u0027id\u0027]\n        sync_func()\n        self.data[\u0027id\u0027] +\u003d 1\n        return unique_id\n\nIn this case, you can only have a race condition if sync_func() calls again unsafe_method(), directly or indirectly. It\u0027s less likely since we don\u0027t pass self to sync_func().\n\nAs I wrote in the spec: asyncio only reduces the risk of race condition, insane code like reentrant and recursive function calls can still have race conditions ;-)\n\nNote: if sync_func() schedules a call to unsafe_method() using call_soon() or a coroutine, the scheduled call will only be called \"later\", after unsafe_method() exited since unsafe_method() cannot wake up the event loop (there is no yield-from).\n\n\n\u003e Perhaps we should reframe this discussion in terms of \"moving away from eventlet\" instead of \"moving to\" a specific solution to give more attention to some of the alternatives in light of the practical considerations I\u0027ve mentioned above.\n\nThis spec helped to evaluate the thread option. Do you see more alternatives?\n\nIf someone is motivated to replace eventlet with threads, it would be better to write a new spec. I didn\u0027t investigated the thread option, I only summarized comments.\n\nI don\u0027t like threads, especially in Python, I prefer to stay away from them ;-)","accounts_in_message":[],"_revision_number":2},{"id":"9fea2e6809d7f7cc9d56e29230cd6c1356ab0cf1","author":{"_account_id":100,"name":"Johannes Erdfelt","email":"johannes@erdfelt.com","username":"johannes.erdfelt"},"date":"2015-02-17 17:14:15.000000000","message":"Patch Set 2:\n\n(3 comments)\n\n\u003e I understood that most OpenStack people want to replace eventlet with something else. Somewhere, we have to invest energy to fix the eventlet issue, no? I don\u0027t understand the logic.\n\u003e In short, you choose to keep eventlet with its known issues?\n\u003e eventlet looks to be an expensive technical debt in OpenStack, no?\n\nI think you are misinterpting peoples dislike for this proposal as liking eventlet. No one likes eventlet :)\n\nJust that some people don\u0027t see asyncio as a significantly better solution than asyncio.\n\nIn some ways it\u0027s worse. It requires a ton of gratuitous syntax changes. The claims that explicitly asynchronous helps prevent bugs falls flat in the face of our existing parallelism.","accounts_in_message":[],"_revision_number":2},{"id":"a32776eb3e9d05ac36346aa04d0ca0415c9644f2","author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"date":"2015-02-17 17:40:38.000000000","message":"Patch Set 2:\n\nI can start a threading spec, I think I have at least some idea of what this would involve and IMHO it isn\u0027t that much, since the parts of openstack I know about are already running in some kind of worker pool, whether that worker pool comes from oslo.messaging or the service.py from the incubator; translating those eventlet workers to threads wouldn\u0027t seem that complicated, even if it does make some threading \u0026 concurrency issues show up in the end (better to fix these anyways right?).","accounts_in_message":[],"_revision_number":2},{"id":"012bd0562d5c3956afc2850ec9ba6e1801213fe8","author":{"_account_id":1849,"name":"Joe Gordon","email":"joe.gordon0@gmail.com","username":"jogo"},"date":"2015-02-17 18:57:21.000000000","message":"Patch Set 2: Code-Review-1\n\nJosh, a threading spec sounds like a good idea I like it.\n\nAs for this spec, I am not a fan due to all the reasons above.","accounts_in_message":[],"_revision_number":2},{"id":"41ef22314261e0519cc06a722ee0c6d48baaea86","author":{"_account_id":11816,"name":"mike bayer","display_name":"Mike Bayer","email":"mike_mp@zzzcomputing.com","username":"zzzeek","status":"Red Hat"},"date":"2015-02-17 19:04:37.000000000","message":"Patch Set 2:\n\nwith threads we can finally just stick with MySQL-Python for database access.  PyMySQL might be a good fit for pypy.","accounts_in_message":[],"_revision_number":2},{"id":"3d5d856a91a58ce13930cadfa52a9ffaa51a7389","author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"date":"2015-02-17 21:03:08.000000000","message":"Patch Set 2:\n\nOk I started, https://review.openstack.org/#/c/156711/ (be nice to it, haha) ;)","accounts_in_message":[],"_revision_number":2},{"id":"68944ddf9b781a0eef305fb3d06c37a170f55324","author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"date":"2015-02-18 21:58:53.000000000","message":"Uploaded patch set 3.","accounts_in_message":[],"_revision_number":3},{"id":"f2a10a16ebfbc0fc35897079140574c0fced9370","author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"date":"2015-02-18 22:02:23.000000000","message":"Patch Set 3:\n\nOk, I wrote a new version of the spec because I realized that many people misunderstood the purpose of replacing eventlet with asyncio. I wrote a long section to explain the specific race conditions avoided in the common case by asyncio. You may disagree, but at least I think that I better explained the rationale in the new version of the spec.\n\nThanks everyone for your feedback.","accounts_in_message":[],"_revision_number":3},{"id":"42ec6f17a42843889f50b8bd8ae58c582e34e097","author":{"_account_id":3,"name":"Jenkins","username":"jenkins"},"date":"2015-02-18 22:16:26.000000000","message":"Patch Set 3: Verified+1\n\nBuild succeeded (check pipeline).\n\n- gate-openstack-specs-docs http://docs-draft.openstack.org/98/153298/3/check/gate-openstack-specs-docs/2c226c3//doc/build/html/ : SUCCESS in 1m 57s","accounts_in_message":[],"_revision_number":3},{"id":"b703daf83b86c489611a2fbf73fbb13044837f52","author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"date":"2015-02-19 00:42:06.000000000","message":"Patch Set 3:\n\n(5 comments)","accounts_in_message":[],"_revision_number":3},{"id":"e6d7a2e93271c49edde5e38535c911a20f0763a0","author":{"_account_id":11816,"name":"mike bayer","display_name":"Mike Bayer","email":"mike_mp@zzzcomputing.com","username":"zzzeek","status":"Red Hat"},"date":"2015-02-19 02:13:06.000000000","message":"Patch Set 3:\n\n(4 comments)","accounts_in_message":[],"_revision_number":3},{"id":"f0c6f6e14eea85b65cf8c424d3dfc02545f0dfce","author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"date":"2015-02-19 07:06:43.000000000","message":"Patch Set 3:\n\n(1 comment)","accounts_in_message":[],"_revision_number":3},{"id":"94e180e69de9468f65990dfd4b3b232d6f8dd4e4","author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"date":"2015-02-19 07:08:18.000000000","message":"Patch Set 3:\n\n(1 comment)","accounts_in_message":[],"_revision_number":3},{"id":"dc08ad8cb2256333893c80a28a1e690614c5aee1","author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"date":"2015-02-19 15:09:14.000000000","message":"Patch Set 3:\n\n(5 comments)","accounts_in_message":[],"_revision_number":3},{"id":"ae6ff36cb1921444cb5b2202b56a5c95b9ca622d","author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"date":"2015-02-19 15:53:16.000000000","message":"Patch Set 3:\n\nDoug Hellmann wrote: \"My understanding is that asynchronous I/O techniques are usually applied where an application is I/O-bound on several inputs or outputs, or wants to work with many many sockets -- possibly more than the supported number of concurrent threads that could be managed reasonably (assuming the usual model of one thread per socket). Do we have any components that scale that way?\"\n\nBrett Slatkin wrote an interesting article: \"Python\u0027s asyncio is for composition, not raw performance\"\nhttp://www.onebigfluke.com/2015/02/asyncio-is-for-composition.html","accounts_in_message":[],"_revision_number":3},{"id":"47e3eff37b2864cfbf795280894258a1662e9c74","author":{"_account_id":11816,"name":"mike bayer","display_name":"Mike Bayer","email":"mike_mp@zzzcomputing.com","username":"zzzeek","status":"Red Hat"},"date":"2015-02-19 16:28:30.000000000","message":"Patch Set 3:\n\n(1 comment)","accounts_in_message":[],"_revision_number":3},{"id":"80e3f8d1de813f36d4f46ccdbd3599f56bdd803c","author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"date":"2015-02-19 18:26:14.000000000","message":"Patch Set 3:\n\n(1 comment)","accounts_in_message":[],"_revision_number":3},{"id":"0288a371c7fa190d80b5d2e30a76d84de09192fb","author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"date":"2015-02-20 09:32:33.000000000","message":"Patch Set 3:\n\nOh, I didn\u0027t notice that the gate builds an HTML version of the spec:\nhttp://docs-draft.openstack.org/98/153298/3/check/gate-openstack-specs-docs/2c226c3//doc/build/html/specs/asyncio.html","accounts_in_message":[],"_revision_number":3},{"id":"68ea57f261d361025ea78aefb6db4ac460167dbb","author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"date":"2015-02-20 12:46:20.000000000","message":"Patch Set 3: Code-Review-1\n\n(2 comments)\n\nI\u0027m okay with experimenting with this, and with ceilometer being the locus of the experimentation, but I think the scope needs to be more limited, or at least more phased. That way there can be more data about what\u0027s going on and the impact of the changes.\n\nOther comments within.","accounts_in_message":[],"_revision_number":3},{"id":"424a6d9412d1be6fa6e8b58891ab74889e119c3e","author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"date":"2015-02-20 13:19:59.000000000","message":"Patch Set 3:\n\n(1 comment)","accounts_in_message":[],"_revision_number":3},{"id":"f15f6e7bc2c220075398609d2f4cec7a9705f2c9","author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"date":"2015-02-20 13:49:42.000000000","message":"Patch Set 3:\n\n(1 comment)\n\nContinue to want small incremental change.","accounts_in_message":[],"_revision_number":3},{"id":"d5d2d88267490d14b0d4dc2b386f58a516ca5796","author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"date":"2015-02-20 15:22:04.000000000","message":"Patch Set 3:\n\n(1 comment)","accounts_in_message":[],"_revision_number":3},{"id":"95d16609bfa778df50ee4ee1abb090e1b4799dcc","author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"date":"2015-02-20 15:53:30.000000000","message":"Patch Set 3:\n\n(1 comment)","accounts_in_message":[],"_revision_number":3},{"id":"5817f59b7cac0b3770c378ec3be7ebe803ebfc23","author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"date":"2015-02-20 16:03:03.000000000","message":"Patch Set 3:\n\n\"In clear: I have no idea of the number of changes that are required to switch to asyncio :-)\"\n\nCool, I admire you for wanting to take on a task involving so much discovery. It\u0027s great.\n\nHowever, since you don\u0027t know what it\u0027s going to take all the more reason to keep the scope of the first goal constrained to one service (the notification agent) within ceilometer. Feel free to do it on a long running branch, I just want the branch that I\u0027m watching to be focused on a relatively small surface area.","accounts_in_message":[],"_revision_number":3},{"id":"763551fca13b9408057ff1b99407fdc35c8d1e0f","author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"date":"2015-02-23 14:02:17.000000000","message":"Patch Set 3:\n\n(1 comment)","accounts_in_message":[],"_revision_number":3},{"id":"49cfa9de55f75b86da6b7a21918c3077d725767c","author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"date":"2015-02-24 18:19:19.000000000","message":"Patch Set 3:\n\n(1 comment)","accounts_in_message":[],"_revision_number":3},{"id":"4999e8e5d7eb3f647314345ff9d40c4b44bef70c","author":{"_account_id":4190,"name":"lifeless","email":"robertc@robertcollins.net","username":"lifeless"},"date":"2015-02-25 03:19:27.000000000","message":"Patch Set 3: Code-Review-1\n\n(2 comments)\n\nSo, I\u0027m glad you\u0027ve written this up.\n\nIts not at all clear to me that the previous learning curve issues that broke the use of Twisted will be better with asyncio; further I think the issues with threaded code are being oversold: there are ways to write bad things in many contexts, but our code is primarily interacting with external resources - so local context, no in-process global state is the rule, not the exception.\n\nI like asyncio per se, and its in the Python space a fairly good approximation to communicating sequential processes, but something like https://code.google.com/p/pycsp/wiki/Getting_Started_With_PyCSP or http://goless.readthedocs.org/en/latest/ is perhaps more general and targetted directly at that design pattern (http://golang.org/doc/faq#csp) which is one of the selling points proponents of golang put forward.\n\nRight now our programming model is \u0027threads, with eventlet magic\u0027; if we\u0027re going to move off of that, I think genuine threads is the lowest sized delta, with anything explicit - CSP, asyncioor Twisted all being a larger delta.\n\nIn terms of choosing what framework / design we should aim for, Glyph\u0027s post about non-local reasoning is nice, but I think it ignores the fact that both Twisted and asyncio are very non-local in  nature - they both perform unsafe operations in-line with business logic, and that\u0027s a recipe for having weird-ass exceptions propogating up through fairly arbitrary code paths. Explicit CSP eases this, since rather than deep exceptions you have explicit layers between the processes. Of course, WSGI doesn\u0027t do a super job of supporting CSP, \n\nWith Python 3 support in eventlet now we don\u0027t have any particular urgency for revising things, but if we are changing things my preferences would be:\n - full blown CSP, probably through the goless library\n - regular threads / multiprocess\n - asyncio/trollius/twisted\n\nBecause:\n - (CSP \u003e asyncio) channels are really quite different to the coroutine approach asyncio uses (you can buffer, you can force a particular channel into one direction rather than bidirectional, you can select on multiple channels to get the next actual output whereas using iterators you have to suspend on just one at a time).\n - (CSP \u003e threads) CSP abstractions are more capable than threads (though we could in principle write shims - indeed, thats what goless gives you...)\n - (threads \u003e asyncio) our code is currently written in threaded style, and I don\u0027t think the benefits (though there are some indeed) from asyncio is worth a full-code-base rewrite. CSP offers enough on top of that to make it worth it IMNSHO.","accounts_in_message":[],"_revision_number":3},{"id":"c159531afe2597b306c79144c276f420ed950e6d","author":{"_account_id":308,"name":"Thierry Carrez","email":"thierry@openstack.org","username":"ttx"},"date":"2015-02-26 15:31:39.000000000","message":"Patch Set 3:\n\nIdeally this would merge with https://review.openstack.org/#/c/156711/ in a meta-spec to present a common overview of the problem, a list of potential solutions with their benefit and drawbacks -- then we can pick one option and have all the alternatives we rejected properly documented. That may avoid to come back to it next month.\n\nI\u0027d also like an assessment of the work required by each option, as well as some performance data (in the spirit of http://techspot.zzzeek.org/2015/02/15/asynchronous-python-and-databases/)","accounts_in_message":[],"_revision_number":3},{"id":"b60ac602983d5f8dc3ba42966f9a3c71ce92a28c","author":{"_account_id":4715,"name":"Angus Salkeld","email":"asalkeld@redhat.com","username":"asalkeld"},"date":"2015-03-04 00:02:02.000000000","message":"Patch Set 3: Code-Review-1\n\nbig +1 to what lifeless said! goless looks promising (very new project, but really small volume of code)","accounts_in_message":[],"_revision_number":3},{"id":"7d51abf483819cce87b5e40bb5f6e8e359a1a2d3","author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"date":"2015-04-30 14:59:06.000000000","message":"Abandoned\n\nReplaced with the meta-spec:\n\"Replace eventlet + monkey-patching with ??\"\nhttps://review.openstack.org/#/c/164035/","accounts_in_message":[],"_revision_number":3}],"current_revision_number":3,"current_revision":"9067443cc73f853beb222bb3de8115c3920d29b4","revisions":{"eda2755d948c0a71e87674620de565ad6d36da46":{"kind":"REWORK","_number":1,"created":"2015-02-05 17:06:51.000000000","uploader":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"ref":"refs/changes/98/153298/1","fetch":{"anonymous http":{"url":"https://review.opendev.org/openstack/openstack-specs","ref":"refs/changes/98/153298/1","commands":{"Checkout":"git fetch https://review.opendev.org/openstack/openstack-specs refs/changes/98/153298/1 \u0026\u0026 git checkout FETCH_HEAD","Cherry Pick":"git fetch https://review.opendev.org/openstack/openstack-specs refs/changes/98/153298/1 \u0026\u0026 git cherry-pick FETCH_HEAD","Format Patch":"git fetch https://review.opendev.org/openstack/openstack-specs refs/changes/98/153298/1 \u0026\u0026 git format-patch -1 --stdout FETCH_HEAD","Pull":"git pull https://review.opendev.org/openstack/openstack-specs refs/changes/98/153298/1"}}},"commit":{"parents":[{"commit":"c3be753672f4f697fab901302c51a368ff2b737f","subject":"Merge \"Log Guidelines\"","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/openstack-specs/commit/c3be753672f4f697fab901302c51a368ff2b737f"}]}],"author":{"name":"Victor Stinner","email":"victor.stinner@enovance.com","date":"2015-02-05 16:49:37.000000000","tz":60},"committer":{"name":"Victor Stinner","email":"victor.stinner@enovance.com","date":"2015-02-05 17:06:48.000000000","tz":60},"subject":"Reeplace eventlet with asyncio","message":"Reeplace eventlet with asyncio\n\nFirst draft.\n\nPart of bp:greenio-executor\n\nChange-Id: If00cda67a79c02aa3fbf413ba0105739567839c7\n","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/openstack-specs/commit/eda2755d948c0a71e87674620de565ad6d36da46"}],"resolve_conflicts_web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/openstack-specs/commit/eda2755d948c0a71e87674620de565ad6d36da46"}]},"branch":"refs/heads/master"},"0b29bf128ed8a710a4ba38c48c79c60a479bb989":{"kind":"REWORK","_number":2,"created":"2015-02-10 23:54:47.000000000","uploader":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"ref":"refs/changes/98/153298/2","fetch":{"anonymous http":{"url":"https://review.opendev.org/openstack/openstack-specs","ref":"refs/changes/98/153298/2","commands":{"Checkout":"git fetch https://review.opendev.org/openstack/openstack-specs refs/changes/98/153298/2 \u0026\u0026 git checkout FETCH_HEAD","Cherry Pick":"git fetch https://review.opendev.org/openstack/openstack-specs refs/changes/98/153298/2 \u0026\u0026 git cherry-pick FETCH_HEAD","Format Patch":"git fetch https://review.opendev.org/openstack/openstack-specs refs/changes/98/153298/2 \u0026\u0026 git format-patch -1 --stdout FETCH_HEAD","Pull":"git pull https://review.opendev.org/openstack/openstack-specs refs/changes/98/153298/2"}}},"commit":{"parents":[{"commit":"c3be753672f4f697fab901302c51a368ff2b737f","subject":"Merge \"Log Guidelines\"","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/openstack-specs/commit/c3be753672f4f697fab901302c51a368ff2b737f"}]}],"author":{"name":"Victor Stinner","email":"victor.stinner@enovance.com","date":"2015-02-05 16:49:37.000000000","tz":60},"committer":{"name":"Victor Stinner","email":"victor.stinner@enovance.com","date":"2015-02-10 23:54:34.000000000","tz":60},"subject":"Replace eventlet with asyncio","message":"Replace eventlet with asyncio\n\nPart of bp:greenio-executor\n\nChange-Id: If00cda67a79c02aa3fbf413ba0105739567839c7\n","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/openstack-specs/commit/0b29bf128ed8a710a4ba38c48c79c60a479bb989"}],"resolve_conflicts_web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/openstack-specs/commit/0b29bf128ed8a710a4ba38c48c79c60a479bb989"}]},"branch":"refs/heads/master"},"9067443cc73f853beb222bb3de8115c3920d29b4":{"kind":"REWORK","_number":3,"created":"2015-02-18 21:58:53.000000000","uploader":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"ref":"refs/changes/98/153298/3","fetch":{"anonymous http":{"url":"https://review.opendev.org/openstack/openstack-specs","ref":"refs/changes/98/153298/3","commands":{"Checkout":"git fetch https://review.opendev.org/openstack/openstack-specs refs/changes/98/153298/3 \u0026\u0026 git checkout FETCH_HEAD","Cherry Pick":"git fetch https://review.opendev.org/openstack/openstack-specs refs/changes/98/153298/3 \u0026\u0026 git cherry-pick FETCH_HEAD","Format Patch":"git fetch https://review.opendev.org/openstack/openstack-specs refs/changes/98/153298/3 \u0026\u0026 git format-patch -1 --stdout FETCH_HEAD","Pull":"git pull https://review.opendev.org/openstack/openstack-specs refs/changes/98/153298/3"}}},"commit":{"parents":[{"commit":"c3be753672f4f697fab901302c51a368ff2b737f","subject":"Merge \"Log Guidelines\"","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/openstack-specs/commit/c3be753672f4f697fab901302c51a368ff2b737f"}]}],"author":{"name":"Victor Stinner","email":"victor.stinner@enovance.com","date":"2015-02-05 16:49:37.000000000","tz":60},"committer":{"name":"Victor Stinner","email":"victor.stinner@enovance.com","date":"2015-02-18 21:58:17.000000000","tz":60},"subject":"Replace eventlet with asyncio","message":"Replace eventlet with asyncio\n\nPart of bp:greenio-executor\n\nChange-Id: If00cda67a79c02aa3fbf413ba0105739567839c7\n","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/openstack-specs/commit/9067443cc73f853beb222bb3de8115c3920d29b4"}],"resolve_conflicts_web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/openstack-specs/commit/9067443cc73f853beb222bb3de8115c3920d29b4"}]},"branch":"refs/heads/master"}},"requirements":[],"submit_records":[],"submit_requirements":[]}
