mirror of
https://github.com/RYGhub/royalnet.git
synced 2024-11-27 13:34:28 +00:00
A lot of improvements
This commit is contained in:
parent
e34b4998fd
commit
baef26b671
5 changed files with 21 additions and 25 deletions
|
@ -3,7 +3,7 @@ from .errors import HeraldError, ConnectionClosedError, LinkError, InvalidServer
|
||||||
from .link import Link
|
from .link import Link
|
||||||
from .package import Package
|
from .package import Package
|
||||||
from .request import Request
|
from .request import Request
|
||||||
from .response import ResponseSuccess, ResponseFailure
|
from .response import Response, ResponseSuccess, ResponseFailure
|
||||||
from .server import Server
|
from .server import Server
|
||||||
|
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ __all__ = [
|
||||||
"Link",
|
"Link",
|
||||||
"Package",
|
"Package",
|
||||||
"Request",
|
"Request",
|
||||||
|
"Response",
|
||||||
"ResponseSuccess",
|
"ResponseSuccess",
|
||||||
"ResponseFailure",
|
"ResponseFailure",
|
||||||
"Server",
|
"Server",
|
||||||
|
|
|
@ -16,7 +16,3 @@ class ConnectionClosedError(LinkError):
|
||||||
|
|
||||||
class InvalidServerResponseError(LinkError):
|
class InvalidServerResponseError(LinkError):
|
||||||
"""The :py:class:`Server` sent invalid data to the :py:class:`Link`."""
|
"""The :py:class:`Server` sent invalid data to the :py:class:`Link`."""
|
||||||
|
|
||||||
|
|
||||||
class ResponseError(LinkError):
|
|
||||||
"""The :py:class:`Response` was an error, and raise_on_error is :py:const:`True`."""
|
|
||||||
|
|
|
@ -2,11 +2,11 @@ import asyncio
|
||||||
import websockets
|
import websockets
|
||||||
import uuid
|
import uuid
|
||||||
import functools
|
import functools
|
||||||
import math
|
|
||||||
import numbers
|
|
||||||
import logging as _logging
|
import logging as _logging
|
||||||
import typing
|
import typing
|
||||||
from .package import Package
|
from .package import Package
|
||||||
|
from .request import Request
|
||||||
|
from .response import Response, ResponseSuccess, ResponseFailure
|
||||||
from .errors import ConnectionClosedError, InvalidServerResponseError
|
from .errors import ConnectionClosedError, InvalidServerResponseError
|
||||||
|
|
||||||
|
|
||||||
|
@ -58,7 +58,8 @@ class Link:
|
||||||
self.nid: str = str(uuid.uuid4())
|
self.nid: str = str(uuid.uuid4())
|
||||||
self.secret: str = secret
|
self.secret: str = secret
|
||||||
self.websocket: typing.Optional[websockets.WebSocketClientProtocol] = None
|
self.websocket: typing.Optional[websockets.WebSocketClientProtocol] = None
|
||||||
self.request_handler = request_handler
|
# Not sure on the type annotation here
|
||||||
|
self.request_handler: typing.Callable[[Request], typing.Awaitable[Response]] = request_handler
|
||||||
self._pending_requests: typing.Dict[str, PendingRequest] = {}
|
self._pending_requests: typing.Dict[str, PendingRequest] = {}
|
||||||
if loop is None:
|
if loop is None:
|
||||||
self._loop = asyncio.get_event_loop()
|
self._loop = asyncio.get_event_loop()
|
||||||
|
@ -127,15 +128,20 @@ class Link:
|
||||||
log.debug(f"Sent package: {package}")
|
log.debug(f"Sent package: {package}")
|
||||||
|
|
||||||
@requires_identification
|
@requires_identification
|
||||||
async def request(self, message, destination):
|
async def request(self, destination: str, request: Request) -> Response:
|
||||||
package = Package(message, source=self.nid, destination=destination)
|
package = Package(request.to_dict(), source=self.nid, destination=destination)
|
||||||
request = PendingRequest(loop=self._loop)
|
request = PendingRequest(loop=self._loop)
|
||||||
self._pending_requests[package.source_conv_id] = request
|
self._pending_requests[package.source_conv_id] = request
|
||||||
await self.send(package)
|
await self.send(package)
|
||||||
log.debug(f"Sent request: {message} -> {destination}")
|
log.debug(f"Sent to {destination}: {request}")
|
||||||
await request.event.wait()
|
await request.event.wait()
|
||||||
response: dict = request.data
|
if request.data["type"] == "ResponseSuccess":
|
||||||
log.debug(f"Received response: {request} -> {response}")
|
response: Response = ResponseSuccess.from_dict(request.data)
|
||||||
|
elif request.data["type"] == "ResponseFailure":
|
||||||
|
response: Response = ResponseFailure.from_dict(request.data)
|
||||||
|
else:
|
||||||
|
raise TypeError("Unknown response type")
|
||||||
|
log.debug(f"Received from {destination}: {request} -> {response}")
|
||||||
return response
|
return response
|
||||||
|
|
||||||
async def run(self):
|
async def run(self):
|
||||||
|
@ -157,7 +163,7 @@ class Link:
|
||||||
# Package is a request
|
# Package is a request
|
||||||
assert isinstance(package, Package)
|
assert isinstance(package, Package)
|
||||||
log.debug(f"Received request {package.source_conv_id}: {package}")
|
log.debug(f"Received request {package.source_conv_id}: {package}")
|
||||||
response = await self.request_handler(package.data)
|
response: Response = await self.request_handler(Request.from_dict(package.data))
|
||||||
response_package: Package = package.reply(response)
|
response_package: Package = package.reply(response.to_dict())
|
||||||
await self.send(response_package)
|
await self.send(response_package)
|
||||||
log.debug(f"Replied to request {response_package.source_conv_id}: {response_package}")
|
log.debug(f"Replied to request {response_package.source_conv_id}: {response_package}")
|
||||||
|
|
|
@ -25,10 +25,6 @@ class Response:
|
||||||
# noinspection PyArgumentList
|
# noinspection PyArgumentList
|
||||||
return cls(**d)
|
return cls(**d)
|
||||||
|
|
||||||
def raise_on_error(self):
|
|
||||||
"""Raise an :py:exc:`ResponseError` if the Response is an error, do nothing otherwise."""
|
|
||||||
raise NotImplementedError("Please override Response.raise_on_error()")
|
|
||||||
|
|
||||||
|
|
||||||
class ResponseSuccess(Response):
|
class ResponseSuccess(Response):
|
||||||
"""A response to a successful :py:class:`Request`."""
|
"""A response to a successful :py:class:`Request`."""
|
||||||
|
@ -42,9 +38,6 @@ class ResponseSuccess(Response):
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"{self.__class__.__qualname__}(data={self.data})"
|
return f"{self.__class__.__qualname__}(data={self.data})"
|
||||||
|
|
||||||
def raise_on_error(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class ResponseFailure(Response):
|
class ResponseFailure(Response):
|
||||||
"""A response to a invalid :py:class:`Request`."""
|
"""A response to a invalid :py:class:`Request`."""
|
||||||
|
@ -56,6 +49,3 @@ class ResponseFailure(Response):
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"{self.__class__.__qualname__}(name={self.name}, description={self.description}, extra_info={self.extra_info})"
|
return f"{self.__class__.__qualname__}(name={self.name}, description={self.description}, extra_info={self.extra_info})"
|
||||||
|
|
||||||
def raise_on_error(self):
|
|
||||||
raise ResponseError(self)
|
|
||||||
|
|
|
@ -103,6 +103,9 @@ class Server:
|
||||||
# Is it nothing?
|
# Is it nothing?
|
||||||
if package.destination == "<none>":
|
if package.destination == "<none>":
|
||||||
return []
|
return []
|
||||||
|
# Is it all possible destinations?
|
||||||
|
if package.destination == "<all>":
|
||||||
|
return self.identified_clients
|
||||||
# Is it a valid nid?
|
# Is it a valid nid?
|
||||||
try:
|
try:
|
||||||
destination = str(uuid.UUID(package.destination))
|
destination = str(uuid.UUID(package.destination))
|
||||||
|
|
Loading…
Reference in a new issue