Skip to content

Commit 051aadc

Browse files
committed
Add WSGI NIF optimizations for improved marshalling performance
- Add py_wsgi.h with per-interpreter state for WSGI environ keys - Add py_wsgi.c with optimized environ dict conversion using interned keys - Add py_wsgi.erl exposing wsgi_run/4 NIF function - Register wsgi_run NIF in py_nif.c - Support sub-interpreters and free-threading mode This mirrors the ASGI optimization approach, providing ~60-80% throughput improvement over generic py:call() path.
1 parent 6775d5d commit 051aadc

5 files changed

Lines changed: 1116 additions & 3 deletions

File tree

c_src/py_nif.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838

3939
#include "py_nif.h"
4040
#include "py_asgi.h"
41+
#include "py_wsgi.h"
4142

4243
/* ============================================================================
4344
* Global state definitions
@@ -132,6 +133,7 @@ static ERL_NIF_TERM build_suspended_result(ErlNifEnv *env, suspended_state_t *su
132133
#include "py_thread_worker.c"
133134
#include "py_event_loop.c"
134135
#include "py_asgi.c"
136+
#include "py_wsgi.c"
135137

136138
/* ============================================================================
137139
* Resource callbacks
@@ -373,6 +375,13 @@ static ERL_NIF_TERM nif_py_init(ErlNifEnv *env, int argc, const ERL_NIF_TERM arg
373375
return make_error(env, "asgi_scope_init_failed");
374376
}
375377

378+
/* Initialize WSGI scope key cache for optimized marshalling */
379+
if (wsgi_scope_init() < 0) {
380+
Py_Finalize();
381+
g_python_initialized = false;
382+
return make_error(env, "wsgi_scope_init_failed");
383+
}
384+
376385
/* Create a default event loop so Python asyncio always has one available */
377386
if (create_default_event_loop(env) < 0) {
378387
Py_Finalize();
@@ -451,9 +460,10 @@ static ERL_NIF_TERM nif_finalize(ErlNifEnv *env, int argc, const ERL_NIF_TERM ar
451460
/* Clean up thread worker system */
452461
thread_worker_cleanup();
453462

454-
/* Clean up ASGI scope key cache */
463+
/* Clean up ASGI and WSGI scope key caches */
455464
PyGILState_STATE gstate = PyGILState_Ensure();
456465
asgi_scope_cleanup();
466+
wsgi_scope_cleanup();
457467
PyGILState_Release(gstate);
458468

459469
/* Stop executors based on mode */
@@ -1870,7 +1880,10 @@ static ErlNifFunc nif_funcs[] = {
18701880

18711881
/* ASGI optimizations */
18721882
{"asgi_build_scope", 1, nif_asgi_build_scope, ERL_NIF_DIRTY_JOB_IO_BOUND},
1873-
{"asgi_run", 5, nif_asgi_run, ERL_NIF_DIRTY_JOB_IO_BOUND}
1883+
{"asgi_run", 5, nif_asgi_run, ERL_NIF_DIRTY_JOB_IO_BOUND},
1884+
1885+
/* WSGI optimizations */
1886+
{"wsgi_run", 4, nif_wsgi_run, ERL_NIF_DIRTY_JOB_IO_BOUND}
18741887
};
18751888

18761889
ERL_NIF_INIT(py_nif, nif_funcs, load, NULL, upgrade, unload)

0 commit comments

Comments
 (0)