【问题标题】:How to approximate job completion times in Hangfire如何在 Hangfire 中估算工作完成时间
【发布时间】:2016-11-17 10:09:33
【问题描述】:

我有一个应用程序,它使用 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 中估算工作完成时间”
  • @TomRedfern:谢谢,好主意。完成。

标签: c# hangfire


【解决方案1】:

您遇到的问题是,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

【讨论】:

  • 感谢您的回答。我知道异步方式,我只需要大概的时间。如果一项工作需要一分钟(包括延迟),并且我有 12 台服务器,那么如果我在队列中排在第 15 位 - 即使有 500 个工作 - 我可以假设我的工作在 2-3 分钟内完成。尽管服务器尽可能地抓取作业,但我认为它们不是随机抓取的,作业中有顺序,还是我弄错了?
  • @EluciusFTW - 这取决于hangfire 如何决定在多服务器环境中接下来处理哪些作业。它可能就像接下来完成最古老的未处理工作一样简单,但它可能是更复杂的行为。我想找到这些信息的一种方法是查询hangfire DB。但是,这不是很有未来性。
  • @EluciusFTW - 如果您确实想出了一个可行的方法,请记住在此处发布。我很想在未来使用它!
猜你喜欢
  • 2011-11-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多