Commit 91acfa10 authored by eckhart's avatar eckhart
Browse files

server.py: run_as_process() added

parent 261b1758
No preview for this file type
...@@ -35,8 +35,8 @@ of module `server`, i.e. the compilation-modules, to decide. ...@@ -35,8 +35,8 @@ of module `server`, i.e. the compilation-modules, to decide.
import asyncio import asyncio
from multiprocessing import Value, Queue from multiprocessing import Process, Value, Queue
from typing import Callable, Any from typing import Callable, Optional, Any
from DHParser.preprocess import BEGIN_TOKEN, END_TOKEN, TOKEN_DELIMITER from DHParser.preprocess import BEGIN_TOKEN, END_TOKEN, TOKEN_DELIMITER
from DHParser.toolkit import get_config_value from DHParser.toolkit import get_config_value
...@@ -48,9 +48,10 @@ SERVER_ERROR = "COMPILER-SERVER-ERROR" ...@@ -48,9 +48,10 @@ SERVER_ERROR = "COMPILER-SERVER-ERROR"
CompileFunc = Callable[[str, str], Any] # compiler_src(source: str, log_dir: str) -> Any CompileFunc = Callable[[str, str], Any] # compiler_src(source: str, log_dir: str) -> Any
SERVER_OFFLINE = 0 SERVER_OFFLINE = 0
SERVER_STARTING = 1 SERVER_STARTING = 1
SERVER_ONLINE = 2 SERVER_ONLINE = 2
SERVER_TERMINATE = 3
...@@ -59,11 +60,12 @@ class CompilerServer: ...@@ -59,11 +60,12 @@ class CompilerServer:
self.compiler = compiler self.compiler = compiler
self.max_source_size = get_config_value('max_source_size') self.max_source_size = get_config_value('max_source_size')
self.stage = Value('b', SERVER_OFFLINE) self.stage = Value('b', SERVER_OFFLINE)
self.server_messages = Queue() self.server_messages = Queue() # type: Queue
self.server_process = None # type: Optional[Process]
async def handle_compilation_request(self, async def handle_compilation_request(self,
reader: asyncio.StreamReader, reader: asyncio.StreamReader,
writer: asyncio.StreamWriter): writer: asyncio.StreamWriter):
data = await reader.read(self.max_source_size + 1) data = await reader.read(self.max_source_size + 1)
if len(data) > self.max_source_size: if len(data) > self.max_source_size:
writer.write(BEGIN_TOKEN + SERVER_ERROR + TOKEN_DELIMITER + writer.write(BEGIN_TOKEN + SERVER_ERROR + TOKEN_DELIMITER +
...@@ -74,19 +76,35 @@ class CompilerServer: ...@@ -74,19 +76,35 @@ class CompilerServer:
await writer.drain() await writer.drain()
writer.close() writer.close()
async def serve(self, address: str='127.0.0.1', port: int=8888): async def serve(self, address: str = '127.0.0.1', port: int = 8888):
server = await asyncio.start_server(self.handle_compilation_request, address, port) server = await asyncio.start_server(self.handle_compilation_request, address, port)
async with server: async with server:
self.stage.value = SERVER_ONLINE self.stage.value = SERVER_ONLINE
self.server_messages.put(SERVER_ONLINE) self.server_messages.put(SERVER_ONLINE)
await server.serve_forever() await server.serve_forever()
def run_server(self, address: str='127.0.0.1', port: int=8888): def run_server(self, address: str = '127.0.0.1', port: int = 8888):
self.stage.value = SERVER_STARTING self.stage.value = SERVER_STARTING
asyncio.run(self.serve(address, port)) asyncio.run(self.serve(address, port))
def wait_until_server_online(self): def wait_until_server_online(self):
if self.server_messages.get() != SERVER_ONLINE: if self.stage.value != SERVER_ONLINE:
raise AssertionError('could not start server!?') if self.server_messages.get() != SERVER_ONLINE:
assert self.stage.value == SERVER_ONLINE raise AssertionError('could not start server!?')
assert self.stage.value == SERVER_ONLINE
def run_as_process(self):
self.server_process = Process(target=self.run_server)
self.server_process.start()
self.wait_until_server_online()
def terminate_server_process(self):
self.server_process.terminate()
def wait_for_termination(self):
assert self.server_process
# self.wait_until_server_online()
while self.server_messages.get() != SERVER_TERMINATE:
pass
self.terminate_server_process()
self.server_process = None
...@@ -26,9 +26,10 @@ from multiprocessing import Process ...@@ -26,9 +26,10 @@ from multiprocessing import Process
import sys import sys
from typing import Tuple from typing import Tuple
sys.path.extend(['../', './'])
from DHParser.server import CompilerServer from DHParser.server import CompilerServer
sys.path.extend(['../', './'])
scriptdir = os.path.dirname(os.path.realpath(__file__)) scriptdir = os.path.dirname(os.path.realpath(__file__))
...@@ -36,12 +37,11 @@ scriptdir = os.path.dirname(os.path.realpath(__file__)) ...@@ -36,12 +37,11 @@ scriptdir = os.path.dirname(os.path.realpath(__file__))
def compiler_dummy(src: str, log_dir: str) -> Tuple[str, str]: def compiler_dummy(src: str, log_dir: str) -> Tuple[str, str]:
return (src, log_dir) return (src, log_dir)
class TestServer: class TestServer:
def test_server(self): def test_server(self):
cs = CompilerServer(compiler_dummy) cs = CompilerServer(compiler_dummy)
p = Process(target=cs.run_server) cs.run_as_process()
p.start()
cs.wait_until_server_online()
async def compile(src, log_dir): async def compile(src, log_dir):
reader, writer = await asyncio.open_connection('127.0.0.1', 8888) reader, writer = await asyncio.open_connection('127.0.0.1', 8888)
...@@ -50,7 +50,7 @@ class TestServer: ...@@ -50,7 +50,7 @@ class TestServer:
print(f'Received: {data.decode()!r}') print(f'Received: {data.decode()!r}')
writer.close() writer.close()
asyncio.run(compile('Test', '')) asyncio.run(compile('Test', ''))
p.terminate() cs.terminate_server_process()
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment