如何在Hangfire中近似工作完成时间

本文关键字:工作 时间 Hangfire | 更新日期: 2023-09-27 18:18:17

我有一个应用程序,它使用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数据库中徘徊。是否有更好的方法?),但为了给出一个适当的估计,我需要知道该作业在队列中的位置。我怎么得到它?

如何在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