Skip to content

Commit 4b7a954

Browse files
committed
Python: ASGI: Factor out event loop creation to its own function.
This is a preparatory patch that factors out the asyncio event loop creation code from nxt_python_asgi_ctx_data_alloc() into its own function, to facilitate being called multiple times. This a part of the work to move away from using the asyncio.get_event_loop() function due to it no longer creating event loops if there wasn't one running. See the following commit for the gory details. Reviewed-by: Alejandro Colomar <[email protected]> Signed-off-by: Andrew Clayton <[email protected]>
1 parent 5a37171 commit 4b7a954

File tree

1 file changed

+35
-21
lines changed

1 file changed

+35
-21
lines changed

src/python/nxt_python_asgi.c

Lines changed: 35 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818

1919
static PyObject *nxt_python_asgi_get_func(PyObject *obj);
20+
static PyObject *nxt_python_asgi_get_event_loop(PyObject *asyncio,
21+
const char *event_loop_func);
2022
static int nxt_python_asgi_ctx_data_alloc(void **pdata, int main);
2123
static void nxt_python_asgi_ctx_data_free(void *data);
2224
static int nxt_python_asgi_startup(void *data);
@@ -201,11 +203,41 @@ nxt_python_asgi_init(nxt_unit_init_t *init, nxt_python_proto_t *proto)
201203
}
202204

203205

206+
static PyObject *
207+
nxt_python_asgi_get_event_loop(PyObject *asyncio, const char *event_loop_func)
208+
{
209+
PyObject *event_loop, *loop;
210+
211+
event_loop = PyDict_GetItemString(PyModule_GetDict(asyncio),
212+
event_loop_func);
213+
if (nxt_slow_path(event_loop == NULL)) {
214+
nxt_unit_alert(NULL, "Python failed to get '%s' from module 'asyncio'",
215+
event_loop_func);
216+
return NULL;
217+
}
218+
219+
if (nxt_slow_path(PyCallable_Check(event_loop) == 0)) {
220+
nxt_unit_alert(NULL, "'asyncio.%s' is not a callable object",
221+
event_loop_func);
222+
return NULL;
223+
}
224+
225+
loop = PyObject_CallObject(event_loop, NULL);
226+
if (nxt_slow_path(loop == NULL)) {
227+
nxt_unit_alert(NULL, "Python failed to call 'asyncio.%s'",
228+
event_loop_func);
229+
return NULL;
230+
}
231+
232+
return loop;
233+
}
234+
235+
204236
static int
205237
nxt_python_asgi_ctx_data_alloc(void **pdata, int main)
206238
{
207239
uint32_t i;
208-
PyObject *asyncio, *loop, *event_loop, *obj;
240+
PyObject *asyncio, *loop, *obj;
209241
const char *event_loop_func;
210242
nxt_py_asgi_ctx_data_t *ctx_data;
211243

@@ -243,26 +275,8 @@ nxt_python_asgi_ctx_data_alloc(void **pdata, int main)
243275

244276
event_loop_func = main ? "get_event_loop" : "new_event_loop";
245277

246-
event_loop = PyDict_GetItemString(PyModule_GetDict(asyncio),
247-
event_loop_func);
248-
if (nxt_slow_path(event_loop == NULL)) {
249-
nxt_unit_alert(NULL,
250-
"Python failed to get '%s' from module 'asyncio'",
251-
event_loop_func);
252-
goto fail;
253-
}
254-
255-
if (nxt_slow_path(PyCallable_Check(event_loop) == 0)) {
256-
nxt_unit_alert(NULL,
257-
"'asyncio.%s' is not a callable object",
258-
event_loop_func);
259-
goto fail;
260-
}
261-
262-
loop = PyObject_CallObject(event_loop, NULL);
263-
if (nxt_slow_path(loop == NULL)) {
264-
nxt_unit_alert(NULL, "Python failed to call 'asyncio.%s'",
265-
event_loop_func);
278+
loop = nxt_python_asgi_get_event_loop(asyncio, event_loop_func);
279+
if (loop == NULL) {
266280
goto fail;
267281
}
268282

0 commit comments

Comments
 (0)