C# 如何使用可观测数据构建速率限制API?
我想创建一个简单的计算器服务,它有一个单一的方法来添加数字。这个C# 如何使用可观测数据构建速率限制API?,c#,.net,async-await,system.reactive,rate-limiting,C#,.net,Async Await,System.reactive,Rate Limiting,我想创建一个简单的计算器服务,它有一个单一的方法来添加数字。这个Add方法应该是async,并且必须限制在给定时间进行的并发调用的数量。例如,每秒并发调用不超过5次。如果超过速率限制,调用将引发异常 课程应该是这样的: public class RateLimitingCalculator { public async Task<int> Add(int a, int b) { //... } } 公共类费率限制计算器 { 公共异步任务添加
Add
方法应该是async
,并且必须限制在给定时间进行的并发调用的数量。例如,每秒并发调用不超过5次。如果超过速率限制,调用将引发异常
课程应该是这样的:
public class RateLimitingCalculator
{
public async Task<int> Add(int a, int b)
{
//...
}
}
公共类费率限制计算器
{
公共异步任务添加(int a、int b)
{
//...
}
}
有什么想法吗?我想用反应式扩展实现它,但如果使用另一种策略更好,我会坚持下去 我认为在这里使用Rx没有意义,除非您可以将您的方法重写为类似于
public IObservable Add(IObservable values)
,正如Enigmativity在评论中所建议的那样
我要做的是将利率限制问题分为一个单独的类别。这样,您的代码可以如下所示:
public class RateLimitingCalculator
{
private RateLimiter rateLimiter = new RateLimiter(5, TimeSpan.FromSeconds(1));
public async Task<int> Add(int a, int b)
{
rateLimiter.ThrowIfRateExceeded();
//...
}
}
class RateLimiter
{
private readonly int rate;
private readonly TimeSpan perTime;
private DateTime secondStart = DateTime.MinValue;
private int count = 0;
public RateLimiter(int rate, TimeSpan perTime)
{
this.rate = rate;
this.perTime = perTime;
}
public void ThrowIfRateExceeded()
{
var now = DateTime.UtcNow;
if (now - secondStart > perTime)
{
secondStart = now;
count = 1;
return;
}
if (count >= rate)
throw new RateLimitExceededException();
count++;
}
}
有些想法可能会对你有所帮助。你真的应该避免混合单子。我认为如果你有这样一个签名,就更容易解释清楚了:
public-IObservable-Add(IObservable-values)
@Enigmativity“避免混合monad”是什么意思?另外,您认为使用Rx对API进行速率限制有意义吗?@SuperJMN-IObservable
和Task
都是单子。它们是“超级类型”,接受底层的T
,并赋予其超级能力。如果你呆在你的单子里,那么一切都很好,但是如果你在两个单子之间走,那么你可能会出错。所以我会避免尝试使用一个单子(Rx)来限制另一个(TPL)。请继续使用Rx,它拥有速率限制所需的所有运算符。每秒不超过5个并发调用我还希望以尽可能透明的方式使用速率限制API来执行相反的操作:。也许你能帮忙。非常感谢!我更喜欢使用秒表
而不是DateTime.UtcNow
来测量时间间隔。它更轻,并保证始终向前推进。DateTime.UtcNow
会根据系统进行调整,因此可以向后移动。