org.apache.pekko.remote.RemoteMetricsExtension.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of pekko-remote_2.13 Show documentation
Show all versions of pekko-remote_2.13 Show documentation
Apache Pekko is a toolkit for building highly concurrent, distributed, and resilient message-driven applications for Java and Scala.
The newest version!
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* license agreements; and to You under the Apache License, version 2.0:
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* This file is part of the Apache Pekko project, which was derived from Akka.
*/
/*
* Copyright (C) 2009-2022 Lightbend Inc.
*/
package org.apache.pekko.remote
import java.util.concurrent.ConcurrentHashMap
import scala.annotation.tailrec
import scala.annotation.nowarn
import org.apache.pekko
import pekko.actor.ActorSelectionMessage
import pekko.actor.ActorSystem
import pekko.actor.ClassicActorSystemProvider
import pekko.actor.ExtendedActorSystem
import pekko.actor.Extension
import pekko.actor.ExtensionId
import pekko.actor.ExtensionIdProvider
import pekko.event.Logging
import pekko.routing.RouterEnvelope
/**
* INTERNAL API
* Extension that keeps track of remote metrics, such
* as max size of different message types.
*/
@nowarn("msg=deprecated")
private[pekko] object RemoteMetricsExtension extends ExtensionId[RemoteMetrics] with ExtensionIdProvider {
override def get(system: ActorSystem): RemoteMetrics = super.get(system)
override def get(system: ClassicActorSystemProvider): RemoteMetrics = super.get(system)
override def lookup = RemoteMetricsExtension
override def createExtension(system: ExtendedActorSystem): RemoteMetrics =
if (RARP(system).provider.remoteSettings.LogFrameSizeExceeding.isEmpty)
new RemoteMetricsOff
else
new RemoteMetricsOn(system)
}
/**
* INTERNAL API
*/
private[pekko] trait RemoteMetrics extends Extension {
/**
* Logging of the size of different message types.
* Maximum detected size per message type is logged once, with
* and increase threshold of 10%.
*/
def logPayloadBytes(msg: Any, payloadBytes: Int): Unit
}
/**
* INTERNAL API
*/
private[pekko] class RemoteMetricsOff extends RemoteMetrics {
override def logPayloadBytes(msg: Any, payloadBytes: Int): Unit = ()
}
/**
* INTERNAL API
*/
@nowarn("msg=deprecated")
private[pekko] class RemoteMetricsOn(system: ExtendedActorSystem) extends RemoteMetrics {
private val logFrameSizeExceeding: Int =
RARP(system).provider.remoteSettings.LogFrameSizeExceeding.getOrElse(Int.MaxValue)
private val log = Logging(system, classOf[RemoteMetrics])
private val maxPayloadBytes: ConcurrentHashMap[Class[_], Integer] = new ConcurrentHashMap
override def logPayloadBytes(msg: Any, payloadBytes: Int): Unit =
if (payloadBytes >= logFrameSizeExceeding) {
val clazz = msg match {
case x: ActorSelectionMessage => x.msg.getClass
case x: RouterEnvelope => x.message.getClass
case _ => msg.getClass
}
// 10% threshold until next log
def newMax = (payloadBytes * 1.1).toInt
@tailrec def check(): Unit = {
val max = maxPayloadBytes.get(clazz)
if (max eq null) {
if (maxPayloadBytes.putIfAbsent(clazz, newMax) eq null)
log.info("Payload size for [{}] is [{}] bytes", clazz.getName, payloadBytes)
else check()
} else if (payloadBytes > max) {
if (maxPayloadBytes.replace(clazz, max, newMax))
log.info("New maximum payload size for [{}] is [{}] bytes", clazz.getName, payloadBytes)
else check()
}
}
check()
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy