message adapter in ActiveActiveShardingDirectReplication (#29328)

* I don't think it's worth cheating with Any and narrow just to save
  one or two allocations given how many other things that are needed for
  sending the messages
This commit is contained in:
Patrik Nordwall 2020-06-30 09:28:48 +02:00 committed by Christopher Batey
parent e79f5ac3c4
commit 238d55a413
3 changed files with 37 additions and 34 deletions

View file

@ -46,6 +46,8 @@ object ActiveActiveShardingDirectReplication {
@InternalApi @InternalApi
private[akka] case class VerifyStarted(replyTo: ActorRef[Done]) extends Command private[akka] case class VerifyStarted(replyTo: ActorRef[Done]) extends Command
private final case class WrappedPublishedEvent(publishedEvent: PublishedEvent) extends Command
/** /**
* Java API: * Java API:
* @param selfReplica The replica id of the replica that runs on this node * @param selfReplica The replica id of the replica that runs on this node
@ -60,15 +62,15 @@ object ActiveActiveShardingDirectReplication {
* @param replicaShardingProxies A replica id to sharding proxy mapping for each replica in the system * @param replicaShardingProxies A replica id to sharding proxy mapping for each replica in the system
*/ */
def apply[T](selfReplica: String, replicaShardingProxies: Map[String, ActorRef[T]]): Behavior[Command] = def apply[T](selfReplica: String, replicaShardingProxies: Map[String, ActorRef[T]]): Behavior[Command] =
Behaviors Behaviors.setup[Command] { context =>
.setup[Any] { context =>
context.log.debug( context.log.debug(
"Subscribing to event stream to forward events to [{}] sharded replicas", "Subscribing to event stream to forward events to [{}] sharded replicas",
replicaShardingProxies.size - 1) replicaShardingProxies.size - 1)
context.system.eventStream ! EventStream.Subscribe[PublishedEvent](context.self) val publishedEventAdapter = context.messageAdapter[PublishedEvent](WrappedPublishedEvent.apply)
context.system.eventStream ! EventStream.Subscribe[PublishedEvent](publishedEventAdapter)
Behaviors.receiveMessagePartial { Behaviors.receiveMessage {
case event: PublishedEvent => case WrappedPublishedEvent(event) =>
context.log.trace( context.log.trace(
"Forwarding event for persistence id [{}] sequence nr [{}] to replicas", "Forwarding event for persistence id [{}] sequence nr [{}] to replicas",
event.persistenceId, event.persistenceId,
@ -85,6 +87,5 @@ object ActiveActiveShardingDirectReplication {
Behaviors.same Behaviors.same
} }
} }
.narrow[Command]
} }

View file

@ -4,13 +4,15 @@
package akka.cluster.sharding.typed package akka.cluster.sharding.typed
import org.scalatest.wordspec.AnyWordSpecLike
import akka.Done import akka.Done
import akka.actor.testkit.typed.scaladsl.LogCapturing import akka.actor.testkit.typed.scaladsl.LogCapturing
import akka.actor.testkit.typed.scaladsl.ScalaTestWithActorTestKit import akka.actor.testkit.typed.scaladsl.ScalaTestWithActorTestKit
import akka.actor.typed.eventstream.EventStream import akka.actor.typed.eventstream.EventStream
import akka.persistence.typed.PersistenceId import akka.persistence.typed.PersistenceId
import akka.persistence.typed.PublishedEvent
import akka.persistence.typed.internal.PublishedEventImpl import akka.persistence.typed.internal.PublishedEventImpl
import org.scalatest.wordspec.AnyWordSpecLike
class ActiveActiveShardingDirectReplicationSpec class ActiveActiveShardingDirectReplicationSpec
extends ScalaTestWithActorTestKit extends ScalaTestWithActorTestKit
@ -20,9 +22,9 @@ class ActiveActiveShardingDirectReplicationSpec
"Active active sharding replication" must { "Active active sharding replication" must {
"replicate published events to all sharding proxies" in { "replicate published events to all sharding proxies" in {
val replicaAProbe = createTestProbe[Any]() val replicaAProbe = createTestProbe[ShardingEnvelope[PublishedEvent]]()
val replicaBProbe = createTestProbe[Any]() val replicaBProbe = createTestProbe[ShardingEnvelope[PublishedEvent]]()
val replicaCProbe = createTestProbe[Any]() val replicaCProbe = createTestProbe[ShardingEnvelope[PublishedEvent]]()
val replicationActor = spawn( val replicationActor = spawn(
ActiveActiveShardingDirectReplication( ActiveActiveShardingDirectReplication(
@ -42,8 +44,8 @@ class ActiveActiveShardingDirectReplicationSpec
System.currentTimeMillis()) System.currentTimeMillis())
system.eventStream ! EventStream.Publish(event) system.eventStream ! EventStream.Publish(event)
replicaBProbe.expectMessageType[ShardingEnvelope[_]].message should equal(event) replicaBProbe.receiveMessage().message should equal(event)
replicaCProbe.expectMessageType[ShardingEnvelope[_]].message should equal(event) replicaCProbe.receiveMessage().message should equal(event)
replicaAProbe.expectNoMessage() // no publishing to the replica emitting it replicaAProbe.expectNoMessage() // no publishing to the replica emitting it
} }

View file

@ -49,8 +49,8 @@ class EventPublishingSpec
"EventPublishing support" must { "EventPublishing support" must {
"publish events after written for any actor" in { "publish events after written for any actor" in {
val topicProbe = createTestProbe[Any]() val topicProbe = createTestProbe[PublishedEvent]()
system.eventStream ! EventStream.Subscribe[PublishedEvent](topicProbe.ref.narrow) system.eventStream ! EventStream.Subscribe(topicProbe.ref)
// We don't verify subscription completed (no ack available), but expect the next steps to take enough time // We don't verify subscription completed (no ack available), but expect the next steps to take enough time
// for subscription to complete // for subscription to complete
@ -61,7 +61,7 @@ class EventPublishingSpec
wowSuchActor ! WowSuchEventSourcingBehavior.StoreThis("great stuff", tagIt = false, replyTo = persistProbe.ref) wowSuchActor ! WowSuchEventSourcingBehavior.StoreThis("great stuff", tagIt = false, replyTo = persistProbe.ref)
persistProbe.expectMessage(Done) persistProbe.expectMessage(Done)
val published1 = topicProbe.expectMessageType[PublishedEvent] val published1 = topicProbe.receiveMessage()
published1.persistenceId should ===(myId) published1.persistenceId should ===(myId)
published1.event should ===(WowSuchEventSourcingBehavior.Event("great stuff", false)) published1.event should ===(WowSuchEventSourcingBehavior.Event("great stuff", false))
published1.sequenceNumber should ===(1L) published1.sequenceNumber should ===(1L)
@ -72,7 +72,7 @@ class EventPublishingSpec
anotherActor ! WowSuchEventSourcingBehavior.StoreThis("another event", tagIt = true, replyTo = persistProbe.ref) anotherActor ! WowSuchEventSourcingBehavior.StoreThis("another event", tagIt = true, replyTo = persistProbe.ref)
persistProbe.expectMessage(Done) persistProbe.expectMessage(Done)
val published2 = topicProbe.expectMessageType[PublishedEvent] val published2 = topicProbe.receiveMessage()
published2.persistenceId should ===(anotherId) published2.persistenceId should ===(anotherId)
published2.event should ===(WowSuchEventSourcingBehavior.Event("another event", true)) published2.event should ===(WowSuchEventSourcingBehavior.Event("another event", true))
published2.sequenceNumber should ===(1L) published2.sequenceNumber should ===(1L)