Closed evshary closed 7 months ago
I'm glad you're asking about this :slightly_smiling_face:
I was also unsure how this would work.
Essentially there must be a way within UTransport::register_listener()
such that we're able to receive back any replies relevant to us.
Is that possible? Are there technical challenges?
What I had imagined is that the Zenoh implementation would have to keep track of the Queryable it sent out and listen for replies over in register_listener()
. But I probably don't understand Zenoh well enough to tell if this works.
Hi @PLeVasseur
Thanks for your input!
I think the key is how to use reqid
in uAttributes to map to the corresponding reply in Zenoh.
While UTransport::receive
doesn't have this argument, we can only use UTransport::register_listener()
and put the certain reqid
into callback as a filter here, indeed.
Let me chew on it and come up with a proper way.
By the way, do you know why we added the new API UTransport::receive
and which kind of case we should use it?
I believe there's an option at uP-L1 to implement it as a push or pull mechanism.
I think the addition of receive()
is to keep up-rust
compliant with the spec, offering it as an option when implementing a up-client-foo-rust
.
From my point of view it's at a minimum an either or thing, both need not be implemented, not relevant to this implementation I think.
Thank you for the clear explanation.
Then I'll ignore receive()
and focus on register_listener()
for the time being.
Let me keep the issue open and I can update the status if I encounter any other technical issues.
@evshary when you send a request message using UTransport::send
then the request must contain
UAttributes::source
field, andUAttributes::reqid
field.So, before you send the request message, you need to make sure to register a listener for the reply-to-address. In the callback you can then compare the correlation ID.
Hi @sophokles73 Thank you for the valuable input!
What bothered me was that Zenoh has three different mechanisms for publish / request / response.
That means I need to distinguish which type we're using while calling send()
or register_listener()
This is not the problem for send()
since we can get type from uAttributes.
However, it's quite difficult for register_listener
since there is only UUri.
async fn register_listener(
&self,
topic: UUri,
listener: Box<dyn Fn(Result<UMessage, UStatus>) + Send + Sync + 'static>,
) -> Result<String, UStatus>;
But I just found out we can distinguish RPC and RPC response with the UUri validator. https://github.com/eclipse-uprotocol/up-spec/blob/main/basics/uri.adoc#3-validators Maybe this can do the magic. I'll check it in the weekend.
I think this can be closed now.
invoke_method
can get the reply UMessage from RpcClientResult (pub type RpcClientResult = Result<UMessage, RpcMapperError>;
)I'm wondering how we get the reply when we use up-l1 API
send
to comprise theinvoke_method
.After taking a look, I guess
receive
should be called after we usesend
to send out the request.async fn receive(&self, topic: UUri) -> Result<UMessage, UStatus>
However, is it possible to send multiple requests to the same topic at the same time? If yes, we'll have trouble to distinguish the mapping of request and reply.