Example #1
0
 def __init__(
     self, dispatcher_fiber: Any, object_factory: Any, driver_executable: Path
 ) -> None:
     self._dispatcher_fiber: Any = dispatcher_fiber
     self._transport = Transport(driver_executable)
     self._transport.on_message = lambda msg: self._dispatch(msg)
     self._waiting_for_object: Dict[str, Any] = {}
     self._last_id = 0
     self._objects: Dict[str, ChannelOwner] = {}
     self._callbacks: Dict[int, ProtocolCallback] = {}
     self._object_factory = object_factory
     self._is_sync = False
Example #2
0
 def __init__(
     self,
     input: asyncio.StreamReader,
     output: asyncio.StreamWriter,
     object_factory: Any,
     loop: asyncio.AbstractEventLoop,
 ) -> None:
     self._transport = Transport(input, output, loop)
     self._transport.on_message = lambda msg: self._dispatch(msg)
     self._waiting_for_object: Dict[str, Any] = {}
     self._last_id = 0
     self._loop = loop
     self._objects: Dict[str, ChannelOwner] = {}
     self._callbacks: Dict[int, ProtocolCallback] = {}
     self._root_object = RootChannelOwner(self)
     self._object_factory = object_factory
     self._is_sync = False
Example #3
0
 def __init__(
     self,
     input: asyncio.StreamReader,
     output: asyncio.StreamWriter,
     object_factory: Any,
     loop: asyncio.AbstractEventLoop,
 ) -> None:
     self._transport = Transport(input, output, loop)
     self._transport.on_message = lambda msg: self._dispatch(msg)
     self._waiting_for_object: Dict[str, Any] = dict()
     self._last_id = 0
     self._loop = loop
     self._objects: Dict[str, ChannelOwner] = dict()
     self._scopes: Dict[str, ConnectionScope] = dict()
     self._callbacks: Dict[int, ProtocolCallback] = dict()
     self._root_scope = self.create_scope("", None)
     self._object_factory = object_factory
Example #4
0
class Connection:
    def __init__(
        self,
        input: asyncio.StreamReader,
        output: asyncio.StreamWriter,
        object_factory: Any,
        loop: asyncio.AbstractEventLoop,
    ) -> None:
        self._transport = Transport(input, output, loop)
        self._transport.on_message = lambda msg: self._dispatch(msg)
        self._waiting_for_object: Dict[str, Any] = {}
        self._last_id = 0
        self._loop = loop
        self._objects: Dict[str, ChannelOwner] = {}
        self._callbacks: Dict[int, ProtocolCallback] = {}
        self._root_object = RootChannelOwner(self)
        self._object_factory = object_factory
        self._is_sync = False

    def run_sync(self) -> None:
        self._is_sync = True
        self._transport.run_sync()

    def run_async(self) -> None:
        self._transport.run_async()

    def stop_sync(self) -> None:
        self._transport.stop()
        dispatcher_fiber().switch()

    def stop_async(self) -> None:
        self._transport.stop()

    async def wait_for_object_with_known_name(self, guid: str) -> Any:
        if guid in self._objects:
            return self._objects[guid]
        callback = self._loop.create_future()

        def callback_wrapper(result: Any) -> None:
            callback.set_result(result)

        self._waiting_for_object[guid] = callback_wrapper
        return await callback

    def call_on_object_with_known_name(
            self, guid: str, callback: Callable[[Any], None]) -> None:
        self._waiting_for_object[guid] = callback

    def _send_message_to_server(self, guid: str, method: str,
                                params: Dict) -> ProtocolCallback:
        self._last_id += 1
        id = self._last_id
        message = dict(
            id=id,
            guid=guid,
            method=method,
            params=self._replace_channels_with_guids(params),
        )
        self._transport.send(message)
        callback = ProtocolCallback(self._loop)
        self._callbacks[id] = callback
        return callback

    def _dispatch(self, msg: ParsedMessagePayload) -> None:
        id = msg.get("id")
        if id:
            callback = self._callbacks.pop(id)
            error = msg.get("error")
            if error:
                parsed_error = parse_error(error["error"])  # type: ignore
                parsed_error.stack = callback.stack_trace
                callback.future.set_exception(parsed_error)
            else:
                result = self._replace_guids_with_channels(msg.get("result"))
                callback.future.set_result(result)
            return

        guid = msg["guid"]
        method = msg.get("method")
        params = msg["params"]
        if method == "__create__":
            parent = self._objects[guid]
            self._create_remote_object(parent, params["type"], params["guid"],
                                       params["initializer"])
            return
        if method == "__dispose__":
            self._objects[guid]._dispose()
            return

        object = self._objects[guid]
        try:
            if self._is_sync:
                for listener in object._channel.listeners(method):
                    g = greenlet(listener)
                    g.switch(self._replace_guids_with_channels(params))
            else:
                object._channel.emit(method,
                                     self._replace_guids_with_channels(params))
        except Exception:
            print(
                "Error dispatching the event",
                "".join(traceback.format_exception(*sys.exc_info())),
            )

    def _create_remote_object(self, parent: ChannelOwner, type: str, guid: str,
                              initializer: Dict) -> Any:
        result: ChannelOwner
        initializer = self._replace_guids_with_channels(initializer)
        result = self._object_factory(parent, type, guid, initializer)
        if guid in self._waiting_for_object:
            self._waiting_for_object.pop(guid)(result)
        return result

    def _replace_channels_with_guids(self, payload: Any) -> Any:
        if payload is None:
            return payload
        if isinstance(payload, list):
            return list(
                map(lambda p: self._replace_channels_with_guids(p), payload))
        if isinstance(payload, Channel):
            return dict(guid=payload._guid)
        if isinstance(payload, dict):
            result = {}
            for key in payload:
                result[key] = self._replace_channels_with_guids(payload[key])
            return result
        return payload

    def _replace_guids_with_channels(self, payload: Any) -> Any:
        if payload is None:
            return payload
        if isinstance(payload, list):
            return list(
                map(lambda p: self._replace_guids_with_channels(p), payload))
        if isinstance(payload, dict):
            if payload.get("guid") in self._objects:
                return self._objects[payload["guid"]]._channel
            result = {}
            for key in payload:
                result[key] = self._replace_guids_with_channels(payload[key])
            return result
        return payload
