When a proxy of a pydase client initialised with
block_until_connected=False is set as an attribute of a data service, a
race condition can happen: when the client connects while the
DataServiceObserver is being initialised, the property_deps_dict
attribute might not be set yet while the DataServiceObserver was already
added as an observer to the client proxy. The proxy will then emit a
notification, which in turn tries to get the dependent properties from
the property_deps_dict attribute, which has not been initialised yet.
The resulting exception will not tell the proxy that the client has
connected.
An exception that was instantiated without any argument could not be
serilaized before. Now, I check if any args were supplied and set the
value to an empty string if no args were passed.
If False, this disables automatic updates from the server by not
subscribing to the "nofity" event. This is useful for request-only where
real-time synchronization is not needed.
The proxy needs to properly handle serialization requests. If such a
requests comes from the asyncio loop used by the socketio client, this
would result in a deadlock. This happens, for example, when the observer
is notified of a change triggered within a socketio event. To prevent
this, I am checking the current loop against the socketio client loop.
If it's the same, return the _service_representation value, which is set
when pydase.Client connects to the server. I do the same when the client
is not connected (to prevent BadNamespaceErrors).
Every other invokation of serialize results in an API call to the
server.
The WebServer can be initialised in the pydase.Server constructor
without any problems. This would allow users to access the socketio
server before starting the pydase.Server.
Before emitting sio events in the SocketIOHandler, I have to check if
the loop is actually still running. This caused issues with pytest as
pytest was tearing down asyncio tasks and stopping the loop, while the
sio handler was still trying to send those logs to the sio clients.
- always initialise the WebServer (also if enable_web is False).
Otherwise, the socketio server will not be initialised
- passing the enable_web argument to the WebServer which is then used to
decide whether to add the frontend routes