我想为RabbitMQ C#客户端的BasicPublish方法编写一个超时函数。由于许多原因,有时队列被阻塞,或者兔子瘫痪或其他什么。但是我想知道发布何时立即失败。我不想出于任何原因阻止该网站。
我担心使用Task或线程为简单发布增加开销来实现超时,我们在生产中已经做了数百万次。
有没有人知道如何在快速阻止方法上写一个快速超时作为BasicPublish?
澄清:我也在.Net 4工作,我没有异步。
答案 0 :(得分:1)
Polly有一个TimeoutPolicy针对这种情况。
Polly的TimeoutStrategy.Optimistic
接近@ ThiagoCustodio的答案,但它也正确处理了toggled
。然而,RabbitMQ的C#客户端(在撰写本文时)未提供var toggled = false
(document).on('click', '#target', function(e){
if(!toggled){
toggled = true
setTimeout(function(){
toggled = false
},500)
//Do stuff
}
});
过载CancellationTokenSource
,因此这种方法无关紧要。
Polly的TimeoutStrategy.Pessimistic
针对BasicPublish()
这样的情况,您希望对不 CancellationToken
支持的代理施加超时。
Polly的BasicPublish()
:
[1]允许调用线程超时(远离等待)执行,即使执行的委托不支持取消也是如此。
[2]以额外的任务/线程(在同步执行中)为代价,并为您管理。
[3]也captures the timed-out Task
(你已经离开的任务)。这对于日志记录很有用,并且必需以避免UnobservedTaskExceptions - 特别是在.NET4.0中,UnobservedTaskException can bring down your entire process。
简单示例:
CancellationToken
正确避免TimeoutStrategy.Pessimistic
的完整示例:
Policy.Timeout(TimeSpan.FromSeconds(10), TimeoutStrategy.Pessimistic).Execute(() => BasicPublish(...));
为避免在RabbitMQ不可用的情况下建立太多并发的待处理任务/线程,您可以使用Bulkhead Isolation policy来限制并行化和/或CircuitBreaker以防止通过调用一旦你发现了一定程度的失败。这些可以使用PolicyWrap
与TimeoutPolicy结合使用。
答案 1 :(得分:0)
我想说最简单的方法是使用任务/取消令牌。你认为这是一个开销吗?
public static async Task WithTimeoutAfterStart(
Func<CancellationToken, Task> operation, TimeSpan timeout)
{
var source = new CancellationTokenSource();
var task = operation(source.Token);
source.CancelAfter(timeout);
await task;
}
用法:
await WithTimeoutAfterStart(
ct => SomeOperationAsync(ct), TimeSpan.FromMilliseconds(n));