Example #5
0
class Connection:
    def __init__(
        self,
        input: asyncio.StreamReader,
        output: asyncio.StreamWriter,
        object_factory: Any,
        loop: asyncio.AbstractEventLoop,
    ) -> None:
        self._transport = Transport(input, output, loop)
        self._transport.on_message = lambda msg: self._dispatch(msg)
        self._waiting_for_object: Dict[str, Any] = dict()
        self._last_id = 0
        self._loop = loop
        self._objects: Dict[str, ChannelOwner] = dict()
        self._scopes: Dict[str, ConnectionScope] = dict()
        self._callbacks: Dict[int, ProtocolCallback] = dict()
        self._root_scope = self.create_scope("", None)
        self._object_factory = object_factory

    async def wait_for_object_with_known_name(self, guid: str) -> Any:
        if guid in self._objects:
            return self._objects[guid]
        callback = self._loop.create_future()
        self._waiting_for_object[guid] = callback
        return await callback

    async def _send_message_to_server(self, guid: str, method: str,
                                      params: Dict) -> Any:
        self._last_id += 1
        id = self._last_id
        message = dict(
            id=id,
            guid=guid,
            method=method,
            params=self._replace_channels_with_guids(params),
        )
        self._transport.send(message)
        callback = ProtocolCallback(self._loop)
        self._callbacks[id] = callback
        return await callback.future

    def _dispatch(self, msg: ParsedMessagePayload) -> None:

        id = msg.get("id")
        if id:
            callback = self._callbacks.pop(id)
            error = msg.get("error")
            if error:
                parsed_error = parse_error(error)
                parsed_error.stack = callback.stack_trace
                callback.future.set_exception(parsed_error)
            else:
                result = self._replace_guids_with_channels(msg.get("result"))
                callback.future.set_result(result)
            return

        guid = msg["guid"]
        method = msg.get("method")
        params = msg["params"]
        if method == "__create__":
            scope = self._scopes[guid]
            scope.create_remote_object(params["type"], params["guid"],
                                       params["initializer"])
            return

        object = self._objects[guid]
        object._channel.emit(method, self._replace_guids_with_channels(params))

    def _replace_channels_with_guids(self, payload: Any) -> Any:
        if payload is None:
            return payload
        if isinstance(payload, list):
            return list(
                map(lambda p: self._replace_channels_with_guids(p), payload))
        if isinstance(payload, Channel):
            return dict(guid=payload._guid)
        if isinstance(payload, dict):
            result = dict()
            for key in payload:
                result[key] = self._replace_channels_with_guids(payload[key])
            return result
        return payload

    def _replace_guids_with_channels(self, payload: Any) -> Any:
        if payload is None:
            return payload
        if isinstance(payload, list):
            return list(
                map(lambda p: self._replace_guids_with_channels(p), payload))
        if isinstance(payload, dict):
            if payload.get("guid") in self._objects:
                return self._objects[payload["guid"]]._channel
            result = dict()
            for key in payload:
                result[key] = self._replace_guids_with_channels(payload[key])
            return result
        return payload

    def create_scope(self, guid: str,
                     parent: Optional[ConnectionScope]) -> ConnectionScope:
        scope = ConnectionScope(self, guid, parent)
        self._scopes[guid] = scope
        return scope