All Downloads are FREE. Search and download functionalities are using the official Maven repository.

spice.util.BufferManager.scala Maven / Gradle / Ivy

There is a newer version: 0.7.2
Show newest version
package spice.util

import cats.effect.{FiberIO, IO}
import cats.syntax.all._
import scribe.cats.{io => logger}

import java.util.concurrent.atomic.AtomicLong
import scala.concurrent.duration._

case class BufferManager(checkEvery: FiniteDuration = 10.seconds,
                         triggerAfter: Int = 100,
                         maxPerBatch: Int = 5000,
                         checkFrequency: FiniteDuration = 1.second,
                         sendEmpty: Boolean = false,
                         logErrorAfter: Int = 3) {
  private var queues = List.empty[BufferQueue[_]]
  private val lastCheck = new AtomicLong(System.currentTimeMillis())
  private var keepAlive = true

  def start: IO[FiberIO[Unit]] = recurse(0).start

  def stop(): IO[Unit] = IO {
    keepAlive = false
  }

  def create[T](handler: List[T] => IO[Unit]): BufferQueue[T] = synchronized {
    val q = BufferQueue[T](this, handler)
    queues = q :: queues
    q
  }

  private def recurse(failures: Int): IO[Unit] = IO
    .sleep(checkFrequency)
    .flatMap { _ =>
      val timeElapsed: Boolean = lastCheck.get() + checkEvery.toMillis < System.currentTimeMillis()
      queues
        .filter(q => q.nonEmpty && (timeElapsed || q.ready))
        .map(q => q.process())
        .parSequence
        .map { _ =>
          if (timeElapsed) lastCheck.set(System.currentTimeMillis())
        }
        .flatMap(_ => recurse(0))
        .whenA(keepAlive)
    }
    .handleErrorWith { throwable =>
      val message = s"An error occurred processing the buffer (failure count: $failures). Delaying before trying again."
      val log = if (failures < logErrorAfter) {
        logger.warn(message)
      } else {
        logger.error(message, throwable)
      }
      log
        .flatMap { _ =>
          IO.sleep(checkEvery).flatMap(_ => recurse(failures + 1)).whenA(keepAlive)
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy