04.06., 9:00 - 12:00: GitLab will be migrated to a new server environment and upgraded to Enterprise Edition Ultimate. The estimated downtime will be 2-3 hours. Please see https://doku.lrz.de/display/PUBLIC/GitLab+Ultimate+Migration for more details about changes related to the migration.

Commit c5b90ba1 authored by eckhart's avatar eckhart

- server.py: compatibility with pypy3 (e.g. python 3.6) fixed

parent ef49649a
...@@ -155,11 +155,11 @@ CONFIG_PRESET['max_rpc_size'] = 4 * 1024 * 1024 ...@@ -155,11 +155,11 @@ CONFIG_PRESET['max_rpc_size'] = 4 * 1024 * 1024
# Defaut host name or IP-adress for the compiler server. Should usually # Defaut host name or IP-adress for the compiler server. Should usually
# be localhost (127.0.0.1) # be localhost (127.0.0.1)
# Default value: 127.0.0.1. # Default value: 127.0.0.1.
CONFIG_PRESET['default_server_host'] = "127.0.0.1" CONFIG_PRESET['server_default_host'] = "127.0.0.1"
# Default port number for the compiler server. # Default port number for the compiler server.
# Default value: 8888 # Default value: 8888
CONFIG_PRESET['default_server_port'] = 8888 CONFIG_PRESET['server_default_port'] = 8888
######################################################################## ########################################################################
......
...@@ -142,20 +142,12 @@ def asyncio_run(coroutine: Coroutine) -> Any: ...@@ -142,20 +142,12 @@ def asyncio_run(coroutine: Coroutine) -> Any:
return asyncio.run(coroutine) return asyncio.run(coroutine)
else: else:
loop = asyncio.get_event_loop() loop = asyncio.get_event_loop()
try: return loop.run_until_complete(coroutine)
return loop.run_until_complete(coroutine)
finally:
loop.close()
def GMT_timestamp() -> str: def GMT_timestamp() -> str:
return time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime()) return time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime())
# CompilationItem = NamedTuple('CompilationItem',
# [('uri', str),
# ('hash', int),
# ('errors', str),
# ('preview', str)])
ALL_RPCs = frozenset('*') # Magic value denoting all remove procedures ALL_RPCs = frozenset('*') # Magic value denoting all remove procedures
...@@ -207,6 +199,8 @@ class Server: ...@@ -207,6 +199,8 @@ class Server:
self.pp_executor = None # type: Optional[ProcessPoolExecutor] self.pp_executor = None # type: Optional[ProcessPoolExecutor]
self.tp_executor = None # type: Optional[ThreadPoolExecutor] self.tp_executor = None # type: Optional[ThreadPoolExecutor]
self.loop = None # just for python 3.5 compatibility...
async def handle_request(self, async def handle_request(self,
reader: asyncio.StreamReader, reader: asyncio.StreamReader,
writer: asyncio.StreamWriter): writer: asyncio.StreamWriter):
...@@ -236,7 +230,8 @@ class Server: ...@@ -236,7 +230,8 @@ class Server:
# #executing-code-in-thread-or-process-pools # #executing-code-in-thread-or-process-pools
has_kw_params = isinstance(params, Dict) has_kw_params = isinstance(params, Dict)
assert has_kw_params or isinstance(params, Sequence) assert has_kw_params or isinstance(params, Sequence)
loop = asyncio.get_running_loop() loop = asyncio.get_running_loop() if sys.version_info >= (3, 7) \
else asyncio.get_event_loop()
executor = self.pp_executor if method_name in self.cpu_bound else \ executor = self.pp_executor if method_name in self.cpu_bound else \
self.tp_executor if method_name in self.blocking else None self.tp_executor if method_name in self.blocking else None
if executor is None: if executor is None:
...@@ -357,9 +352,11 @@ class Server: ...@@ -357,9 +352,11 @@ class Server:
% (rpc_error[0], rpc_error[1], json_id)).encode()) % (rpc_error[0], rpc_error[1], json_id)).encode())
await writer.drain() await writer.drain()
if kill_switch: if kill_switch:
# TODO: terminate processes and threads! # TODO: terminate processes and threads! Is this needed??
self.stage.value = SERVER_TERMINATE self.stage.value = SERVER_TERMINATE
self.server.close() self.server.close()
if self.loop is not None:
self.loop.stop()
async def serve(self, host: str = USE_DEFAULT_HOST, port: int = USE_DEFAULT_PORT): async def serve(self, host: str = USE_DEFAULT_HOST, port: int = USE_DEFAULT_PORT):
if host == USE_DEFAULT_HOST: if host == USE_DEFAULT_HOST:
...@@ -380,6 +377,31 @@ class Server: ...@@ -380,6 +377,31 @@ class Server:
self.server_messages.put(SERVER_ONLINE) self.server_messages.put(SERVER_ONLINE)
await self.server.serve_forever() await self.server.serve_forever()
def serve_py35(self, host: str = USE_DEFAULT_HOST, port: int = USE_DEFAULT_PORT):
if host == USE_DEFAULT_HOST:
host = get_config_value('server_default_host')
if port == USE_DEFAULT_PORT:
port = get_config_value('server_default_port')
assert port >= 0
with ProcessPoolExecutor() as p, ThreadPoolExecutor() as t:
self.pp_executor = p
self.tp_executor = t
self.stop_response = "DHParser server at {}:{} stopped!".format(host, port)
self.host.value = host.encode()
self.port.value = port
self.loop = asyncio.get_event_loop()
self.server = cast(
asyncio.base_events.Server,
self.loop.run_until_complete(
asyncio.start_server(self.handle_request, host, port)))
try:
self.stage.value = SERVER_ONLINE
self.server_messages.put(SERVER_ONLINE)
self.loop.run_forever()
finally:
self.server.close()
self.server.wait_closed()
def _empty_message_queue(self): def _empty_message_queue(self):
while not self.server_messages.empty(): while not self.server_messages.empty():
self.server_messages.get() self.server_messages.get()
...@@ -393,13 +415,17 @@ class Server: ...@@ -393,13 +415,17 @@ class Server:
self.stage.value = SERVER_STARTING self.stage.value = SERVER_STARTING
self._empty_message_queue() self._empty_message_queue()
try: try:
asyncio_run(self.serve(host, port)) if sys.version_info >= (3, 7):
asyncio.run(self.serve(host, port))
else:
self.serve_py35(host, port)
except CancelledError: except CancelledError:
self.pp_executor = None pass
self.tt_exectuor = None self.pp_executor = None
asyncio_run(self.server.wait_closed()) self.tt_exectuor = None
self.server_messages.put(SERVER_OFFLINE) asyncio_run(self.server.wait_closed())
self.stage.value = SERVER_OFFLINE self.server_messages.put(SERVER_OFFLINE)
self.stage.value = SERVER_OFFLINE
def wait_until_server_online(self): def wait_until_server_online(self):
if self.stage.value != SERVER_ONLINE: if self.stage.value != SERVER_ONLINE:
...@@ -447,7 +473,8 @@ class Server: ...@@ -447,7 +473,8 @@ class Server:
self.stage.value = SERVER_TERMINATE self.stage.value = SERVER_TERMINATE
self.server_process.terminate() self.server_process.terminate()
self.server_process.join() self.server_process.join()
self.server_process.close() if sys.version_info >= (3, 7):
self.server_process.close()
self.server_process = None self.server_process = None
self.stage.value = SERVER_OFFLINE self.stage.value = SERVER_OFFLINE
except AssertionError as debugger_err: except AssertionError as debugger_err:
......
...@@ -35,7 +35,7 @@ def run_doctests(module): ...@@ -35,7 +35,7 @@ def run_doctests(module):
if __name__ == "__main__": if __name__ == "__main__":
interpreters = ['python3 ' if os.system('python3 -V') == 0 else 'python '] interpreters = [] # ['python3 ' if os.system('python3 -V') == 0 else 'python ']
if os.system('pypy3 -V') == 0: if os.system('pypy3 -V') == 0:
interpreters.append('pypy3 ') interpreters.append('pypy3 ')
elif os.system('pypy -V') == 0: elif os.system('pypy -V') == 0:
......
...@@ -83,7 +83,7 @@ class TestServer: ...@@ -83,7 +83,7 @@ class TestServer:
try: try:
cs.spawn_server('127.0.0.1', 8888) cs.spawn_server('127.0.0.1', 8888)
result = asyncio_run(send_request(IDENTIFY_REQUEST)) result = asyncio_run(send_request(IDENTIFY_REQUEST))
assert result.startswith('DHParser') assert result.startswith('DHParser'), result
finally: finally:
cs.terminate_server() cs.terminate_server()
......
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