-
Notifications
You must be signed in to change notification settings - Fork 998
Simplify asyncio and server list #2033
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
|
@@ -4,7 +4,6 @@ | |||
|
||||
import asyncio | ||||
import os | ||||
import time | ||||
import traceback | ||||
from contextlib import suppress | ||||
|
||||
|
@@ -284,10 +283,6 @@ def callback_new_connection(self): | |||
return ModbusServerRequestHandler(self) | ||||
|
||||
async def shutdown(self): | ||||
"""Shutdown server.""" | ||||
await self.server_close() | ||||
|
||||
async def server_close(self): | ||||
"""Close server.""" | ||||
if not self.serving.done(): | ||||
self.serving.set_result(True) | ||||
|
@@ -556,19 +551,14 @@ class _serverList: | |||
:meta private: | ||||
""" | ||||
|
||||
active_server: ModbusTcpServer | ModbusUdpServer | ModbusSerialServer | ||||
|
||||
def __init__(self, server): | ||||
"""Register new server.""" | ||||
self.server = server | ||||
self.loop = asyncio.get_event_loop() | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We do need to register the server, that is sort of the whole purpose of the class (keep track of multiple servers). it used in line 596 and can not be undefined (its interesting that the linters do not complain in line 596, since the class no longer have a loop variable. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. They do not complain because each server has already has pymodbus/pymodbus/server/async_io.py Line 267 in fe809d9
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. aah...but we still need to register the server (or somehow have a list somewhere). |
||||
active_server: ModbusTcpServer | ModbusUdpServer | ModbusSerialServer | None | ||||
|
||||
@classmethod | ||||
async def run(cls, server, custom_functions): | ||||
"""Help starting/stopping server.""" | ||||
for func in custom_functions: | ||||
server.decoder.register(func) | ||||
cls.active_server = _serverList(server) | ||||
cls.active_server = server | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is how we build a list of servers, shortcutting that means no list of servers. |
||||
with suppress(asyncio.exceptions.CancelledError): | ||||
await server.serve_forever() | ||||
|
||||
|
@@ -577,11 +567,7 @@ async def async_stop(cls): | |||
"""Wait for server stop.""" | ||||
if not cls.active_server: | ||||
raise RuntimeError("ServerAsyncStop called without server task active.") | ||||
await cls.active_server.server.shutdown() | ||||
if os.name == "nt": | ||||
alexrudd2 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||
await asyncio.sleep(1) | ||||
else: | ||||
await asyncio.sleep(0) | ||||
await cls.active_server.shutdown() | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. active_server is a _serverlist object, not the real server (name is quite confusing though). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This comment and below "These are needed to allow the async task to run" got confused because the diff view does not show the changes well. Really the changes are this: -- await cls.active_server.server.shutdown()
++ await cls.active_server.shutdown() The new code shuts down a server correctly since await cls.active_server.shutdown()
-- if os.name == "nt":
-- await asyncio.sleep(1)
-- else:
-- await asyncio.sleep(0) I do not see why the sleeps are "needed to allow the asyncio tasks to run". The There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We have had severe problems in the past, but not forcing a task switch which is essentially what asyncio.sleep(0) does. Not having a task switch mean e.g. that the task is cancelled but not yet terminated, not always but sometimes (especially on windows). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So you are saying there are no reason to keep a list of active servers, but then we could remove _server_list totally. _server_list was build to maintain a list of active server, which comes handy when debugging...I do not like to keep _server_list without the list. |
||||
cls.active_server = None | ||||
|
||||
@classmethod | ||||
|
@@ -593,11 +579,8 @@ def stop(cls): | |||
if not cls.active_server.loop.is_running(): | ||||
Log.info("ServerStop called with loop stopped.") | ||||
return | ||||
asyncio.run_coroutine_threadsafe(cls.async_stop(), cls.active_server.loop) | ||||
if os.name == "nt": | ||||
time.sleep(10) | ||||
else: | ||||
time.sleep(0.1) | ||||
future = asyncio.run_coroutine_threadsafe(cls.async_stop(), cls.active_server.loop) | ||||
future.result(timeout=10 if os.name == 'nt' else 0.1) | ||||
alexrudd2 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||
|
||||
|
||||
async def StartAsyncTcpServer( # pylint: disable=invalid-name,dangerous-default-value | ||||
|
Uh oh!
There was an error while loading. Please reload this page.