Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The async for natsConnection_RequestString #449

Open
portsip opened this issue Aug 4, 2021 · 8 comments
Open

The async for natsConnection_RequestString #449

portsip opened this issue Aug 4, 2021 · 8 comments

Comments

@portsip
Copy link

portsip commented Aug 4, 2021

Feature Request

Currently, I see there have the natsConnection_RequestString with a given timeout in MS, can it has an async version? Likes
natsConnection_RequestString(&reply, nc, "foo", "help", callback, 1000);
Once received the reply in 1000 MS or its timeout, the callback will be triggered.

Use Case:

For some large amounts of the sync call will cause the thread blocked

Proposed Change:

Add a callback parameter to the natsConnection_RequestString.

Who Benefits From The Change(s)?

Alternative Approaches

@derekcollison
Copy link
Member

Is this for the server or a specific client language?

@portsip
Copy link
Author

portsip commented Aug 4, 2021

Is this for the server or a specific client language?

For the C language client.

Thanks

@derekcollison
Copy link
Member

ok will move this over to there.

@derekcollison derekcollison transferred this issue from nats-io/nats-server Aug 4, 2021
@kozlovic kozlovic closed this as completed Aug 4, 2021
@kozlovic kozlovic reopened this Aug 4, 2021
@kozlovic
Copy link
Member

kozlovic commented Aug 4, 2021

The C client already provides a way to create an async subscription that times out. See natsConnection_SubscribeTimeout. So you could create a subscription on a wildcard subject, and publish your requests using natsConnection_PublishRequestString with a unique token at the end of the reply subject.

Take note of the behavior of the async subscription timeout in the doc. That is, the callback will be invoked with a NULL message if no message is received in the timeout interval specified when creating the subscription. Receiving a message reset this interval, etc..

@calvin2021y
Copy link

calvin2021y commented Nov 19, 2024

@kozlovic

In your case, If I send multi message to multi consumer in async style, how to tell which one is timeout or drop by any kind error.

edit:

I see there is jsPubAckErrHandler, the jsPubAckErr.Msg could be used to know which one get error.

If there is a void* context or data, to allow the client handle the related logic will be perfect.

@kozlovic
Copy link
Member

@calvin2021y The API you reference in your edit are related to JetStream, which is not really a good fit for request/reply patterns (since by definition, a message sent to JS is persisted, which means that the request would be persisted, which is often not the desired outcome).

At this time we don't have an "async request" API, and unless the dev team judge that this is something needed and is going to be implemented (we try to have some consistency between clients, so I would expect then the Go client to have such feature, etc), then your best approach was I described above, that is, setup your own async subscription (with timeout) to receive the reply. You would have to take care of the closure yourself (that is, store it somewhere where it can be retried with the reply's subject maybe being the key). Again, I understand that this is not something that the end user would want to implement, but the fact is that we don't have such API at the moment.

Note: I see that you have posted on several different issues, and I realize that you are using event loop, and as you have realized by now, any "blocking" request/reply won't play well with an event loop. Since I saw that you referenced JetStream, know that the core but even more the JetStream part of the library uses a lot of "blocking" internal request/replies. That is, lots of JetStream APIs would not work because they are internally using request/reply to communicate with the server.

@calvin2021y
Copy link

Thank you for your detailed explanation! I appreciate your clarification on JetStream’s design and its lack of suitability for request/reply patterns due to the persistence aspect. I understand now that JetStream’s approach inherently makes it less ideal for scenarios where transient messaging is preferred.

The lack of an "async request" API at the moment is unfortunate but understandable, given the consistency goals across different client implementations. Your suggested workaround of setting up an async subscription with a timeout and managing closures manually is very helpful, even if it introduces some additional implementation complexity. I’ll take your advice into consideration while planning my approach.

Lastly, your note about the internal blocking request/reply behavior, especially when working within an event loop, is particularly insightful. It’s clear that this limitation would impact certain use cases significantly, especially when using JetStream APIs. I appreciate the heads-up and will keep this in mind while integrating the library.

@derekcollison
Copy link
Member

You can always setup and inbox or other reply subject and do a publish with this reply that you have a subscription to that will fire the callback when the response arrives and not block in place.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants