improve EarlyMultiThrottler interface

pull/10033/head
Thibault Duplessis 2021-10-26 10:01:10 +02:00
parent 98e8b6bacd
commit bcd0e8da32
3 changed files with 21 additions and 24 deletions

View File

@ -2,18 +2,27 @@ package lila.hub
import akka.actor._ import akka.actor._
import scala.concurrent.duration._ import scala.concurrent.duration._
import scala.concurrent.ExecutionContext
import lila.log.Logger
/** Runs the work then waits cooldown /** Runs the work then waits cooldown
* only runs once at a time per id. * only runs once at a time per id.
* Guarantees that work is ran as early as possible. * Guarantees that work is ran as early as possible.
* Also saves work and runs it after cooldown. * Also saves work and runs it after cooldown.
*/ */
final class EarlyMultiThrottler( final class EarlyMultiThrottler(logger: Logger)(implicit ec: ExecutionContext, system: ActorSystem) {
logger: lila.log.Logger
)(implicit ec: scala.concurrent.ExecutionContext)
extends Actor {
import EarlyMultiThrottler._ private val actor = system.actorOf(Props(new EarlyMultiThrottlerActor(logger)))
def apply(id: String, cooldown: FiniteDuration)(run: => Funit) =
actor ! EarlyMultiThrottlerActor.Work(id, run = () => run, cooldown)
}
// actor based implementation
final private class EarlyMultiThrottlerActor(logger: Logger)(implicit ec: ExecutionContext) extends Actor {
import EarlyMultiThrottlerActor._
var running = Set.empty[String] var running = Set.empty[String]
var planned = Map.empty[String, Work] var planned = Map.empty[String, Work]
@ -45,13 +54,11 @@ final class EarlyMultiThrottler(
lila.common.Future.makeItLast(work.cooldown) { work.run() } lila.common.Future.makeItLast(work.cooldown) { work.run() }
} }
object EarlyMultiThrottler { private object EarlyMultiThrottlerActor {
case class Work( case class Work(
id: String, id: String,
run: () => Funit, run: () => Funit,
cooldown: FiniteDuration // how long to wait after running, before next run cooldown: FiniteDuration // how long to wait after running, before next run
) )
private case class Done(id: String) private case class Done(id: String)
} }

View File

@ -4,25 +4,22 @@ import akka.actor._
import scala.concurrent.duration._ import scala.concurrent.duration._
import lila.study.MultiPgn import lila.study.MultiPgn
import lila.hub.EarlyMultiThrottler
final class RelayPush(sync: RelaySync, api: RelayApi)(implicit final class RelayPush(sync: RelaySync, api: RelayApi)(implicit
system: ActorSystem, system: ActorSystem,
ec: scala.concurrent.ExecutionContext ec: scala.concurrent.ExecutionContext
) { ) {
private val throttler = system.actorOf(Props(new EarlyMultiThrottler(logger = logger))) private val throttler = new lila.hub.EarlyMultiThrottler(logger)
def apply(rt: RelayRound.WithTour, pgn: String): Fu[Option[String]] = def apply(rt: RelayRound.WithTour, pgn: String): Fu[Option[String]] =
if (rt.round.sync.hasUpstream) if (rt.round.sync.hasUpstream)
fuccess("The relay has an upstream URL, and cannot be pushed to.".some) fuccess("The relay has an upstream URL, and cannot be pushed to.".some)
else else
fuccess { fuccess {
throttler ! EarlyMultiThrottler.Work( throttler(rt.round.id.value, if (rt.tour.official) 3.seconds else 7.seconds) {
id = rt.round.id.value, pushNow(rt, pgn)
run = () => pushNow(rt, pgn), }
cooldown = if (rt.tour.official) 3.seconds else 7.seconds
)
none none
} }

View File

@ -758,8 +758,6 @@ final class TournamentApi(
private object updateTournamentStanding { private object updateTournamentStanding {
import lila.hub.EarlyMultiThrottler
// last published top hashCode // last published top hashCode
private val lastPublished = lila.memo.CacheApi.scaffeineNoScheduler private val lastPublished = lila.memo.CacheApi.scaffeineNoScheduler
.initialCapacity(16) .initialCapacity(16)
@ -778,15 +776,10 @@ final class TournamentApi(
} }
} }
private val throttler = system.actorOf(Props(new EarlyMultiThrottler(logger = logger))) private val throttler = new lila.hub.EarlyMultiThrottler(logger)
def apply(tour: Tournament): Unit = def apply(tour: Tournament): Unit =
if (!tour.isTeamBattle) if (!tour.isTeamBattle) throttler(tour.id, 15.seconds) { publishNow(tour.id) }
throttler ! EarlyMultiThrottler.Work(
id = tour.id,
run = () => publishNow(tour.id),
cooldown = 15.seconds
)
} }
} }