13

Stackoverflow 有一个漂亮的徽章系统。我注意到的一件事是,徽章不会立即授予,但有时在我达到标准后似乎会有某种延迟。我在其他一些也有徽章的网站上注意到了这一点。

这大概是因为他们正在使用延迟作业,该作业会定期扫描以查看是否需要授予任何新徽章。我在这里也看到了这种方法:
如何实现徽章?

但是,我真的不明白为什么这应该是必要的,并且我倾向于在我的实现中简单地拥有一个系统,在执行相关操作之后,例如发布新评论,调用 checkAwardBadge 函数,它检查是否用户满足新评论徽章的标准。

Speedwise,我认为所有相关的用户统计信息都将简单地存储在 User 的子模型中,例如 UserStats,这样就不必每次都计算评论的数量,而只是一个简单的查询。

令我震惊的是,我喜欢的系统应该是快速且易于理解的。关于为什么有必要通过延迟工作使事情复杂化,我在这里是否遗漏了一些缺点?

澄清一下:我计划有一个抽象类成就,每个实际成就都是成就的实现。每个成就都会有一个 checkAwardBadge 函数,可以从控制器调用,如果我应该选择走那条路线,甚至可以延迟工作,或者任何时候,检查用户是否获得了某个徽章。因此,成就代码将全部集中。

4

4 回答 4

15

您的实现可能适用于简单的场景(如您所描述的场景),但如果事情变得更复杂,您有一个解决方案:

  1. 在每个动作中进行不必要的检查
  2. 为每个动作增加惩罚性能
  3. 不缩放
  4. 没有所有规则的中心位置。
于 2010-07-29T19:13:41.597 回答
15

虽然这只是与您描述的场景大致相似,但我认为讨论我们在工作中所做的工作可能有助于阐明这种方法的部分原因。

我在一家实时算法交易公司工作。我们的软件所做的部分工作是处理来自供应商的市场数据。

现在,有一些事情需要发生以响应每个单独的市场报价。我们运行分析,有在某些情况下生效的安全触发器等。但我们不惜一切代价避免做的是用所有这些“次要”逻辑来膨胀对市场事件做出反应的代码。

这里的原因是我们的数据来自数据供应商的网络,我们需要这个数据源可以在没有任何备份的情况下自由流动。我们的软件每秒可以处理大约 10,000 个市场报价。如果处理这些市场事件的时间过长,信息源就会开始堵塞,我们尽快对市场做出反应的能力就会受到影响。

这样做的结果是我们处理新市场事件的代码非常精简。事件更新价格,仅此而已。至于需要为每个事件运行的所有其他逻辑:通过尚未由该逻辑检查的所有事件的队列定期发生。

这允许我们拥有一个响应速度极快且不备份数据的线程,而另一个线程处理传入事件并使用它们执行更重要的计算。以这种方式将工作分成两部分可以使一切顺利进行。

我承认这只是与您的问题无关,但在我看来,不检查每个用户操作的徽章相关逻辑的原因很可能是相同的。您不希望通过在操作发生的精确时刻执行次要逻辑来减慢服务器上的每个操作。一般策略是保持快速操作(即基本上所有用户操作)并将更多耗时的工作委派给可能经常运行的辅助进程,但并非针对每个此类操作。

于 2010-07-29T19:29:57.210 回答
4

可能是这样的,如果一个动作完成并立即撤消,它不会导致徽章被授予。

于 2010-07-29T19:12:57.457 回答
2

我一直认为延迟是因为提供静态内容更快。我认为这在高流量网站上很常见,定期更新静态内容而不是为每个 Web 请求生成它。

周期性作业只会生成新的静态内容,并且会非常频繁地运行,但比每个单独的页面请求都少。

于 2010-07-29T19:13:12.457 回答