apache / pekko

Build highly concurrent, distributed, and resilient message-driven applications using Java/Scala
https://pekko.apache.org/
Apache License 2.0
1.17k stars 139 forks source link

chore: avoid the double evaluation of entityId in ClusterSharding #1304

Closed Roiocam closed 3 months ago

Roiocam commented 4 months ago

Found something we could optimized it.

laglangyue commented 4 months ago

Seems like duplicate code, can it be abstracted

Roiocam commented 3 months ago

Use the cacheable partial function, and then verify it works.


var calTime: Int = 0
def entityId(value: Any): String = {
  calTime = calTime + 1
  value match {
    case "wrong" => null
    case _ => String.valueOf(value)
  }
}

def extractEntityIdFromExtractor: PartialFunction[Any, Any] =
  new scala.runtime.AbstractPartialFunction[Any, (String, Any)] {
    var cache: String = _

    override def isDefinedAt(msg: Any): Boolean = {
      cache = entityId(msg)
      cache != null
    }

    override def apply(x: Any): (String, Any) = (cache, x)
  }

lazy val xx = extractEntityIdFromExtractor

lazy val yy: PartialFunction[Any, Any] = {
  case message if entityId(message) != null => (entityId(message), message)

}

assert(!xx.isDefinedAt("wrong"))
assert(!yy.isDefinedAt("wrong"))
calTime = 0
val health = "health"
println(xx.isDefinedAt(health))
println(xx(health))
println(s"caltime = $calTime")
println("=====")
calTime = 0
println(yy.isDefinedAt(health))
println(yy(health))
println(s"caltime = $calTime")
pjfanning commented 3 months ago

@Roiocam is it ok to get this merged now?

Roiocam commented 3 months ago

@Roiocam is it ok to get this merged now?

I have no objections to this, but it would be better if there were reviews from others.