简体   繁体   中英

AMQP.Net Credit doesn't seem to work as expected

I am having a problem fully understanding the “credit” property used with AMQP.Net. The way it reads it appears that it can be used to prevent the sender queuing up too much data. If I set the credit to a low value, when the credit runs out the “ResponseLink.Closed” event fires and the process stops. What I would like to do is to set a credit so that when the receiver is overwhelmed, the sender can pause to allow the receiver to catch-up a bit and then start sending again from where it left off. At the moment, the sender is queuing up so much data that the computer runs out of memory as the receiver is running slow. Is this possible by using credit or should an alternative solution need to be used?

Update

The way I am using AMQP.Net at the moment is that the client makes a call to the server requesting that data is sent of a certain type. The server makes a call to the database and gets back a very large list of data. This data is then sent to the client from a foreach loop using:

requestContext.Complete( ** an item of data goes in here **)

The client is getting these via the OnMessage event at its end. Because the send is quicker than the client can handle them, the memory usage grows quickly. How is it possible to get some feedback on the server side to know when the client has handled n number of messages so that it can pause before sending more?

The update gives a better description of how you use the library and the problem you are running into. Depending what you have in the request message, there are two solutions you can try.

  1. if you always have a lot of data for a client request, you can switch to use a single receiver link from the client. On the listener side, you register a link processor (ILinkProcessor) and create a SourceLinkEndpoint when receiving a link attach request. You can pass request specific data in attach.properties when you create the link. You will also need to implement the IMessageSource interface. The library will invoke your method implementations on flow and acknowledgement events. In the GetMessageAsync method you can query the database to get the data that fits in just one message, or a list of items to fill a in-memory cache from which the GetMessageAsync call is served. You close the link after all data is transferred. In this model, the AMQP link flow control will take place in message transfer and you have full control of how much memory can be used for a link.

  2. If you prefer the request/response model, you would need to implement some paging logic to avoid high memory consumption on the listener side. The request/response pattern is build on top of the standard AMQP message transfer using a pair of links. The flow control in one link is independent of the other and cannot be used to coordinate transfers of request and response messages. Instead of serving all data to one client request, you could send requests more frequently and serve only a fixed-size (or number) of messages to each request.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM