#!/usr/bin/env python3 """Concurrency-bounded threaded HTTP server for the Hermes SCM broker.""" from __future__ import annotations import threading from http.server import ThreadingHTTPServer MAX_CONCURRENT_REQUESTS = 2 class BoundedThreadingHTTPServer(ThreadingHTTPServer): """Cap active handlers so large Git exchanges cannot exhaust memory.""" daemon_threads = True block_on_close = True request_queue_size = 16 def __init__(self, *args, **kwargs): self._slots = threading.BoundedSemaphore(MAX_CONCURRENT_REQUESTS) super().__init__(*args, **kwargs) def process_request(self, request, client_address) -> None: if not self._slots.acquire(blocking=False): try: request.sendall( b"HTTP/1.1 503 Service Unavailable\r\n" b"Connection: close\r\nContent-Length: 0\r\n\r\n" ) finally: self.shutdown_request(request) return try: super().process_request(request, client_address) except Exception: self._slots.release() self.shutdown_request(request) raise def process_request_thread(self, request, client_address) -> None: try: super().process_request_thread(request, client_address) finally: self._slots.release()