governance/a0d828ea7ad58f7e0102bb91da9...

1180 lines
70 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"comments": [
{
"unresolved": true,
"key": {
"uuid": "3b0cd8d9_4dc55183",
"filename": "/PATCHSET_LEVEL",
"patchSetId": 14
},
"lineNbr": 0,
"author": {
"id": 28522
},
"writtenOn": "2023-12-22T15:53:22Z",
"side": 1,
"message": "@Sean: I\u0027ll address your comments early in 2024. I\u0027m on PTO during the two next weeks, so I won\u0027t be online, and I won\u0027t update this patch during this period.\n\nI need more reflexion about your proposal, in order to draft something clear.",
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": false,
"key": {
"uuid": "2ebfbe94_b0b29397",
"filename": "/PATCHSET_LEVEL",
"patchSetId": 14
},
"lineNbr": 0,
"author": {
"id": 27615
},
"writtenOn": "2023-12-26T15:23:30Z",
"side": 1,
"message": "Great work Herve to get this effort started. Although i understand it isn\u0027t possible to lay out all the details of the migration here, it would really help if we get a document lining out a step by step procedure that would make the task of every service migration easier. Thanks!",
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": false,
"key": {
"uuid": "3c03c38c_088d498e",
"filename": "/PATCHSET_LEVEL",
"patchSetId": 14
},
"lineNbr": 0,
"author": {
"id": 8313
},
"writtenOn": "2024-01-10T19:49:57Z",
"side": 1,
"message": "Thanks, just a few nits, which not require new patch I think",
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": false,
"key": {
"uuid": "d3dc6143_db0a6842",
"filename": "/PATCHSET_LEVEL",
"patchSetId": 14
},
"lineNbr": 0,
"author": {
"id": 4393
},
"writtenOn": "2024-01-11T17:29:57Z",
"side": 1,
"message": "I\u0027m definitely concerned with everything past the \"short term\" section and am definitely not going to be RC+2 until we\u0027ve had a much more thorough conversation about this in a higher-bandwidth forum. I\u0027m fully on board with \"we have to do something\" but I\u0027m not sure moving to a different async model is the best for us at this point in our lifecycle. I\u0027m *definitely* concerned that we\u0027ll head down this path and never finish (like many of our much smaller migrations in the past) leaving us in a potentially worse situation than just maintaining another library and/or moving to native threads...",
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": false,
"key": {
"uuid": "ee539101_7f12bac0",
"filename": "/PATCHSET_LEVEL",
"patchSetId": 14
},
"lineNbr": 0,
"author": {
"id": 28522
},
"writtenOn": "2024-02-21T09:57:47Z",
"side": 1,
"message": "Done",
"parentUuid": "3b0cd8d9_4dc55183",
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": true,
"key": {
"uuid": "e863b629_d0529291",
"filename": "goals/proposed/modernize-openstack-async-model.rst",
"patchSetId": 14
},
"lineNbr": 173,
"author": {
"id": 4393
},
"writtenOn": "2024-01-11T17:29:57Z",
"side": 1,
"message": "Moving away from eventlet doesn\u0027t necessarily mean a move to asyncio, IMHO. Since the point of eventlet is to provide a native threads experience with green threads underneath, I feel like moving to native threads is less of a change. It\u0027s something that *can* be done incrementally and also provides potential for performance improvement for areas of the code that already would benefit from actual parallelism.\n\nIn short, just because python\u0027s choice of async programming model is asyncio doesn\u0027t mean we need to move to it, IMHO.",
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": true,
"key": {
"uuid": "0077c369_041e8ca3",
"filename": "goals/proposed/modernize-openstack-async-model.rst",
"patchSetId": 14
},
"lineNbr": 173,
"author": {
"id": 597
},
"writtenOn": "2024-01-11T20:12:23Z",
"side": 1,
"message": "We will also have to decide upon the webserver if we move to asyncio, be it aiohttp, aiowsgi, or something else. Swift in particular runs outside of Apache often, even predominantly.",
"parentUuid": "e863b629_d0529291",
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": true,
"key": {
"uuid": "fb6af254_727ef8ab",
"filename": "goals/proposed/modernize-openstack-async-model.rst",
"patchSetId": 14
},
"lineNbr": 173,
"author": {
"id": 10342
},
"writtenOn": "2024-01-16T16:49:34Z",
"side": 1,
"message": "While this is true, I think it\u0027s useful to identify a framework for OpenStack projects to use moving forward, if not eventlet. Even if that is \"just use natvie threads\" (I suspect this may not be sufficient for all use cases).\n\nI would think a major failure of this initiative would be if multiple OpenStack projects are using different approaches to this problemset after a project to sunset use of eventlet.",
"parentUuid": "0077c369_041e8ca3",
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": true,
"key": {
"uuid": "4b0f680b_b5a0be2d",
"filename": "goals/proposed/modernize-openstack-async-model.rst",
"patchSetId": 14
},
"lineNbr": 173,
"author": {
"id": 4393
},
"writtenOn": "2024-01-18T15:15:59Z",
"side": 1,
"message": "I don\u0027t think we need to come up with a single replacement technology for eventlet across the board. We already have projects using different things for WSGI frameworks or task management. The fact that we\u0027re \"all using eventlet\" isn\u0027t even really accurate. Since the eventlet programming model is identical to native threads, it is/was a fairly easy sell for people. Asyncio itself is very different (from eventlet, from native threads, and really anything else), and even with a wrapper around it that makes it \"look more normal\", is quite a bit more polarizing.\n\nI think this is my primary concern here - that we not assume everything that is eventlet today must be converted to a single solution as a community. For eventlet haters (I\u0027m not an eventlet lover by any means), the fact that eventlet is a pseudo-default in our community is not a good thing. As I note below, some projects (and/or services in those projects) aren\u0027t even dependent on eventlet today. Moving them to proper asyncio-native code is a very big change that effectively keeps them tied to asyncio at a syntax level.",
"parentUuid": "fb6af254_727ef8ab",
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": true,
"key": {
"uuid": "54d8aa55_54f1ad11",
"filename": "goals/proposed/modernize-openstack-async-model.rst",
"patchSetId": 14
},
"lineNbr": 173,
"author": {
"id": 11604
},
"writtenOn": "2024-01-18T19:53:50Z",
"side": 1,
"message": "the main caveat i would say is while we dont need to have a single implementation across all of opensstack we need need compatiblity within the common libs and withing a given project.\n\ni.e. we woudl need the share code to supprot being used from an async eventloop (async def funtions) or just with native threads.\n\nrather then using raw thread directly i think nova would likely continue to use futureist executors with the threadpool executor in the event we dont ues syncio/trio/anyio \n\nif we were ot use any of the async framewroks above i would use anyio personally as it provides trio\u0027s api/taskgroup (now in python 3.11) on asyncio on py3.8 +\n\nbut the first place i tried to use anyio/asyncio i realliese without a async rest client i really needed to use thread pool instead so ... i kidn of agree that one size proably does not fit all in this regard.\n\nwe are fortunet that sqlachemy supprots asyncio and or async frameworks but we also need to be carful with our other external deps\n\nnot all will but perhaps we can look at how they approch this for some pointers.\nhttps://docs.sqlalchemy.org/en/20/orm/extensions/asyncio.html\nhttps://github.com/sqlalchemy/sqlalchemy/tree/main/lib/sqlalchemy/ext/asyncio\nhttps://gist.github.com/zzzeek/6287e28054d3baddc07fa21a7227904e\n\nif we want to make progress on this we need an approch that crosses the blue/green fucntion devied.\nhttps://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function/",
"parentUuid": "4b0f680b_b5a0be2d",
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": true,
"key": {
"uuid": "6d81bc29_80f62789",
"filename": "goals/proposed/modernize-openstack-async-model.rst",
"patchSetId": 14
},
"lineNbr": 173,
"author": {
"id": 28522
},
"writtenOn": "2024-01-23T14:36:48Z",
"side": 1,
"message": "In a perfect world, I\u0027d prefer an unified approach. An approach retained by all Openstack deliverables. An approach that fit all scenario. Unfortunatelly, we are not living in a perfect world, and, I think that, comments from Sean and Dan, reflects the complexity of this topic and the lack of clarity within this proposal.\n\nWe are facing an emergency, i.e the non-sustainable maintainability of eventlet. However, the proposal as currently formulated is poorly worded. I think that Sean and Dan concerns are relevant and legit. The title of this proposal well justifies their concerns.\n\nWithout these considerations, we would introduce changes that will lead us to reinvent the wheel for every Openstack component. That\u0027s not the goal of this proposal.\n\nThis proposal was implicitly focused on Openstack deliverables that relies on Eventlet. With potential unforseen side effects, thanks Sean and Dan for your thoughts. That\u0027s why, no matter the context, implicit is a bad idea...\n\nThis proposal should simply advocate to move away from eventlet, rather than, advocate for a new \"Openstack Networking Programming Model\".\n\nAgain, our goal is to respond to the emergency that arises, i.e the growing gaps between Eventlet and CPython.\n\nAFAIK, on Openstack, Eventlet is mostly used to allow async things. So replacing eventlet mean, we need a replacent for async features. Asyncio is designed for that usage. Hence, this proposal advocate to use Asyncio as replacent for Eventlet. This proposal won\u0027t propose any other alternatives.\n\nHowever, as I suggested in my other comment, this proposal needs adjustements [1]:\n\n* this proposal should encourage the migration of common libs toward Asyncio but by offering synchronous facade, to avoid contamination of higher level components, deliverables that do not rely on eventlet, by the Asyncio model.\n* this proposal should ONLY encourage the migration of services that relies on eventlet and advocate for an asyncio approach.\n\nOther approaches exists (threading etc). If someone volunteer to advocate and document a different approach, then that\u0027s not a problem, that will offer other alternatives to services developers. I think, they should be discussed in a separated thread, thoughs. Services maintainers would be able to weight pros and cons of proposed approaches and then decide then one to use. However, IMO, this proposal should only focus on proposing the Asyncio approach. An approach to replace async functionalities poorly maintained by async functionalities who are long term maintained. With the adjustments listed here [1].\n\n[1] https://review.opendev.org/c/openstack/governance/+/902585/comment/d6f0ae46_f505ea4f/",
"parentUuid": "54d8aa55_54f1ad11",
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": false,
"key": {
"uuid": "5e1f25cc_b69d7eed",
"filename": "goals/proposed/modernize-openstack-async-model.rst",
"patchSetId": 14
},
"lineNbr": 173,
"author": {
"id": 28522
},
"writtenOn": "2024-02-21T09:57:47Z",
"side": 1,
"message": "Done",
"parentUuid": "6d81bc29_80f62789",
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": true,
"key": {
"uuid": "116f2c36_51a9c65e",
"filename": "goals/proposed/modernize-openstack-async-model.rst",
"patchSetId": 14
},
"lineNbr": 220,
"author": {
"id": 27615
},
"writtenOn": "2023-12-26T15:23:30Z",
"side": 1,
"message": "nit: whitespace",
"range": {
"startLine": 220,
"startChar": 73,
"endLine": 220,
"endChar": 74
},
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": false,
"key": {
"uuid": "a77cd8d1_bc987914",
"filename": "goals/proposed/modernize-openstack-async-model.rst",
"patchSetId": 14
},
"lineNbr": 220,
"author": {
"id": 28522
},
"writtenOn": "2024-02-21T09:57:47Z",
"side": 1,
"message": "Done",
"parentUuid": "116f2c36_51a9c65e",
"range": {
"startLine": 220,
"startChar": 73,
"endLine": 220,
"endChar": 74
},
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": true,
"key": {
"uuid": "be27198d_b38fbd80",
"filename": "goals/proposed/modernize-openstack-async-model.rst",
"patchSetId": 14
},
"lineNbr": 223,
"author": {
"id": 8313
},
"writtenOn": "2024-01-10T19:49:57Z",
"side": 1,
"message": "This should be * to be a list I think (in the rendered html it is not a list for sure)",
"range": {
"startLine": 223,
"startChar": 0,
"endLine": 223,
"endChar": 1
},
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": true,
"key": {
"uuid": "a043a7be_1fd255c3",
"filename": "goals/proposed/modernize-openstack-async-model.rst",
"patchSetId": 14
},
"lineNbr": 223,
"author": {
"id": 10342
},
"writtenOn": "2024-01-16T16:49:34Z",
"side": 1,
"message": "To make it render as a list, I think you\u0027ll need two spaces before the -",
"parentUuid": "be27198d_b38fbd80",
"range": {
"startLine": 223,
"startChar": 0,
"endLine": 223,
"endChar": 1
},
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": false,
"key": {
"uuid": "d9fc50c3_840d09a2",
"filename": "goals/proposed/modernize-openstack-async-model.rst",
"patchSetId": 14
},
"lineNbr": 223,
"author": {
"id": 28522
},
"writtenOn": "2024-02-21T09:57:47Z",
"side": 1,
"message": "Done",
"parentUuid": "a043a7be_1fd255c3",
"range": {
"startLine": 223,
"startChar": 0,
"endLine": 223,
"endChar": 1
},
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": true,
"key": {
"uuid": "938219e2_8187e7cd",
"filename": "goals/proposed/modernize-openstack-async-model.rst",
"patchSetId": 14
},
"lineNbr": 270,
"author": {
"id": 8313
},
"writtenOn": "2024-01-10T19:49:57Z",
"side": 1,
"message": "nit: usp\u003dsearch is not necessary for the link (just some gerrit anchor)",
"range": {
"startLine": 270,
"startChar": 65,
"endLine": 270,
"endChar": 76
},
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": false,
"key": {
"uuid": "db00322e_22f04ad8",
"filename": "goals/proposed/modernize-openstack-async-model.rst",
"patchSetId": 14
},
"lineNbr": 270,
"author": {
"id": 28522
},
"writtenOn": "2024-02-21T09:57:47Z",
"side": 1,
"message": "Done",
"parentUuid": "938219e2_8187e7cd",
"range": {
"startLine": 270,
"startChar": 65,
"endLine": 270,
"endChar": 76
},
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": true,
"key": {
"uuid": "f4e4bc67_85b8806e",
"filename": "goals/proposed/modernize-openstack-async-model.rst",
"patchSetId": 14
},
"lineNbr": 272,
"author": {
"id": 8313
},
"writtenOn": "2024-01-10T19:49:57Z",
"side": 1,
"message": "shall we have periodic jobs in the main projects to test with eventlet master (or do we have alredy, like for sqlalchemy?)",
"range": {
"startLine": 272,
"startChar": 3,
"endLine": 272,
"endChar": 47
},
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": true,
"key": {
"uuid": "26c824f1_d58976f6",
"filename": "goals/proposed/modernize-openstack-async-model.rst",
"patchSetId": 14
},
"lineNbr": 272,
"author": {
"id": 28522
},
"writtenOn": "2024-01-26T10:13:13Z",
"side": 1,
"message": "IMO that can\u0027t hurt. Please can you point me where I can find the sqlalchemy periodic jobs? I\u0027m not sure.",
"parentUuid": "f4e4bc67_85b8806e",
"range": {
"startLine": 272,
"startChar": 3,
"endLine": 272,
"endChar": 47
},
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": true,
"key": {
"uuid": "c811e88d_58bc82d4",
"filename": "goals/proposed/modernize-openstack-async-model.rst",
"patchSetId": 14
},
"lineNbr": 280,
"author": {
"id": 11604
},
"writtenOn": "2024-01-10T20:21:54Z",
"side": 1,
"message": "so python 3.12 wont be officaly supproted in caracal regardels of if we merge this\n\nunoffially i hope the eventlet changes cna make it work but we select our suported testing runtime at the start of each cycle and 3.12 is not on that list for caracal.\n\nhttps://github.com/openstack/governance/blob/master/reference/runtimes/2024.1.rst\n\nso the first realeast that would have 3.12 as a testing runtim will be the D cycle.",
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": false,
"key": {
"uuid": "c60750cf_4bd15ca5",
"filename": "goals/proposed/modernize-openstack-async-model.rst",
"patchSetId": 14
},
"lineNbr": 280,
"author": {
"id": 28522
},
"writtenOn": "2024-01-26T10:13:13Z",
"side": 1,
"message": "Yes, our runtimes for Caracal are already set and runtimes are set at the start of each cycle. This sentence is related to 2024.2/dalmatian \"Decide with the TC to postpone the support of Python 3.12 within the next series (\"D\")\"",
"parentUuid": "c811e88d_58bc82d4",
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": true,
"key": {
"uuid": "35bbce15_77af9117",
"filename": "goals/proposed/modernize-openstack-async-model.rst",
"patchSetId": 14
},
"lineNbr": 323,
"author": {
"id": 8313
},
"writtenOn": "2024-01-10T19:49:57Z",
"side": 1,
"message": "nit: 2024.1",
"range": {
"startLine": 323,
"startChar": 6,
"endLine": 323,
"endChar": 8
},
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": true,
"key": {
"uuid": "a6a3597b_071f07bf",
"filename": "goals/proposed/modernize-openstack-async-model.rst",
"patchSetId": 14
},
"lineNbr": 323,
"author": {
"id": 28522
},
"writtenOn": "2024-01-26T10:13:13Z",
"side": 1,
"message": "Dalmatian \u003d 2024.2",
"parentUuid": "35bbce15_77af9117",
"range": {
"startLine": 323,
"startChar": 6,
"endLine": 323,
"endChar": 8
},
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": false,
"key": {
"uuid": "a9293321_bfb36939",
"filename": "goals/proposed/modernize-openstack-async-model.rst",
"patchSetId": 14
},
"lineNbr": 323,
"author": {
"id": 28522
},
"writtenOn": "2024-02-21T09:57:47Z",
"side": 1,
"message": "Done",
"parentUuid": "a6a3597b_071f07bf",
"range": {
"startLine": 323,
"startChar": 6,
"endLine": 323,
"endChar": 8
},
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": true,
"key": {
"uuid": "ab21f5b5_adf489e3",
"filename": "goals/proposed/modernize-openstack-async-model.rst",
"patchSetId": 14
},
"lineNbr": 324,
"author": {
"id": 8313
},
"writtenOn": "2024-01-10T19:49:57Z",
"side": 1,
"message": "nit:2025.1",
"range": {
"startLine": 324,
"startChar": 54,
"endLine": 324,
"endChar": 59
},
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": false,
"key": {
"uuid": "95f5a9f3_2db09e72",
"filename": "goals/proposed/modernize-openstack-async-model.rst",
"patchSetId": 14
},
"lineNbr": 324,
"author": {
"id": 28522
},
"writtenOn": "2024-02-21T09:57:47Z",
"side": 1,
"message": "Done",
"parentUuid": "ab21f5b5_adf489e3",
"range": {
"startLine": 324,
"startChar": 54,
"endLine": 324,
"endChar": 59
},
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": true,
"key": {
"uuid": "d94bc911_a735d166",
"filename": "goals/proposed/modernize-openstack-async-model.rst",
"patchSetId": 14
},
"lineNbr": 337,
"author": {
"id": 4393
},
"writtenOn": "2024-01-11T17:29:57Z",
"side": 1,
"message": "Maybe I\u0027m missing something, but purely replacing the eventlet hub with asyncio in the background is a major change to how a service that depends on this works. Right now, we are able to tightly interleave things we pretend are parallel (but aren\u0027t) because of the monkeypatching. By just moving the dispatching to asyncio but still considering each thing a monolithic non-async operation, our actual concurrency will go from reasonably fine-grained today (i.e. from yields injected in the monkeypatches) to extremely coarse-grained, no?\n\nIf, as described in the above discussion page, we hand-edit every call we need to make to an otherwise-blocking API, we\u0027ll have moved to using asyncio for the actual switching, but without moving any of our actual code to async routines, which will then require another re-write after we\u0027re ready to move on. It seems to me like if we move to using real threads, the immediate and future programming models are the same, and the only thing we need to work through is making sure that our locking in critical code is corrent, where now we\u0027re getting some isolation due to the lack of switches.",
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": true,
"key": {
"uuid": "3935ded4_4c3a0194",
"filename": "goals/proposed/modernize-openstack-async-model.rst",
"patchSetId": 14
},
"lineNbr": 337,
"author": {
"id": 36603
},
"writtenOn": "2024-01-17T21:00:46Z",
"side": 1,
"message": "## Threads lose a key capability vs eventlet\n\nThe problem with real threads is that it\u0027s very difficult to make robust software with blocking APIs. Moving from eventlet to normal threaded blocking APIs loses the ability to have high-level timeouts and high-level cancellation, which tend to be pretty important when writing a distributed system!\n\nAll of these problems are solved, or much more solvable, with an async event loop.\n\n### 1. Timeouts may not be available\n\nTimeouts are at the discretion of the library you\u0027re using. If they didn\u0027t provide them, you\u0027re stuck with potentially infinite blocking.\n\n### 2. Even when available, timeouts are typically at the wrong granularity\n\nConsider an HTTP request; the timeout you want is usually \"the whole operation didn\u0027t finish within N seconds.\" A blocking library cannot provide this without significant difficulty, so typically it won\u0027t. Thus `requests` provides timeouts on connecting, and a timeout on _individual reads_, but there\u0027s no way to say \"the whole request didn\u0027t finish after 10 seconds, cancel it.\"\n\n### 3. Cancellation is not possible\n\nIf an API is blocking... that\u0027s it, you\u0027re stuck. You can\u0027t kill a thread, you can\u0027t cancel an operation.\n\n## eventlet and asyncio are essentially the same model\n\nReferring to:\n\n\u003e Right now, we are able to tightly interleave things we pretend are parallel (but aren\u0027t) because of the monkeypatching. By just moving the dispatching to asyncio but still considering each thing a monolithic non-async operation, our actual concurrency will go from reasonably fine-grained today (i.e. from yields injected in the monkeypatches) to extremely coarse-grained, no?\n\nEventlet essentially gives you context switching on things like socket reads, socket writes, socket connects, and scheduled events/sleeps, with the massive caveat that this only applies to places that got monkeypatched. Not everything got monkeypatched so for some third-party libraries you\u0027re out of lock...\n\nAsyncio gives you the exact same context switching locations.\n\n## How porting would work\n\nReferring to:\n\n\u003e If, as described in the above discussion page, we hand-edit every call we need to make to an otherwise-blocking API, we\u0027ll have moved to using asyncio for the actual switching, but without moving any of our actual code to async routines, which will then require another re-write after we\u0027re ready to move on.\n\nA port to asyncio would therefore involve:\n\n1. Switching all networking functions to be Python `async` functions.\n2. Add an `await` on all places where pretending-to-block happened. This means places where undesired _real_ blocking happened become much more obvious.\n3. Switch from \"we monkeypatched this into pseudo-blocking\" APIs to async APIs (e.g. `urllib`/`requests` to `aiohttp`.)\n\nEventlet now has initial APIs for mixing Eventlet and `asyncio` code in the same library/application, so this can be a gradual process. It does not require two passes.",
"parentUuid": "d94bc911_a735d166",
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": true,
"key": {
"uuid": "3989d0ab_43953bc6",
"filename": "goals/proposed/modernize-openstack-async-model.rst",
"patchSetId": 14
},
"lineNbr": 337,
"author": {
"id": 36603
},
"writtenOn": "2024-01-17T21:05:23Z",
"side": 1,
"message": "Hm, no editing capabilities. To clarify, the three bullet points under the first heading refer to problems with pure blocking APIs. And I meant to say \"out of luck\", not \"out of lock\" 😊",
"parentUuid": "3935ded4_4c3a0194",
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": true,
"key": {
"uuid": "cae5b3d5_8674a0c4",
"filename": "goals/proposed/modernize-openstack-async-model.rst",
"patchSetId": 14
},
"lineNbr": 337,
"author": {
"id": 36603
},
"writtenOn": "2024-01-17T21:22:02Z",
"side": 1,
"message": "## Migrating from eventlet to regular threads requires addressing thread safety\n\nEventlet is essentially running as a single thread, so problems of thread safety are much more limited. So long as you don\u0027t call a function that causes a context switch to another greenlet, only one thread is running. So for example data structures can be mutated safely without worrying about locking. \n\nMigrating to blocking threads would involve auditing all code for places that are potentially not thread-safe, and adding locking (while avoiding deadlocks). This is possible, of course; I can\u0027t speak to how much work it would be compared to an asyncio migration, but it is work that will need to be done.",
"parentUuid": "3989d0ab_43953bc6",
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": true,
"key": {
"uuid": "1fa9775a_e3ffdc32",
"filename": "goals/proposed/modernize-openstack-async-model.rst",
"patchSetId": 14
},
"lineNbr": 337,
"author": {
"id": 11604
},
"writtenOn": "2024-01-17T21:39:27Z",
"side": 1,
"message": "there is a key diffent between eventlet and asyncio with regards to the model\n\none is implict the other is explcity\n\ncurrently every io (http request, unix socket read/write, file io) or process spawn like calling oslo process ustils even privsep calls are an implict yeild to the eventloop\n\nif nothing is pending that as if we blocked but if other eventlets need to run we get concuancy while waiting.\n\nnow the actual concurrency is the same in that we are using userland coperative mulit thread but the mechaium by which that happens is very diffent.\n\nwith wregards to thirdpary libs and what get monkey patched.\n\nwe monkey patch very very early to ensure that modules are moneky patched before any third party libs are imported.\n\nthat should mean that unless that lib has explcit code to detect eventlets, and un monkey patch its locally copy of the std lib moduels we can expect all third party libs to be un in a monkey patched context. if the third party lib spwans a thread via the threading module for example that will be monkey patched.\n\n\nwith asyncio we would have to manually wrap all blockign api calls to use a future adn dispatch it to a thread pool then await the future or we would have to similarly swap form the blocking api to a non blockign api.\n\nwhat that means in practic is in codebases that have to supprot both models\nwe need to build a libary of wrapper code that can work correctly with or without eventlest in use to make sure our code works in both modles.\n\nthis is complciated by the fact that you cant call \"async def\" fucntions form a non \"asycn def\" function so we have to keep declaring the function with the \nnon async sysntax and return a future/awaiable instead.\n\n\nthat means doign things like this \nhttps://review.opendev.org/c/openstack/nova/+/904425/10/nova/context.py\n\nthat ^ is also not providing concurrancy.\nnote the comment inlien, because it was using the oepsntack sdk and request \nthe async def gather_result fucntion woudl actully block the main loop\n\nso we would need to first port the OpenStack SDK to provide async_def fucntions for all the api (perhaps using aiohttp instead of requests) and then swap between \nwhich openstack sdk client method we use based on if its eventlet or not.\n\n\none approch that might work to enabel a migration is what dan was saying.\n\nin the core of our service eventlopp we can have a singel thread pooling for rpc messages. when it recives one it can spwan the request handleing into an thread pool, each request to the service and then run in a blocking manner in the thread.\n\nthat will reulst in very course granulatiy which can be refiend using seperate async io eventloops within those treads as we migrate but that will increase memroy usage and while the gil extis will be less performant then usign eventlest today.",
"parentUuid": "3989d0ab_43953bc6",
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": true,
"key": {
"uuid": "c64ed701_9cd1bfee",
"filename": "goals/proposed/modernize-openstack-async-model.rst",
"patchSetId": 14
},
"lineNbr": 337,
"author": {
"id": 11604
},
"writtenOn": "2024-01-17T21:42:29Z",
"side": 1,
"message": "\"Migrating from eventlet to regular threads requires addressing thread safety\"\n\nthat a fundemental misunderstading of how eventlest works\n\neventlet code already has to be written in a thread safe manner with locks and explcit scynoistation as the implict context swtiching can cause the same race condtions as real thread.\n\nany eventlet code that is not thread safe is also not eventlet safe in general.\n\nso movign to explcit treading is less work then moving to asyncio",
"parentUuid": "1fa9775a_e3ffdc32",
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": true,
"key": {
"uuid": "b1ce7b3f_43530ac5",
"filename": "goals/proposed/modernize-openstack-async-model.rst",
"patchSetId": 14
},
"lineNbr": 337,
"author": {
"id": 36603
},
"writtenOn": "2024-01-18T13:31:45Z",
"side": 1,
"message": "## Locking\n\nAnything like this would not need locks in eventlet:\n\n```\nclass Counter:\n def increment(self):\n self.x +\u003d 1\n```\n\nBut would need locks with blocking threads. It\u0027s possible that the OpenStack codebase has enough discipline to already add locking everywhere pure data structure manipulation is susceptible to race conditions, but I\u0027m skeptical.\n\nSee my comments elsewhere re the problem with blocking APIs as regards timeouts.\n\nMore broadly: I don\u0027t think the question is purely about what is easiest; switching to blocking+normal threading is definitely easiest. It\u0027s about what will result in robust, functioning software at the end of the process. An easy transition to buggy software isn\u0027t very helpful. So there\u0027s a need to think about sources of bugs as well.\n\n## Asyncio\n\nAgain, to be clear, the proposal is that asyncio and eventlet can call each other directly. It\u0027s not a giant switch you turn on one day, it\u0027s a gradual migration and in the short term you can have a mixture both. So you don\u0027t need if statements, you just use transformation APIs.\n\nhttps://github.com/eventlet/eventlet/blob/ddb29e09fe0d8e5e4e52d3065f62e63f910f3ef9/doc/source/migration.rst#step-2-migrate-code-to-asyncio has some examples.",
"parentUuid": "c64ed701_9cd1bfee",
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": true,
"key": {
"uuid": "b0b9f227_fc98c7d5",
"filename": "goals/proposed/modernize-openstack-async-model.rst",
"patchSetId": 14
},
"lineNbr": 337,
"author": {
"id": 4393
},
"writtenOn": "2024-01-18T15:15:59Z",
"side": 1,
"message": "\u003e If an API is blocking... that\u0027s it, you\u0027re stuck. You can\u0027t kill a thread, you can\u0027t cancel an operation.\n\nI think your point here is really that asyncio/eventlet make it easier to leak stuck threads, not that threads no longer get stuck. Delegating something synchronous we have no control over to a worker thread is still the same model. We may be able to stop waiting for it, but the result is really the same under the covers.\n\n\u003e Asyncio gives you the exact same context switching locations.\n\nBut not natively, right? Asyncio gives you the same ability to delegate things to worker threads and wait/yield while it runs, but without monkeypatching calls to synchronous calls, I don\u0027t see how this doesn\u0027t involve an additional layer. Perhaps eventlet in asyncio-compat mode is that layer for the time being, but that doesn\u0027t really help us get off eventlet.\n\nSean\u0027s point about `async def` methods is exactly my point about the second step of actually cleaning things up. If we assume everything that currently appears to be synchronous stays that way, then we\u0027re forever in the situation where we only yield when we explicitly delegate a subroutine call to a worker thread until we have `async def`\u0027d everything up the stack. That\u0027s a much worse place to be in than we are today, IMHO.\n\nI\u0027d also like to point out that python has been on a breaking-things streak lately unlike anything we\u0027ve seen. They have deprecated and removed things in asyncio since the start of python3 (in fact asyncio code looks a lot different now than it did in the earlier versions). Not only is async code in python incompatible (without work) with regular synchronous code, but moving code _syntax_ to that mechanism also invites (IMHO) more potential for \"oh well, python 3.20 has removed `async def` in favor of `def async`, time to change all the code again\" sorts of liabilities.\n\n\u003e Anything like this would not need locks in eventlet:\n\nPlease don\u0027t assume that we\u0027re ignorant about eventlet and how it works. Sean is right that any code that is not native-thread safe today isn\u0027t safe under eventlet either. There are probably plenty of places where we\u0027re not thread safe and don\u0027t realize it because of how coarse the thread switching is with eventlet. However, if we start wrapping synchronous code in thread workers with asyncio, we\u0027re going to expose the same thread safety things as if we were running things in native threads ourselves, AFAIK. I think it\u0027s important to keep in mind that any change we make here is going to be destabilizing and require a lot more verification. Just saying \"meh, they\u0027re the same model\" is way too naive for a system as complicated as this, IMHO.",
"parentUuid": "b1ce7b3f_43530ac5",
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": true,
"key": {
"uuid": "65b9fde3_80f23a73",
"filename": "goals/proposed/modernize-openstack-async-model.rst",
"patchSetId": 14
},
"lineNbr": 337,
"author": {
"id": 11604
},
"writtenOn": "2024-01-18T19:53:50Z",
"side": 1,
"message": "here are just some of the exampel of the exisign lock we have to maintain in nvoa with eventltets\n\nhttps://codesearch.opendev.org/?q\u003dutils.synchronized\u0026i\u003dnope\u0026literal\u003dnope\u0026files\u003d.py\u0026excludeFiles\u003dtest\u0026repos\u003dopenstack%2Fnova\n\neach of those @utils.synchronized decorators are creating a file to ack as a lock when we are perfoaming operatios that cannot happen conncurently either on an instance or on our shared memory datastucrue liek the resouce tracker.\n\nany time we have a share datastucre in memory or we preform operatoins on the hypervier liek addding a prot to a vm we need to lock to prevent concurrent rpc calls or perodic tasks that get interleaved form currpting the shared state.",
"parentUuid": "b0b9f227_fc98c7d5",
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": true,
"key": {
"uuid": "6d447ed3_bacc9927",
"filename": "goals/proposed/modernize-openstack-async-model.rst",
"patchSetId": 14
},
"lineNbr": 337,
"author": {
"id": 36603
},
"writtenOn": "2024-01-19T14:37:34Z",
"side": 1,
"message": "\u003e I think your point here is really that asyncio/eventlet make it easier to leak stuck threads, not that threads no longer get stuck. Delegating something synchronous we have no control over to a worker thread is still the same model. We may be able to stop waiting for it, but the result is really the same under the covers.\n\nIf you have a blocking API you need threads, no way around that. The nice thing about `asyncio` is that you have the option of replacing many APIs with a non-blocking API, with superior timeouts and cancellation. And there are _many_ APIs you can replace with non-blocking alternatives, e.g. https://github.com/timofurrer/awesome-asyncio has database drivers, HTTP clients, DNS, Kafka client, websockets, AMQP, SSH, GraphQL, etc..\n\nSo the question is whether or not replacing blocking APIs with non-blocking APIs is worth it. That is problem-specific. For example, here are some cases where async is pointless:\n\n* **Service is unusable if upstream service goes down:** A Django web server where all data is in a PostgreSQL database may in theory suffer from issues with blocking API to the database, but in practice if the database go down the website is unusable, so using an async database connection usually has no benefit.\n* **Write-only operations, especially to a single destination:** Writing logs to a remote service is something you never want to block, but you can have a single writer thread, buffer on disk primarily and secondarily in memory in case disk blocks, and then in extreme cases drop old messages. Even if the implementation is async, the API exposed to users can be synchronous \"queue this log message\" operation that returns immediately.\n\nBlocking APIs become much more problematic when they\u0027re interactive (you need to rely on responses in the business logic), especially when they\u0027re high frequency, and when you have services whose uptime needs to be decoupled. If service A is down and service B relies on it for _some_ of its functionality, with infinitely-blocking APIs and limited size thread pools it\u0027s easy to end up with a situation where all of service B\u0027s threads are blocked waiting on A. At that point requests to B that don\u0027t need A can\u0027t proceed. \n\nIn other words, one service being down can lead to cascades where everything is down. Even worse, sufficiently _slow_ services can take down downstream services with blocking APIs, because thread pools fill up.\n\nAsync frameworks are typically much better programming model for systems where these situations are possible, since one can use timeouts and cancellation appropriately. Again, only if you can have non-blocking APIs, but that is quite likely in a wide range of cases.\n\n(Separately, blocking APIs are much more of a pain from an ergonomics perspective if the API model is asynchronous, e.g. a chat server with streaming going both ways.)\n\nSo there is of course no one-size-fits-all answer, but there is a reason why async networking is so useful for distributed systems.\n\n\u003e I\u0027d also like to point out that python has been on a breaking-things streak lately unlike anything we\u0027ve seen. They have deprecated and removed things in asyncio since the start of python3 (in fact asyncio code looks a lot different now than it did in the earlier versions). Not only is async code in python incompatible (without work) with regular synchronous code, but moving code syntax to that mechanism also invites (IMHO) more potential for \"oh well, python 3.20 has removed async def in favor of def async, time to change all the code again\" sorts of liabilities.\n\nCan you give some specific examples of deprecated APIs in `asyncio` that you think were very difficult for upstream users to deal with? All the `asyncio`-based libraries I\u0027ve seen work with a decent range of Python versions (3.8 or later, i.e. the ones that aren\u0027t EOL).\n\nIf you really are worried about Python changing from `async def` to `def async`, there\u0027s no reason to think that couldn\u0027t happen to any part of the language, and perhaps OpenStack would be better off moving off of Python. But since Python devs have made clear they have learned their lesson from 2 to 3 transition and won\u0027t do that again, that kind of change seems highly improbable.",
"parentUuid": "65b9fde3_80f23a73",
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": true,
"key": {
"uuid": "d681a203_43bab774",
"filename": "goals/proposed/modernize-openstack-async-model.rst",
"patchSetId": 14
},
"lineNbr": 337,
"author": {
"id": 11604
},
"writtenOn": "2024-01-19T18:17:01Z",
"side": 1,
"message": "openstack is much less tightly coupled then that\n\ncinder crashign wont break nova.\n\nit may prevent you attachign or detaching volumes form a vm\nbut you can still boot new vms that dont use cinder or even reboot vms taht have cinder volumes provided the storage backend is still alive.\n\nkeystone going offline breaks everything but that just because without auth we cant confirm if the request is correct from a policy perspective.\n\nto be clear we already have async networkign capablity provided by eventlet.\nwe are not using it becasue we have hight data throughput.\n\nwe are using eventlet so that we can start many request in paralel and interleave them to make forward progress when we would otherwise stall waitign on the io without havign the memory overhead fo userland threads.\n\nie. rpc_one ask us to stop a vm so that can run until we call livbirt to stop the vm and whiled then in the mean time we dequeue the next request to detach a volume form a diffent vm. that can proceed until we make the next io and we can result the livbirt stop ectra.\n\n\nso networking is not really our probelm for nova at least. we use eventlet more to for concurancy then anythign else. sometiem explcitly by spwaning greenthread sometiems implictly via io or in the backgound with perodic tasks.",
"parentUuid": "6d447ed3_bacc9927",
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": false,
"key": {
"uuid": "20f33f09_f6c74a1f",
"filename": "goals/proposed/modernize-openstack-async-model.rst",
"patchSetId": 14
},
"lineNbr": 337,
"author": {
"id": 28522
},
"writtenOn": "2024-02-21T09:57:47Z",
"side": 1,
"message": "Done",
"parentUuid": "d681a203_43bab774",
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": true,
"key": {
"uuid": "d6f0ae46_f505ea4f",
"filename": "goals/proposed/modernize-openstack-async-model.rst",
"patchSetId": 14
},
"lineNbr": 357,
"author": {
"id": 11604
},
"writtenOn": "2024-01-10T20:21:54Z",
"side": 1,
"message": "by the way not all openstack service use oslo service.\nit might be worth considering if we can reire oslo service isnstead of proting it and instead just port to an eqiuvelnt python lib that is mainted by others.\n\nor if we do we might want to port it in a reduced form.\n\noslo privsep does not use oslo.service for example but it uses its own lightwhete deamon loop\n\nhttps://github.com/openstack/oslo.privsep/blob/master/oslo_privsep/daemon.py\n\nnova may currenly depend on many of the internal so oslo.service but we will be refactiong with the porting anyway and i think we can simplfy alot.\n\njsut somethign to think about.",
"range": {
"startLine": 357,
"startChar": 5,
"endLine": 357,
"endChar": 17
},
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": true,
"key": {
"uuid": "14721dae_f61e17f4",
"filename": "goals/proposed/modernize-openstack-async-model.rst",
"patchSetId": 14
},
"lineNbr": 357,
"author": {
"id": 4393
},
"writtenOn": "2024-01-18T15:15:59Z",
"side": 1,
"message": "It\u0027s also worth noting that not all services are really using eventlet either. Glance can run in eventlet or native thread mode, depending on how it\u0027s being run. If in a wsgi container, it uses native threads to do the few things it needs to offload, which plays very well with uwsgi, et al. If it\u0027s running standalone, then it uses eventlet. Dropping eventlet from glance\u0027s repo would be trivial.\n\nI\u0027d also point out that nova-api isn\u0027t really using eventlet (properly) right now either, which is why we\u0027ve got an effort underway to make it usable in native thread mode. I certainly wouldn\u0027t want to derail that effort as I think it\u0027s probably the best option for it anyway. If nova-api goes native-threads and the rest of nova remains eventlet-on-asyncio or native-asyncio, there will be places where we have to handle (yes, I know it can be done) that because of how incompatible asyncio code is with synchronous code.",
"parentUuid": "d6f0ae46_f505ea4f",
"range": {
"startLine": 357,
"startChar": 5,
"endLine": 357,
"endChar": 17
},
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": true,
"key": {
"uuid": "bd2a883e_a1c6ce7f",
"filename": "goals/proposed/modernize-openstack-async-model.rst",
"patchSetId": 14
},
"lineNbr": 357,
"author": {
"id": 11604
},
"writtenOn": "2024-01-18T19:53:50Z",
"side": 1,
"message": "placement form day one had a policy fo no eventlet and i thinke keystone dropped it when they moved to wsgi only. so ya not all projects use eventlet today.\n\nnova, neutron, cinder, swift all do as do other but its not universal",
"parentUuid": "14721dae_f61e17f4",
"range": {
"startLine": 357,
"startChar": 5,
"endLine": 357,
"endChar": 17
},
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": true,
"key": {
"uuid": "ecb427c3_70a875c7",
"filename": "goals/proposed/modernize-openstack-async-model.rst",
"patchSetId": 14
},
"lineNbr": 357,
"author": {
"id": 4393
},
"writtenOn": "2024-01-22T17:56:38Z",
"side": 1,
"message": "Yeah, so this is sort of my point. Code that is asyncio-only is \"incompatible[0]\" with regular/synchronous code. It would be really unfortunate if all our libraries assume everything calling them is running in an asyncio loop. For widely-used libraries, both need to be supported (an unfortunate but very clear reality of the current situation). That would be the ideal for our own (because of keystone, placement, nova-api, glance, etc not running in asyncio) but I don\u0027t want libraries to assume *everyone* will only/always be asyncio.\n\n0: Yes, I know there are ways to dispatch async methods synchronously so it doesn\u0027t become a hard break, but it is very not ideal to have to do that everywhere.",
"parentUuid": "bd2a883e_a1c6ce7f",
"range": {
"startLine": 357,
"startChar": 5,
"endLine": 357,
"endChar": 17
},
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": true,
"key": {
"uuid": "d1c11806_84f09ba9",
"filename": "goals/proposed/modernize-openstack-async-model.rst",
"patchSetId": 14
},
"lineNbr": 357,
"author": {
"id": 28522
},
"writtenOn": "2024-01-23T13:28:19Z",
"side": 1,
"message": "I agree with all the remarks and comments made by Sean and Dan.\nMoving to asyncio is not a solution that fit all the case.\n\nAs Sean and Dan said, some services doesn\u0027t even relies on eventlet.\nForcing common libs, like oslo, or even sdk, to adopt the asyncio model will surely force all the pieces of openstack to adopt this model (the asyncio model).\n\nThat\u0027s not what we want here. I think we should clarify that aspect in this proposal.\n\nIndeed, the way asyncio is designed divides code into two islands - async and non-async. If our low level components (common libs) adopt a strict async approach, then all the higher level components (services) will be also forced to adopt this approach, even if they not uses eventlet currently. I think that\u0027s the main point of the remarks of Sean and Dan.\n\nImplementing asyncio in our common libs, will spreads its usage throughout the stack unless we specifically adopt a facade approach. Tiny synchronous facades for make both worlds happy. \nCommon libs would use async/await for literally everything internally, and would provide a tiny synchronous facade on top. \n\nEdgedb-python [1] is based on this paradigm and we could inspire from it to, at least, migrate our libraries. Edgedb-python provide an Asyncio API [2] and a blocking API [3]. Islands are no more isolated worlds. Bridges connect both worlds.\n\nOnly services that relies on eventlet would really have to decide for their own design. One thing is sure, they have to migrate away from eventlet. They could decide to rely on asyncio, or rather, as you said, to use native threads.\n\nEach approach, threading based network programming, or asyncio based network programming, have downsides [4][5]. Developers should weight each pros and cons of the available solutions.\n\nHowever, for services that should abandon eventlet, as this document advocate to promote the use of Asyncio, I\u0027ll add that there are two reasons to use async-based concurrency over thread-based concurrency:\n\n- Asyncio offers a safer alternative to preemptive multitasking (i.e., using threads), thereby avoiding the bugs, race conditions, and other nondeterministic dangers that frequently occur in nontrivial threaded applications.\n- Asyncio offers a simple way to support many thousands of simultaneous socket connections, including being able to handle many long-lived connections for technologies like WebSockets, or MQTT etc.\n\nBoth reasons should be considered. Arguments gave by Itamar in his comments are also good ones and can\u0027t be ignored.\n\nTo summarize, I think this proposal need to be adjusted, at least, to reflect:\n- the non-propagation of concurrency models changes in common libraries, i.e synchronous facades.\n- the fact that services not relying on eventlet are not concerned by this proposal, i.e this community goal only concern services that rely on eventlet.\n\nThe \"How to migrate a library or a service\" sections needs a refactor with more details and precisions.\n\nTo finish, I recognize the magnitude of the impact of this proposal. We, the Openstack community, have to deal with limited resources. Openstack reached a kind of stability point. We are now in maintenance mode, and resources are more decreasing than they increase. It\u0027s not the right timing for such a work. Unfortunately, we don\u0027t really have choice. Python is maintained by at least 95 core developers and thousand contributors, while Eventlet rest on the shoulder of 3 active people. It\u0027s not possible, on the long term, to keep eventlet up-to-date with all the supported versions of Python and with coming versions of Python. If we want to keep Openstack going on the long run, we have to divorce from Eventlet.\n\n[1] https://github.com/edgedb/edgedb-python\n[2] https://www.edgedb.com/docs/clients/python/api/asyncio_client\n[3] https://www.edgedb.com/docs/clients/python/api/blocking_client\n[4] Threads downsides:\n\nThreading is an inefficient model for large-scale concurrency (thousands of con current tasks), because...\n\nUsing threads is resource-intensive. Threads require extra operating system resources to create, such as preallocated, per-thread stack space that consumes process virtual memory up front. 8Mb stack space per thread...\n\nUsing threading can affect throughput. At very high concurrency levels (say, \u003e5,000 threads), there can also be an impact on throughput due to context-switching costs.\n\nThreading is inflexible. The operating system will continually share CPU time with all threads regardless of whether a thread is ready to do work or not. For instance, a thread may be waiting for data on a socket, but the OS scheduler may still switch to and from that thread thousands of times before any actual work needs to be done. In the async world, the select() system call is used to check whether a socket-awaiting coroutine needs a turn; if not, that coroutine isnt even woken up, avoiding any switching costs completely.\n\n[5] Asyncio downsides:\n\nSince Asyncio is single-threaded (almost by definition), it is unaffected by the GIL, but it cannot benefit from multiple CPU cores either.\n\nAsyncio won\u0027t make concurrent programming more easy. Asyncio makes it a little easier to avoid certain kinds of truly nightmarish race condition bugs, but even with Asyncio there is still a great deal of complexity to deal with. How will our applications support health checks? How will our programs terminate connections gracefully when we receive a signal to shut down? How will we handle (blocking!) disk access and logging? These are just a few of the many complex design decisions that we will have to answer.\n\nWithout a clear vision during implementation Asyncio could propagate its model to higher level modules in the stack.",
"parentUuid": "ecb427c3_70a875c7",
"range": {
"startLine": 357,
"startChar": 5,
"endLine": 357,
"endChar": 17
},
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": true,
"key": {
"uuid": "ea7228fc_c26e23a7",
"filename": "goals/proposed/modernize-openstack-async-model.rst",
"patchSetId": 14
},
"lineNbr": 357,
"author": {
"id": 28522
},
"writtenOn": "2024-01-23T15:06:38Z",
"side": 1,
"message": "@Sean: Concerning the oslo.service topic, what equivalent/alternative are you suggesting to use? \n\nI think this oslo.service topic is a side topic, though. I\u0027m not against removing and replacing oslo.service, however, I think that this topic will have impact even outside of the scope of of this goal proposal, e.g even on services that could not relies on eventlet. I\u0027d prefer to manage that point throughout an oslo blue print proposal or something like that.",
"parentUuid": "d1c11806_84f09ba9",
"range": {
"startLine": 357,
"startChar": 5,
"endLine": 357,
"endChar": 17
},
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": false,
"key": {
"uuid": "96800e79_df115233",
"filename": "goals/proposed/modernize-openstack-async-model.rst",
"patchSetId": 14
},
"lineNbr": 357,
"author": {
"id": 28522
},
"writtenOn": "2024-02-21T09:57:47Z",
"side": 1,
"message": "Done",
"parentUuid": "ea7228fc_c26e23a7",
"range": {
"startLine": 357,
"startChar": 5,
"endLine": 357,
"endChar": 17
},
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": true,
"key": {
"uuid": "6b59f7e4_90762ed8",
"filename": "goals/proposed/modernize-openstack-async-model.rst",
"patchSetId": 14
},
"lineNbr": 359,
"author": {
"id": 8313
},
"writtenOn": "2024-01-10T19:49:57Z",
"side": 1,
"message": "nit: in the rendered html these are not in a list",
"range": {
"startLine": 357,
"startChar": 3,
"endLine": 359,
"endChar": 21
},
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": true,
"key": {
"uuid": "2d47c3b3_49e5d7d4",
"filename": "goals/proposed/modernize-openstack-async-model.rst",
"patchSetId": 14
},
"lineNbr": 359,
"author": {
"id": 11604
},
"writtenOn": "2024-01-10T20:21:54Z",
"side": 1,
"message": "one large depensicy to call out as well is the entiry Openstack sdk need to be ported to support asyncio.\n\nwithout a full reimplmation of the sdk to nativly support async io and provide no blocking client lib we will have to wrap all rest calls made to other sevice in a thread disptached to a thread pool.\n\nthat is a viable approch in the very short term but not long term so in the mediaum term native asyncio support in the sdk is required.\n\ni dont think the sdk has any eventlet dep but its a blocking lib so we need an async version fo it to replace the current blocking api or reset request will block the event loop. currently with eventlet all io including rest calles yeild the curernt eventlet to the envent loop until the request is compelte.\n\nwe will need to await a future/awaitable returned by an \"async def\" version of the sdk methods so that other async task can execute while we are waitign.",
"parentUuid": "6b59f7e4_90762ed8",
"range": {
"startLine": 357,
"startChar": 3,
"endLine": 359,
"endChar": 21
},
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": false,
"key": {
"uuid": "93ea1f75_ab329ec3",
"filename": "goals/proposed/modernize-openstack-async-model.rst",
"patchSetId": 14
},
"lineNbr": 359,
"author": {
"id": 28522
},
"writtenOn": "2024-02-21T09:57:47Z",
"side": 1,
"message": "Done",
"parentUuid": "2d47c3b3_49e5d7d4",
"range": {
"startLine": 357,
"startChar": 3,
"endLine": 359,
"endChar": 21
},
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": true,
"key": {
"uuid": "a4a7d854_2a907fbf",
"filename": "goals/proposed/modernize-openstack-async-model.rst",
"patchSetId": 14
},
"lineNbr": 396,
"author": {
"id": 4393
},
"writtenOn": "2024-01-11T17:29:57Z",
"side": 1,
"message": "I feel like this is a lot longer of a target than is maybe being presented or assumed here. This change would be, IMHO, the largest migration we\u0027ve ever undertaken, at a time when development resources are historically low. We\u0027ve still got rootwrap in the major projects (not like we used to, but I wouldn\u0027t say we ever finished that transition) for example. Developer resources for the RBAC have been difficult to come by for years, and that\u0027s work that actually brings important new functionality, not just what would be perceived as invisible hygeine maintenance from the outside. And of course, using RBAC as an example, I think this is likely to be a moving target over time, as we determine the best way to make these things happen as we convert actual code, monitor actual performance and behavior regressions, etc.\n\nSo if we\u0027re going to go this way, I think we need to be realistic and honest about how long it\u0027s going to take, and at what point we expect migration to stop (not be finished). Like, I expect much of nova will move to the explicit wait-for-async call points, but never move past that. Actual use of async methods for RPC-serving manager calls I can imagine never happening and just remaining effectively in compatibility mode forever.\n\nMigrating to \"good enough to drop eventlet but far from done\" and never moving past that means a lot of cruft in the code base and a very non-ideal situation from a performance perspective, I think.",
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": true,
"key": {
"uuid": "f445a74e_ef06d2e8",
"filename": "goals/proposed/modernize-openstack-async-model.rst",
"patchSetId": 14
},
"lineNbr": 396,
"author": {
"id": 28522
},
"writtenOn": "2024-01-26T10:13:13Z",
"side": 1,
"message": "Indeed, the estimated deadline is surely undervalued. It is difficult to evaluate it properly.\n\nMoving the deadline too far could counter productive while proposing a closer deadline could be unrealistic.\n\n\u003e Actual use of async methods for RPC-serving manager calls I can imagine never happening and just remaining effectively in compatibility mode forever.\n\nWhat do you mean by compatibility mode? Please describe your thinking.\n\n\u003e Migrating to \"good enough to drop eventlet but far from done\" and never moving past that means a lot of cruft in the code base and a very non-ideal situation from a performance perspective, I think.\n\nI\u0027d expect that if we are able to drop eventlet, then we would be iso, in terms of IO concurrency/async, with our current runtime. In other words, green things would have been replaced by their asyncio equivalent, and where the asyncio paradigm is enough isolated to do not propagate to service that do not relied on eventlet before. So, I\u0027m not sure what you mean by saying:\n\n\u003e lot of cruft in the code base and a very non-ideal situation from a performance perspective.\n\nAfter the migration I\u0027d expect, at least, identical performances, or even improved performance. Asyncio, by design, would reduce CPU usages (virtual memory concontext switching) and things like that.",
"parentUuid": "a4a7d854_2a907fbf",
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": false,
"key": {
"uuid": "348f94a2_e7b8789a",
"filename": "goals/proposed/modernize-openstack-async-model.rst",
"patchSetId": 14
},
"lineNbr": 396,
"author": {
"id": 28522
},
"writtenOn": "2024-02-21T09:57:47Z",
"side": 1,
"message": "Done",
"parentUuid": "f445a74e_ef06d2e8",
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": true,
"key": {
"uuid": "d76b4ab9_e01adb18",
"filename": "goals/proposed/modernize-openstack-async-model.rst",
"patchSetId": 14
},
"lineNbr": 432,
"author": {
"id": 27615
},
"writtenOn": "2023-12-26T15:23:30Z",
"side": 1,
"message": "nit: run",
"range": {
"startLine": 432,
"startChar": 29,
"endLine": 432,
"endChar": 32
},
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": false,
"key": {
"uuid": "75ad1a2e_aea87701",
"filename": "goals/proposed/modernize-openstack-async-model.rst",
"patchSetId": 14
},
"lineNbr": 432,
"author": {
"id": 28522
},
"writtenOn": "2024-02-21T09:57:47Z",
"side": 1,
"message": "Done",
"parentUuid": "d76b4ab9_e01adb18",
"range": {
"startLine": 432,
"startChar": 29,
"endLine": 432,
"endChar": 32
},
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": true,
"key": {
"uuid": "63b4e49b_8074b8ad",
"filename": "goals/proposed/modernize-openstack-async-model.rst",
"patchSetId": 14
},
"lineNbr": 520,
"author": {
"id": 8313
},
"writtenOn": "2024-01-10T19:49:57Z",
"side": 1,
"message": "Is this a new paragraph?",
"range": {
"startLine": 520,
"startChar": 0,
"endLine": 520,
"endChar": 9
},
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
},
{
"unresolved": false,
"key": {
"uuid": "ce6cd475_71b19f7c",
"filename": "goals/proposed/modernize-openstack-async-model.rst",
"patchSetId": 14
},
"lineNbr": 520,
"author": {
"id": 28522
},
"writtenOn": "2024-02-21T09:57:47Z",
"side": 1,
"message": "Done",
"parentUuid": "63b4e49b_8074b8ad",
"range": {
"startLine": 520,
"startChar": 0,
"endLine": 520,
"endChar": 9
},
"revId": "a0d828ea7ad58f7e0102bb91da927bc0ccbe2a32",
"serverId": "4a232e18-c5a9-48ee-94c0-e04e7cca6543"
}
]
}