如何估算Hangfire

时间:2016-11-17 10:09:33

标签: c# hangfire

我有一个应用程序,它使用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数据库中停留。是否有更好的方法?),但为了给出正确的估计,我需要知道工作的位置。队列。我怎么做到的?

1 个答案:

答案 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