question

Nate Breeden avatar image
Nate Breeden asked Nate Breeden commented

C# Rate Limiting / Auto Retry Question

Trying to implement auto-retry, or at least utilize the rate limiting header from responses on my program to wait so I do not exceed the limit.

Originally I was trying to utilize the header to find the current rate, then wait if it was about to exceed. But what I noticed was not all calls return a header for some reason? For example below the below call, it doesn't allow me to see the header so that I can see the what the returned rate is to wait on my next call.

ListCallQueuesParameters listCallQueuesParameters = new ListCallQueuesParameters
{
    perPage = 100,
    memberExtensionId = emailCheck.records[0].id.ToString()
};
var callQueues = await rc.Restapi("v1.0").Account("~").CallQueues().List(listCallQueuesParameters);

Digging through and I've found where in SDK 4.0 beta there was "Auto Retry" and "Rate Limit Helper" features. Was that ever implemented? I see in Nuget package manager there is a "RingCentral.Net.Retry" and "RingCentral.Net.RateLimit", is there documentation on utilizing these?

When reading the 4.0 beta feature document, the examples do not line up with those Nugets so here is what I tried - but I'm not sure if this is correct nor if I need more than just the below to make it work properly(Found most of the below when Googling the Nuget).

When testing after implementing these, it seems like the below code is working but I end up receiving the below error

(Code below is added after "var rc =")

var retryExtension = new RetryExtension();
retryExtension.enabled = true;
await rc.InstallExtension(retryExtension);

var rateLimitExtension = new RateLimitExtension();
rateLimitExtension.enabled = true;
await rc.InstallExtension(rateLimitExtension);

Also did this, but not even sure what it does, just shooting in the dark lol (probably redundant):

var rcExtList = new System.Collections.Generic.List<RingCentral.SdkExtension> { };
rcExtList.Add(rateLimitExtension);
rcExtList.Add(retryExtension);
rc.sdkExtensions = rcExtList;

Error received after wait:

See the end of this message for details on invoking 
just-in-time (JIT) debugging instead of this dialog box.

************** Exception Text **************
System.InvalidOperationException: The request message was already sent. Cannot send the same request message multiple times.
   at System.Net.Http.HttpClient.CheckRequestMessage(HttpRequestMessage request)
   at System.Net.Http.HttpClient.SendAsync(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at RingCentral.RestClient.<Request>d__31.MoveNext()

That was when making this call:

ReadAccountPresenceParameters readAccountPresenceParameters = new ReadAccountPresenceParameters
{
    perPage = 200
};
var dndList = await rc.Restapi("v1.0").Account("~").Presence().Get(readAccountPresenceParameters);


Sorry if this is covered somewhere, I searched and was not able to find an up-to-date document/article

sdkrate limits
1 |3000

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

1 Answer

Tyler Liu avatar image
Tyler Liu answered Nate Breeden commented

For rate limit handling, please refer to https://github.com/ringcentral/RingCentral.Net/tree/master/RingCentral.Net.RateLimit

Source code is very short: https://github.com/ringcentral/RingCentral.Net/blob/master/RingCentral.Net.RateLimit/RateLimitExtension.cs

RingCentral.Net.RateLimit is built on top of https://github.com/ringcentral/RingCentral.Net/tree/master/RingCentral.Net.Retry

Note a lot of people are aware of these extensions. So you may deem them as beta or as reference for your own implementation.

Kindly have a try and provide feedbacks, thanks.


5 comments
1 |3000

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

Tyler Liu avatar image Tyler Liu ♦ commented ·

There is a demo application in TypeScript https://github.com/tylerlong/export-rc-sms-data/blob/master/src/index.ts

In theory, the C# version works the same way. Let us know if it doesn't work as expected.

0 Likes 0 ·
Nate Breeden avatar image Nate Breeden Tyler Liu ♦ commented ·

Thanks for the response Tyler, tested some more with it last night and it does seem to work as expected. However, about <10% of the time I get the below error after a long wait, I'm assuming the other >90% of the time it works because I make a good amount of calls in a short amount of time and there appears to be a short wait after the max is reached. When receiving the error the wait time is much greater (about 30-60 seconds) prior to the error appearing.


Is there a way around this error, if not it's not the end of the world as it appears to work more than not.


Error:

System.InvalidOperationException: The request message was already sent. Cannot send the same request message multiple times.
   at System.Net.Http.HttpClient.CheckRequestMessage(HttpRequestMessage request)
   at System.Net.Http.HttpClient.SendAsync(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at RingCentral.RestClient.<Request>d__31.MoveNext()

Call example:

ReadAccountPresenceParameters readAccountPresenceParameters = new ReadAccountPresenceParameters
{
    perPage = 200
};
var dndList = await rc.Restapi("v1.0").Account("~").Presence().Get(readAccountPresenceParameters);


Side note, the extension is pretty awesome as it is easily implemented - thanks for the hard work you all do.

0 Likes 0 ·
Tyler Liu avatar image Tyler Liu ♦ Nate Breeden commented ·

I released a new version https://github.com/ringcentral/RingCentral.Net/commit/7d5b4d53216c83e4db7a1b60c3f53286b3a1714f

Please kindly try again.

The extension is current experimental, feel free to provide feedbacks.

1 Like 1 ·
Show more comments
Show more comments

Developer sandbox tools

Using the RingCentral Phone for Desktop, you can dial or receive test calls, send and receive test SMS or Fax messages in your sandbox environment.

Download RingCentral Phone for Desktop:

Tip: switch to the "sandbox mode" before logging in the app:

  • On MacOS: press "fn + command + f2" keys
  • On Windows: press "Ctrl + F2" keys