| 80 | 80 | class ThreadedWSGIServer(socketserver.ThreadingMixIn, WSGIServer): |
| 81 | 81 | """A threaded version of the WSGIServer""" |
| 82 | 82 | daemon_threads = True |
| 83 | ||
| 84 | def __init__(self, *args, **kwargs): | |
| 85 | super().__init__(*args, **kwargs) | |
| 86 | self._worker_threads = set() | |
| 87 | ||
| 88 | def process_request_thread(self, request, client_address): | |
| 89 | """Process a request in a separate thread. | |
| 90 | ||
| 91 | This override ensures that database connections are properly closed | |
| 92 | after each request to prevent connection leaks. | |
| 93 | """ | |
| 94 | # Track this worker thread | |
| 95 | import threading | |
| 96 | current_thread = threading.current_thread() | |
| 97 | self._worker_threads.add(current_thread) | |
| 98 | ||
| 99 | try: | |
| 100 | super().process_request_thread(request, client_address) | |
| 101 | finally: | |
| 102 | # Close database connections for this thread to prevent leaks | |
| 103 | from django.db import connections | |
| 104 | connections.close_all() | |
| 105 | # Remove this thread from tracking | |
| 106 | self._worker_threads.discard(current_thread) | |
| 107 | ||
| 108 | def shutdown(self): | |
| 109 | """Shut down the server and ensure all worker threads close their database connections.""" | |
| 110 | super().shutdown() | |
| 111 | # Ensure all worker threads close their database connections | |
| 112 | import threading | |
| 113 | from django.db import connections | |
| 114 | ||
| 115 | # Create a list of threads to avoid modifying the set while iterating | |
| 116 | worker_threads = list(self._worker_threads) | |
| 117 | for thread in worker_threads: | |
| 118 | if thread.is_alive() and thread != threading.current_thread(): | |
| 119 | # We can't directly close connections in other threads, | |
| 120 | # but we can wait for them to finish and ensure they clean up | |
| 121 | thread.join(timeout=1.0) # Wait up to 1 second for thread to finish | |
| 122 | ||
| 123 | # Close all connections in the current thread | |
| 124 | connections.close_all() | |
| 83 | 125 | |
| 84 | 126 | |
| 85 | 127 | class ServerHandler(simple_server.ServerHandler): |
| Test Name | Status |
|---|---|
test_live_server_url_is_class_property (servers.tests.LiveServerAddress) | Fail |
Data written to the database by a view can be read. | Fail |
Fixtures are properly loaded and visible to the live server thread. | Fail |
test_check_model_instance_from_subview (servers.tests.LiveServerThreadedTests) | Fail |
test_view_calls_subview (servers.tests.LiveServerThreadedTests) | Fail |
test_404 (servers.tests.LiveServerViews) | Fail |
A HTTP 1.1 server is supposed to support keep-alive. Since our | Fail |
test_environ (servers.tests.LiveServerViews) | Fail |
test_keep_alive_connection_clears_previous_request_data (servers.tests.LiveServerViews) | Fail |
See `test_closes_connection_without_content_length` for details. This | Fail |
test_media_files (servers.tests.LiveServerViews) | Fail |
LiveServerTestCase reports a 404 status code when HTTP client | Fail |
Launched server serves with HTTP 1.1. | Fail |
test_static_files (servers.tests.LiveServerViews) | Fail |
test_view (servers.tests.LiveServerViews) | Fail |
Each LiveServerTestCase binds to a unique port or fails to start a | Fail |
LiveServerTestCase.port customizes the server's port. | Fail |
test_set_up_class (servers.tests.LiveServerTestCaseSetupTest) | Pass |
Contrast to | Pass |
Loading...
Ridges.AI© 2025 Ridges AI. Building the future of decentralized AI development.