Skip to content

Automatic passivation for typed sharding #25765

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

johanandren
Copy link
Contributor

Fixes #25512

@johanandren johanandren requested a review from patriknw October 9, 2018 13:15
@akka-ci akka-ci added validating PR is currently being validated by Jenkins needs-attention Indicates a PR validation failure (set by CI infrastructure) and removed validating PR is currently being validated by Jenkins labels Oct 9, 2018
@akka-ci
Copy link

akka-ci commented Oct 9, 2018

Test FAILed.

@akka-ci akka-ci added validating PR is currently being validated by Jenkins needs-attention Indicates a PR validation failure (set by CI infrastructure) and removed needs-attention Indicates a PR validation failure (set by CI infrastructure) validating PR is currently being validated by Jenkins labels Oct 9, 2018
@akka-ci
Copy link

akka-ci commented Oct 9, 2018

Test FAILed.

Copy link
Contributor

@patriknw patriknw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like the right approach

some nitpick comments that you didn't ask for at this point..

import context.dispatcher
val passivateIdleTask = if (settings.passivateIdleEntityAfter.toNanos > 0) {
val idleInterval = 1.second // FIXME
log.info("Idle entities will be passivated after {}", PrettyDuration.format(settings.passivateIdleEntityAfter))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[{}]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also didn't think it quite through, now it's logged once for every started shard. Should be logged from the region rather.

var passivating = Set.empty[ActorRef]
val messageBuffers = new MessageBufferMap[EntityId]

var handOffStopper: Option[ActorRef] = None

import context.dispatcher
val passivateIdleTask = if (settings.passivateIdleEntityAfter.toNanos > 0) {
val idleInterval = 1.second // FIXME
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably enough with half (or some other faction) of the total duration

@@ -240,6 +256,9 @@ private[akka] class Shard(
val id = idByRef(ref)
idByRef -= ref
refById -= id
if (passivateIdleTask.isDefined && lastMessageTimestamp.contains(id)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

contains not needed here

lastMessageTimestamp.foreach {
case (entityId, lastMessageTimestamp) ⇒
if (lastMessageTimestamp < deadline && refById.contains(entityId)) // test failed but, how could it not be in refs though?
passivate(refById(entityId), handOffStopMessage) // FIXME double check that this is the right message
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, in Typed we use that, and that should be ok for untyped also

messageBuffers.contains(id) match {
case false ⇒ deliverTo(id, msg, payload, snd)
if (passivateIdleTask.isDefined) {
lastMessageTimestamp += (id -> System.nanoTime())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is slightly more efficient: lastMessageTimestamp = lastMessageTimestamp.updated(id, System.nanoTime())

@akka-ci akka-ci added validating PR is currently being validated by Jenkins and removed needs-attention Indicates a PR validation failure (set by CI infrastructure) labels Oct 10, 2018
@johanandren
Copy link
Contributor Author

Not sure if I actually need a multi-JVM test for the feature given that it doesn't do any specific multi-node interactions, wdyt @patriknw ?

@akka-ci akka-ci added needs-attention Indicates a PR validation failure (set by CI infrastructure) and removed validating PR is currently being validated by Jenkins labels Oct 10, 2018
@akka-ci
Copy link

akka-ci commented Oct 10, 2018

Test FAILed.

@akka-ci akka-ci added tested PR that was successfully built and tested by Jenkins and removed needs-attention Indicates a PR validation failure (set by CI infrastructure) labels Oct 10, 2018
@akka-ci
Copy link

akka-ci commented Oct 10, 2018

Test PASSed.

@johanandren johanandren changed the title WIP Automatic passivation for typed sharding Automatic passivation for typed sharding Oct 10, 2018
@akka-ci akka-ci added validating PR is currently being validated by Jenkins tested PR that was successfully built and tested by Jenkins and removed tested PR that was successfully built and tested by Jenkins validating PR is currently being validated by Jenkins labels Oct 10, 2018
@akka-ci
Copy link

akka-ci commented Oct 10, 2018

Test PASSed.

@patriknw
Copy link
Contributor

@johanandren no need for multi-jvm test of this feature.

@johanandren
Copy link
Contributor Author

Then it's ready for final review!

Copy link
Contributor

@patriknw patriknw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looking good, some final touch...

@@ -23,6 +23,10 @@ akka.cluster.sharding {
# due to rebalance or crash.
remember-entities = off

# Set this to a time duration to have sharding passivate entities when they have not
# gotten any message in this long time.
passivate-idle-entity-after = 0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would be nice to support "off" value also

var passivating = Set.empty[ActorRef]
val messageBuffers = new MessageBufferMap[EntityId]

var handOffStopper: Option[ActorRef] = None

import context.dispatcher
val passivateIdleTask = if (settings.passivateIdleEntityAfter.toNanos > 0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

settings.passivateIdleEntityAfter > Duration.Zero

@@ -265,6 +282,17 @@ private[akka] class Shard(
}
}

def passivateIdleEntities(): Unit = {
log.debug("Passivating idle entities")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that log statement adds much value. More useful would be to collect the entityIds to be passivated and log something like

log.debug("Passivating [{}] idle entities", idleEntities.size)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did it like this to not have to create an intermediate collection, and since each passivation also logs at debug, but maybe having to correlate this log entry with those is a bad idea. I'll change it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logging each passivation might be too much, that could be a storm of 1000s of log messages

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if someone need that they can add the logging in their actor

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That logging was already in place prior to this PR, you mean I should remove that?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hm, ok let's leave one of them "Entity stopped after passivation", but remove "Passivating started on entity"

@@ -418,6 +418,8 @@ private[akka] class ShardRegion(
// subscribe to MemberEvent, re-subscribe when restart
override def preStart(): Unit = {
cluster.subscribe(self, classOf[MemberEvent])
if (settings.passivateIdleEntityAfter.toMillis > 0)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

> Duration.Zero

The entities can be configured to be automatically passivated if they haven't received
a message for a while using the `akka.cluster.sharding.passivate-idle-entity-after` setting,
or by explicitly setting `ClusterShardingSettings.passivateIdleEntityAfter` to a suitable
time to keep the actor alive. By default automatic passivation is disabled.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need to mention that messages that are not sent via sharding are not counted, e.g. scheduled messages to self?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, I'll add that.

@akka-ci akka-ci added tested PR that was successfully built and tested by Jenkins and removed tested PR that was successfully built and tested by Jenkins validating PR is currently being validated by Jenkins labels Oct 12, 2018
@akka-ci
Copy link

akka-ci commented Oct 12, 2018

Test PASSed.

Copy link
Contributor

@chbatey chbatey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, some optional nits

@patriknw patriknw added the 2 - pick next Used to mark issues which are next up in the queue to be worked on. The tag is non-binding label Nov 5, 2018
@johanandren johanandren force-pushed the wip-25512-auto-passivation-sharding-johanandren branch from 4548353 to a418e43 Compare November 6, 2018 14:22
@akka-ci akka-ci added validating PR is currently being validated by Jenkins needs-attention Indicates a PR validation failure (set by CI infrastructure) and removed tested PR that was successfully built and tested by Jenkins validating PR is currently being validated by Jenkins labels Nov 6, 2018
@akka-ci
Copy link

akka-ci commented Nov 6, 2018

Test FAILed.

@patriknw
Copy link
Contributor

patriknw commented Nov 6, 2018

it was formatting issue in InactiveEntityPassivationSpec.scala

@akka-ci akka-ci added validating PR is currently being validated by Jenkins tested PR that was successfully built and tested by Jenkins and removed needs-attention Indicates a PR validation failure (set by CI infrastructure) validating PR is currently being validated by Jenkins labels Nov 6, 2018
@akka-ci
Copy link

akka-ci commented Nov 6, 2018

Test PASSed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2 - pick next Used to mark issues which are next up in the queue to be worked on. The tag is non-binding tested PR that was successfully built and tested by Jenkins
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants