scala - 节流或去抖动方法调用

标签 scala

假设我有一个方法可以更新数据库中的某个日期:

def updateLastConsultationDate(userId: String): Unit = ???

我怎样才能轻松地限制/消除该方法,使其每小时运行一次以上 每个用户 .

我想要最简单的解决方案,而不是基于任何事件总线、actor 库或持久层。我想要一个内存中的解决方案(我知道风险)。

我已经看到基于 Akka Throttler 的 Scala 节流解决方案,但在我看来,开始使用 actor 仅用于限制方法调用确实有点矫枉过正。不是有一个非常简单的方法来做到这一点吗?

编辑 : 好像还不够清楚,这里是 visual representation我想要的,在 JS 中实现。如您所见,节流可能不仅是过滤后续调用,还包括推迟调用(在 js/lodash/underscore 中也称为 trailing events)。我正在寻找的解决方案不能仅基于纯同步代码。

最佳答案

对于 ReactiveX 来说,这听起来是个不错的工作。基于的解决方案。在 Scala 上,Monix是我最喜欢的。这是Ammonite REPL session 说明了它:

import $ivy.`io.monix::monix:2.1.0` // I'm using Ammonite's magic imports, it's equivalent to adding "io.monix" %% "monix" % "2.1.0" into your libraryImports in SBT

import scala.concurrent.duration.DurationInt
import monix.reactive.subjects.ConcurrentSubject
import monix.reactive.Consumer
import monix.execution.Scheduler.Implicits.global
import monix.eval.Task

class DbUpdater {
  val publish = ConcurrentSubject.publish[String]
  val throttled = publish.throttleFirst(1 hour)
  val cancelHandle = throttled.consumeWith(
    Consumer.foreach(userId =>
      println(s"update your database with $userId here")))
    .runAsync

  def updateLastConsultationDate(userId: String): Unit = {
    publish.onNext(userId)
  }

  def stop(): Unit = cancelHandle.cancel()
}

是的,如果使用 Scala.js,这段代码也可以在浏览器中运行,如果它对您很重要的话。

关于scala - 节流或去抖动方法调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40660126/

相关文章:

scala - 是否可以使用 @ 语法简化此 Scala 匹配语句?

scala - Spark SQL 仅映射一列 DataFrame

scala - 为什么 receive 被称为方法?

scala - Vaadin 8 - 包含字符串内容的文本文件的下载按钮

scala - 了解 Spark 中广播变量的大小

scala - 从基本抽象类构造子类

java - scala.runtime 中这些 Java 文件的用途是什么?

mysql - 光滑的动态分组

mongodb - 无法将 casbah 解析为 sbt 依赖项

scala - 使用 Spark Scala 计算平均值