Files
CN2021/server/httpserver.py
2021-03-22 02:41:49 +01:00

96 lines
2.5 KiB
Python

import logging
import multiprocessing as mp
import socket
import time
from multiprocessing.context import Process
from multiprocessing.queues import Queue
from multiprocessing.synchronize import Event
from server import worker
class HTTPServer:
address: str
port: int
workers = []
worker_count: int
server: socket
_dispatch_queue: Queue
_stop_event: Event
def __init__(self, address: str, port: int, worker_count, logging_level):
self.address = address
self.port = port
self.worker_count = worker_count
self.logging_level = logging_level
mp.set_start_method("spawn")
self._dispatch_queue = mp.Queue()
self._stop_event = mp.Event()
def start(self):
try:
self.__do_start()
except KeyboardInterrupt:
self.__shutdown()
def __do_start(self):
# Create socket
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server.bind((self.address, self.port))
self.__create_workers()
self.__listen()
def __listen(self):
self.server.listen()
logging.debug("Listening for connections")
while True:
if self._dispatch_queue.qsize() > self.worker_count:
time.sleep(0.01)
continue
conn, addr = self.server.accept()
logging.info("New connection: %s", addr[0])
self._dispatch_queue.put((conn, addr))
logging.debug("Dispatched connection %s", addr)
def __shutdown(self):
# Set stop event
self._stop_event.set()
# Wake up workers
logging.debug("Waking up workers")
for p in self.workers:
self._dispatch_queue.put((None, None))
logging.debug("Closing dispatch queue")
self._dispatch_queue.close()
logging.debug("Waiting for workers to shutdown")
p: Process
for p in self.workers:
p.join()
p.terminate()
logging.debug("Shutting down socket")
self.server.shutdown(socket.SHUT_RDWR)
self.server.close()
def __create_workers(self):
for i in range(self.worker_count):
logging.debug("Creating worker: %d", i + 1)
p = mp.Process(target=worker.worker,
args=(f"{self.address}:{self.port}", i + 1, self.logging_level, self._dispatch_queue, self._stop_event))
p.start()
self.workers.append(p)
time.sleep(0.2)
time.sleep(1)