Using an actor with persistence for a shopping cart so every visitor will have their own actor

126 Views Asked by At

If I have an actor to represent a shopping cart:

class ShoppingCartActor extends PersistentActor with ActorLogging {
   override def persistenceId: String = "shopping-cart-actor"

   override def receiveCommand: Receive = ???
   override def receiveRecover: Receive = ???
}

val system = ActorSystem("PersistenceActors")

for(i <- 1 to 100) {
  val carts = system.actorOf(Props[ShoppingCartActor], s"shopping-cart-actor-$i"
}

If I create a new shopping cart actor for every visitor to a ecommerce store, will all event messages be stored in the same journal/table in the storage engine? e.g. postgres or cassandra

If it is the same journal/table, how does it reload the events for the correct shopping cart actor since each visitor/customer will have their own shopping cart actor.

1

There are 1 best solutions below

2
On

The persistenceId should be unique per PersistentActor. That is how persistence retrieves the events per specific actor (in postgres or cassandra it will be stored in its own column). So you'd want something like

class ShoppingCartActor(cartNum: Int) extends PersistentActor with ActorLogging {
  override def persistenceId: String = s"shopping-cart:$cartNum"

  override def receiveCommand: Receive = ???
  override def receiveRecover: Receive = ???
}

object ShoppingCartActor {
  def props(cartId: String): Props[ShoppingCartActor] =
    Props(new ShoppingCartActor(cartId))
}

And then:

val system = ActorSystem(???)

val carts = (1 to 100).map { cartNum =>
  cartNum -> system.actorOf(ShoppingCartActor.props(cartNum), s"shopping-cart-actor-$i")
}.toMap

EDIT to clarify:

The Postgres schema for the event journal is:

CREATE TABLE IF NOT EXISTS journal (
  ordering BIGSERIAL,
  persistence_id VARCHAR(255) NOT NULL,
  sequence_number BIGINT NOT NULL,
  deleted BOOLEAN DEFAULT FALSE NOT NULL,
  tags VARCHAR(255) DEFAULT NULL,
  message BYTEA NOT NULL,
  PRIMARY KEY(persistence_id, sequence_number)
)

i.e. each event is one row in the journal table with a column corresponding to the persistenceId. Akka Persistence Cassandra also uses a single journal table.