scheduleWithFixedDelay vs scheduleAtFixedRate, #26910
* previous `schedule` method is trying to maintain a fixed average frequency over time, but that can result in undesired bursts of scheduled tasks after a long GC or if the JVM process has been suspended, same with all other periodic scheduled message sending via various Timer APIs * most of the time "fixed delay" is more desirable * we can't just change because it's too big behavioral change and some might depend on previous behavior * deprecate the old `schedule` and introduce new `scheduleWithFixedDelay` and `scheduleAtFixedRate`, when fixing the deprecation warning users should make a concious decision of which behavior to use (scheduleWithFixedDelay in most cases) * Streams * SchedulerSpec * test both fixed delay and fixed rate * TimerSpec * FSM and PersistentFSM * mima * runnable as second parameter list, also in typed.Scheduler * IllegalStateException vs SchedulerException * deprecated annotations * api and reference docs, all places * migration guide
This commit is contained in:
parent
72cfc2485e
commit
10d32fceb9
99 changed files with 2285 additions and 909 deletions
|
|
@ -1232,14 +1232,19 @@ final class Replicator(settings: ReplicatorSettings) extends Actor with ActorLog
|
|||
|
||||
//Start periodic gossip to random nodes in cluster
|
||||
import context.dispatcher
|
||||
val gossipTask = context.system.scheduler.schedule(gossipInterval, gossipInterval, self, GossipTick)
|
||||
val gossipTask = context.system.scheduler.scheduleWithFixedDelay(gossipInterval, gossipInterval, self, GossipTick)
|
||||
val notifyTask =
|
||||
context.system.scheduler.schedule(notifySubscribersInterval, notifySubscribersInterval, self, FlushChanges)
|
||||
context.system.scheduler.scheduleWithFixedDelay(
|
||||
notifySubscribersInterval,
|
||||
notifySubscribersInterval,
|
||||
self,
|
||||
FlushChanges)
|
||||
val pruningTask =
|
||||
if (pruningInterval >= Duration.Zero)
|
||||
Some(context.system.scheduler.schedule(pruningInterval, pruningInterval, self, RemovedNodePruningTick))
|
||||
Some(
|
||||
context.system.scheduler.scheduleWithFixedDelay(pruningInterval, pruningInterval, self, RemovedNodePruningTick))
|
||||
else None
|
||||
val clockTask = context.system.scheduler.schedule(gossipInterval, gossipInterval, self, ClockTick)
|
||||
val clockTask = context.system.scheduler.scheduleWithFixedDelay(gossipInterval, gossipInterval, self, ClockTick)
|
||||
|
||||
val serializer = SerializationExtension(context.system).serializerFor(classOf[DataEnvelope])
|
||||
val maxPruningDisseminationNanos = maxPruningDissemination.toNanos
|
||||
|
|
@ -1291,7 +1296,7 @@ final class Replicator(settings: ReplicatorSettings) extends Actor with ActorLog
|
|||
val deltaPropagationInterval = (gossipInterval / deltaPropagationSelector.gossipIntervalDivisor).max(200.millis)
|
||||
Some(
|
||||
context.system.scheduler
|
||||
.schedule(deltaPropagationInterval, deltaPropagationInterval, self, DeltaPropagationTick))
|
||||
.scheduleWithFixedDelay(deltaPropagationInterval, deltaPropagationInterval, self, DeltaPropagationTick))
|
||||
} else None
|
||||
|
||||
// cluster nodes, doesn't contain selfAddress, doesn't contain joining and weaklyUp
|
||||
|
|
|
|||
|
|
@ -159,7 +159,7 @@ class ReplicatorMessageSerializer(val system: ExtendedActorSystem)
|
|||
.millis
|
||||
private val readCache = new SmallCache[Read, Array[Byte]](4, cacheTimeToLive, m => readToProto(m).toByteArray)
|
||||
private val writeCache = new SmallCache[Write, Array[Byte]](4, cacheTimeToLive, m => writeToProto(m).toByteArray)
|
||||
system.scheduler.schedule(cacheTimeToLive, cacheTimeToLive / 2) {
|
||||
system.scheduler.scheduleWithFixedDelay(cacheTimeToLive, cacheTimeToLive / 2) { () =>
|
||||
readCache.evict()
|
||||
writeCache.evict()
|
||||
}(system.dispatchers.internalDispatcher)
|
||||
|
|
|
|||
|
|
@ -74,9 +74,9 @@ class LotsOfDataBot extends Actor with ActorLogging {
|
|||
val isPassive = context.system.settings.config.getBoolean("passive")
|
||||
var tickTask =
|
||||
if (isPassive)
|
||||
context.system.scheduler.schedule(1.seconds, 1.seconds, self, Tick)
|
||||
context.system.scheduler.scheduleWithFixedDelay(1.seconds, 1.seconds, self, Tick)
|
||||
else
|
||||
context.system.scheduler.schedule(20.millis, 20.millis, self, Tick)
|
||||
context.system.scheduler.scheduleWithFixedDelay(20.millis, 20.millis, self, Tick)
|
||||
|
||||
val startTime = System.nanoTime()
|
||||
var count = 1L
|
||||
|
|
@ -94,7 +94,7 @@ class LotsOfDataBot extends Actor with ActorLogging {
|
|||
if (count == maxEntries) {
|
||||
log.info("Reached {} entries", count)
|
||||
tickTask.cancel()
|
||||
tickTask = context.system.scheduler.schedule(1.seconds, 1.seconds, self, Tick)
|
||||
tickTask = context.system.scheduler.scheduleWithFixedDelay(1.seconds, 1.seconds, self, Tick)
|
||||
}
|
||||
val key = ORSetKey[String]((count % maxEntries).toString)
|
||||
if (count <= 100)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue