Files
CN2021/server/worker.py
2021-03-21 23:01:09 +01:00

84 lines
2.3 KiB
Python

import logging
import multiprocessing
import multiprocessing as mp
import threading
from concurrent.futures import ThreadPoolExecutor
from logging import Logger
from socket import socket
from server.RequestHandler import RequestHandler
THREAD_LIMIT = 20
def worker(address, name, log_level, queue: mp.Queue, stop_event: mp.Event):
logging.basicConfig(level=log_level)
logger = multiprocessing.log_to_stderr(level=log_level)
runner = Worker(address, name, logger, queue, stop_event)
runner.logger.debug("Worker %s started", name)
try:
runner.run()
except KeyboardInterrupt:
logger.debug("Ctrl+C pressed, terminating")
runner.shutdown()
class Worker:
host: str
name: str
logger: Logger
queue: mp.Queue
executor: ThreadPoolExecutor
stop_event: mp.Event
finished_queue: mp.Queue
def __init__(self, host, name, logger, queue: mp.Queue, stop_event: mp.Event):
self.host = host
self.name = name
self.logger = logger
self.queue = queue
self.executor = ThreadPoolExecutor(THREAD_LIMIT)
self.stop_event = stop_event
self.finished_queue = mp.Queue()
for i in range(THREAD_LIMIT):
self.finished_queue.put(i)
def run(self):
while not self.stop_event.is_set():
# Blocks until thread is free
self.finished_queue.get()
# Blocks until new client connects
conn, addr = self.queue.get()
if conn is None or addr is None:
break
self.logger.debug("Received new client: %s", addr)
# submit client to thread
print(threading.get_ident())
self.executor.submit(self._handle_client, conn, addr)
self.shutdown()
def _handle_client(self, conn: socket, addr):
try:
self.logger.debug("Handling client: %s", addr)
handler = RequestHandler(conn, self.logger, self.host)
handler.listen()
except Exception as e:
self.logger.debug("Internal error", exc_info=e)
# Finished, put back into queue
self.finished_queue.put(threading.get_ident())
def shutdown(self):
self.logger.info("shutting down")
self.executor.shutdown()