io.youi.util.Repeatable.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of youi-core_sjs0.6_2.13 Show documentation
Show all versions of youi-core_sjs0.6_2.13 Show documentation
Core functionality leveraged and shared by most other sub-projects of YouI.
The newest version!
package io.youi.util
import scala.concurrent.duration.FiniteDuration
import scala.concurrent.{ExecutionContext, Future}
import scala.util.{Failure, Success}
/**
* @see Time.repeat for convenient usage
*/
case class Repeatable(delay: FiniteDuration,
initialDelay: Option[FiniteDuration],
stopOnError: Boolean,
task: () => Future[Unit],
errorHandler: Throwable => Unit)
(implicit ec: ExecutionContext) {
private var running = false
private var keepAlive = true
private var future: Future[Unit] = Future.successful(())
def start(): Unit = synchronized {
if (!running) {
running = true
keepAlive = true
run(initialDelay.getOrElse(delay))
}
}
private def run(delay: FiniteDuration): Unit = synchronized {
if (keepAlive && Repeatable.keepAlive) {
future = Time.delay(delay).flatMap { _ =>
if (keepAlive && Repeatable.keepAlive) {
task()
} else {
Future.successful(())
}
}
future.onComplete {
case Success(_) => reSchedule()
case Failure(exception) => {
errorHandler(exception)
if (!stopOnError) {
reSchedule()
}
}
}
}
}
private def reSchedule(): Unit = run(delay)
def stop(): Unit = synchronized {
keepAlive = false
}
}
// TODO: Merge Maintenane functionality and TaskStatus for much more powerful implementation
object Repeatable {
private var keepAlive: Boolean = true
def dispose(): Unit = keepAlive = false
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy