包装速率限制API调用 [英] Wrapping rate limiting API call

查看:143
本文介绍了包装速率限制API调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有访问一个API调用接受每秒呼叫的最大速率。如果超过该速率,抛出异常

I have access an API call that accepts a maximum rate of calls per second. If the rate is exceeded, an exception is thrown.

我想这个调用包装成做必要保持通话率限制下的抽象。它会像一个网络路由器:处理多个电话,并将结果返回到正确的调用者关心的拆借利率。的目标是使调用代码作为察觉尽可能有关的限制。 !否则,在具有此调用的代码的每一部分都必须裹成一个try-catch

I would like to wrap this call into an abstraction that does the necessary to keep the call rate under the limit. It would act like a network router: handling multiple calls and returning the results to the correct caller caring about the call rate. The goal is to make the calling code as unaware as possible about that limitation. Otherwise, every part in the code having this call would have to be wrapped into a try-catch!

例如:想象一下,你可以调用从可加2号一个外部API的方法。这个API可以每秒被称为 5倍。任何高于此将导致异常。

For example: Imagine that you can call a method from an extern API that can add 2 numbers. This API can be called 5 times per second. Anything higher than this will result in an exception.

为了说明这个问题,这限制了拆借利率就像一个在回答这个外部服务问题

如何建立一个限速API与观测量

其他信息:

既然你不希望有关限制的担心每次调用从代码的任何部分,这种方法的时候,你想想设计,你可以不用担心调用的包装方法限速。在里面你所关心的限制,但在外面你暴露一个简单的异步方法。

Since you don't want the worry about that limit every time you call this method from any part of your code, you think about designing a wrapper method that you could call without worrying about the rate limit. On the inside you care about the limit, but on the outside you expose a simple async method.

这是类似于一个Web服务器。它是如何结果的正确包返回到正确的客户?

It's similar to a web server. How does it return the correct pack of results to the correct customer?

多个来电会调用这个方法,因为他们来,他们将得到的结果。这种抽象应该像一个代理。

Multiple callers will call this method, and they will get the results as they come. This abstraction should act like a proxy.

我怎么能这样做呢?

我敢肯定,坚定包装的方法应该是这样的。

I'm sure the firm of the wrapper method should be like

public async Task<Results> MyMethod()

和方法内,将执行逻辑,也许使用无扩展(缓冲)。我不知道。

And inside the method it will perform the logic, maybe using Reactive Extensions (Buffer). I don't know.

但如何?我的意思是,这种方法的多次调用应该将结果返回到正确的调用者。这甚至可能?

But how? I mean, multiple calls to this method should return the results to the correct caller. Is this even possible?

感谢您了很多!

推荐答案

究竟你应该取决于你的目标和限制。我的假设:

What exactly you should depends on your goals and limitations. My assumptions:


  • 您想避免发出请求,而速度限制生效

  • 您无法预测一个特定的请求是否会被拒绝,否则将究竟如何采取再次允许其他请求

  • 您不必进行多次请求同时,当多个请求在等待,它无关紧要的次序是他们完成了

如果这些假设是正确的,你可以使用的 AsyncAutoResetEvent 从AsyncEx :在等待它被之前设置。提出请求时,设置成功后发出请求时,它的速度有限,延迟一段时间后设置

If these assumptions are valid, you could use AsyncAutoResetEvent from AsyncEx: wait for it to be set before making the request, set it after successfully making a request and set it after a delay when it's rate limited.

中的代码可以是这样的:

The code can look like this:

class RateLimitedWrapper<TException> where TException : Exception
{
    private readonly AsyncAutoResetEvent autoResetEvent = new AsyncAutoResetEvent(set: true);

    public async Task<T> Execute<T>(Func<Task<T>> func) 
    {
        while (true)
        {
            try
            {
                await autoResetEvent.WaitAsync();

                var result = await func();

                autoResetEvent.Set();

                return result;
            }
            catch (TException)
            {
                var ignored = Task.Delay(500).ContinueWith(_ => autoResetEvent.Set());
            }
        }
    }
}



用法

Usage:

public static Task<int> Add(int a, int b)
{
    return rateLimitedWrapper.Execute(() => rateLimitingCalculator.Add(a, b));
}

这篇关于包装速率限制API调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