Closed pipermerriam closed 4 years ago
class ProxyAnimal(proxy.Proxy[Animal]):
name = proxy.Text()
get_sound = proxy.Method()
wait_something = proxy.AsyncMethod()
This :point_up: looks like it would mess with typing, no? How would mypy
know the correct types of get_sound
or wait_something
.
I'm also not entirely sold yet if optimizing for proxy objects is the best way forward. While it is convenient, I'm scared it would lead us back to the RPC style approach to multiprocessing that we replaced with a more explicit, event-based paradigm.
I think that there may be some middle ground where the object on the consumer side is still hand crafted in the sense of it being:
I also think that there isn't evens so much inconvenience on the consumer side today. E.g. this is an RPC module in Trinity fetching the network id via the event bus.
async def version(self) -> str:
"""
Returns the current network ID.
"""
response = await self.event_bus.request(
NetworkIdRequest(),
TO_NETWORKING_BROADCAST_CONFIG
)
return str(response.network_id)
And this could even still get simpler with https://github.com/ethereum/lahja/issues/90
I think it is more the serving side that needs more of our attention. Currently in Trinity we have the PeerPoolEventServer
that receives requests and delegates them somewhere and then wraps the response and sends it back. I think that is the bigger inconvenience we have today. Some of this may be easier if our PeerPool would just natively speak lahja so that there would simply be no need for a PeerPoolEventServer
to step in. But it could also be that we could come up with better tools that would just simplify the job of replaying events onto some methods and returning the results (and capturing exceptions).
To recap my thoughts, I'm not saying I'm against proxies, I'm just saying maybe there are other options that we should check before.
I'm no longer convinced this is a good idea.
What was wrong?
Here's a fictional API I've been thinking about.
I think this achieves the following goals.
ObjectAPI
equivalent implementations via proxy objects which should mean they are functionally interchangeable.How can it be fixed?
Not sure. One major problem is the need to interact with the event bus from both async and synchronous call sites. Things like object properties and non-
async
methods will mean that we'll be entering the endpoint APIs from a synchronous context. We can likely pull something off using threads andbroadcast_nowait
. It might be nice to have a way to interact withEndpointAPI.request
as well since everything from the client side will be a request/response.The
Text()
andMethod()
APIs would likely be descriptors which know how to access the endpoint through their parent object.A meta-class is probably going to be needed to programmatically generate event types but it may be possible to do get by with something simpler like a set of builtin events for the request/response or an internal event.