How to keep track the id of entity between write side and read side?

I’m working on a project with CQRS pattern. By reading the Akka Guide :: Akka Guide (lightbend.com), I’m confused with keeping track the id of entity.

  1. In the Domain Layer, at the write side, I use EventSourcedBehavior to generate events, and use the id of entity and event class name as the tag. By this way, one id is corresponding to one entity (or one behavior object).

The id of entity is generated by myself in the Application Layer.

def apply(id: String): Behavior[Command] = {
  val starter = Starter(id)
  EventSourcedBehavior
    .withEnforcedReplies[Command, Event, Project](
      persistenceId = PersistenceId(entityTypeHint = EntityKey.name, entityId = id),
      emptyState = starter,
      commandHandler = (state, cmd) => state.onCommand(cmd),
      eventHandler = (state, event) => state.onEvent(event)
      )
    .withTagger(event => Set(id, event.getClass.toString)    
}
  1. At the read side, I want to build the material of entity by the projection. But I don’t know how to assign the param numberOfInstances of ShardedDaemonProcess.init() to create projection, because there are lots of instances of entity in the system, not only 5 shopping-carts in the guide. And the system will produce more entities later. Should the ShardedDaemonProcess.init() be called one more time?

  2. I suppose that one projection is corresponding to one tag, then one id of entity. By this way, one projection will handle all events of one entity.

  3. At the other side, if I take event class name as element of the tag set in the EventSourcedBehavior, should the projection corresponding to the event class name handle only the kind of event of any entity?

  4. Because nobody keeps the track to all ids of entities, should I keep them with a table by myself? Then either the sharding.entityRefFor(id) or EventSourcedProvider.eventsByTag(tag) can get the id.

Thanks.

The id should not be used as a tag, there already is an events by persistence id query that you can use to list all events for a specific id.

In general one projection handles all the events for all entities of a specific type, turning them into a read side view or emitting them to a message broker topic.

The way tags are used in the guide (and often with projections) is to partition the global stream of events for an entity type into a predetermined number of of streams that can be consumed independently but still guarantees that each event is processed.

For ordering guarantees it is important that events from the same entity always end up with the same tag. Each tag is then consumed by one projection consumer, so you should size them to not be too few but also not too many for a given application.

The guide uses 5 tags, you can see that and how the tag for all events of each entity is calculated based on the entity id here: Section 6: Projection for queries :: Akka Guide

This does not mean there can only be 5 shopping carts but that the events of all created shopping carts, whether that is 5 or 10 000 or 100 000 are processed with 5 independent consumers to build the view.

When using tags the number is decided up front and cannot easily be changed after the fact (we have an upcoming solution coming for this with a new eventsBySlice query instead of the tags).

If you want to query the full list of entities, there are two queries that a persistence plugin can implement: persistenceIds and currentPersistenceIds but it would also be possible to define a projection to keep track of those in some other representation or with additional data per id.

I see. I misunderstand the tag usage. I read the guide, but not to understand the relationships between persistenId, entity id and tag.

What I want, the one is to list all events of one entity, then make a material by projection at read side. The material will be the querier for query service. Then, the entity takes the job of aggregate, the projection takes the job of querier, that’s CQRS pattern what I understand.

The two is to peek some specific kinds of events which the client focuses on or cares of. It’s for the OLAP or the other services.

Thank you.