我有一个应用程序,它使用hangfire为我做长时间运行的工作(我知道工作时间和它总是大致相同),并且在我的UI中我想估计某个工作的时间已经完成了。为此,我需要查询hangfire以了解队列中作业的位置以及处理它的服务器数量。
我知道我可以通过
获得排队作业的数量(在" DEFAULT"队列中)public long JobsInQueue() {
var monitor = JobStorage.Current.GetMonitoringApi();
return monitor.EnqueuedCount("DEFAULT");
}
和
的服务器数量public int HealthyServers() {
var monitor = JobStorage.Current.GetMonitoringApi();
return monitor.Servers().Count(n => (n.Heartbeat != null) && (DateTime.Now - n.Heartbeat.Value).TotalMinutes < 5);
}
(顺便说一句:我排除了较旧的心跳,因为如果我关闭服务器,他们有时会在hangfire数据库中停留。是否有更好的方法?),但为了给出正确的估计,我需要知道工作的位置。队列。我怎么做到的?
答案 0 :(得分:2)
你遇到的问题是hangfire是异步的,排队的,并行的,表现出至少一次的持久性语义,而且基本上是非确定性的。
要确切知道在这样的系统中完成项目处理的顺序是不可能的。事实上,如果要求是强制执行严格的排序,那么hangfire的许多好处都会消失。
@odinserj(hangfire的作者)有一篇非常好的博客文章,他概述了这一点:http://odinserj.net/2014/05/10/are-your-methods-ready-to-run-in-background/
然而,也就是说,提出合理的估算算法并非不可能,但它必须是以某种方式近似执行顺序的算法。至于你如何得到这样的算法,我不知道,但像这样的可能工作(但可能不会):
Approximate seconds remaining until completion =
(
(average duration of job in seconds * queue depth)
/ (the lower of: number of hangfire threads OR queue depth)
)
- number of seconds already spent in queue
+ average duration of job in seconds