Passing request_data wasn't a good idea for certain reasons. I probably just rediscovered why I didn't do it that way in the first place. :-)
Anyway, provided you use the latest from 'develop' branch of GitHub repo, play around with the following code.
import os
import sys
import time
import threading
import traceback
import mod_wsgi
def event_handler(name, **kwargs):
if name == 'request_started':
request_data = mod_wsgi.request_data()
request_data.update(kwargs)
request_data['python_thread_id'] = threading.get_ident()
elif name == 'process_stopping':
if kwargs['shutdown_reason'] == 'request_timeout':
print('SHUTDOWN')
current_time = time.time()
stacks = dict(sys._current_frames().items())
active = dict(mod_wsgi.active_requests.items())
for request_id, request_data in active.items():
python_thread_id = request_data['python_thread_id']
application_start = request_data['application_start']
request_environ = request_data['request_environ']
request_uri = request_environ['REQUEST_URI']
running_time = current_time - application_start
print()
print('THREAD_ID', python_thread_id)
print('REQUEST_ID', request_id)
print('REQUEST_URI', request_uri)
print('RUNNING_TIME', running_time)
if python_thread_id in stacks:
print('STACK-TRACE')
traceback.print_stack(stacks[python_thread_id])
mod_wsgi.subscribe_events(event_handler)
def application(environ, start_response):
sleep_duration = environ.get('HTTP_X_SLEEP_DURATION', 0)
sleep_duration = float(sleep_duration or 0)
status = '200 OK'
output = b'Hello World!'
response_headers = [('Content-type', 'text/plain'),
('Content-Length', str(len(output)))]
start_response(status, response_headers)
if sleep_duration:
time.sleep(sleep_duration)
yield output
I am running that with:
mod_wsgi-express start-server tests/request-timeout.wsgi --log-to-terminal --request-timeout 1 --threads 1 --log-level info
and running curl as:
That gets me the following. One stack trace I generate myself just for that sub interpreter out of event mechanism. The other is process wide generated from C code level.
[Thu Feb 08 22:52:41.635819 2018] [wsgi:info] [pid 21486] mod_wsgi (pid=21486): Daemon process request time limit exceeded, stopping process 'localhost:8000'.
[Thu Feb 08 22:52:41.636053 2018] [wsgi:info] [pid 21486] mod_wsgi (pid=21486): Shutdown requested 'localhost:8000'.
[Thu Feb 08 22:52:41.636126 2018] [wsgi:error] [pid 21486] SHUTDOWN
[Thu Feb 08 22:52:41.636149 2018] [wsgi:error] [pid 21486]
[Thu Feb 08 22:52:41.636156 2018] [wsgi:error] [pid 21486] THREAD_ID 123145557110784
[Thu Feb 08 22:52:41.636162 2018] [wsgi:error] [pid 21486] REQUEST_ID YSp5DBLFVJs
[Thu Feb 08 22:52:41.636166 2018] [wsgi:error] [pid 21486] REQUEST_URI /
[Thu Feb 08 22:52:41.636179 2018] [wsgi:error] [pid 21486] RUNNING_TIME 1.85565185546875
[Thu Feb 08 22:52:41.636187 2018] [wsgi:error] [pid 21486] STACK-TRACE
[Thu Feb 08 22:52:41.819058 2018] [wsgi:error] [pid 21486] File "/Volumes/graham/Projects/mod_wsgi/tests/request-timeout.wsgi", line 56, in application
[Thu Feb 08 22:52:41.819071 2018] [wsgi:error] [pid 21486] time.sleep(sleep_duration)
[Thu Feb 08 22:52:41.819080 2018] [wsgi:info] [pid 21486] mod_wsgi (pid=21486): Dumping stack trace for active Python threads.
[Thu Feb 08 22:52:41.819083 2018] [wsgi:info] [pid 21486] mod_wsgi (pid=21486): Thread 123145557110784 executing file "/Volumes/graham/Projects/mod_wsgi/tests/request-timeout.wsgi", line 56, in application
[Thu Feb 08 22:52:46.636172 2018] [wsgi:info] [pid 21486] mod_wsgi (pid=21486): Aborting process 'localhost:8000'.
[Thu Feb 08 22:52:46.636375 2018] [wsgi:info] [pid 21486] mod_wsgi (pid=21486): Exiting process 'localhost:8000'.
Graham