akka / akka-projection

Akka Projections is intended for building systems with the CQRS pattern, and facilitate in event-based service-to-service communication.
https://doc.akka.io/libraries/akka-projection/current/
Other
102 stars 35 forks source link

Add ProjectionDaemon as glue to ShardedDaemon #137

Open octonato opened 4 years ago

octonato commented 4 years ago
ShardedDaemonProcess(system).init[ProjectionBehavior.Command](
      name = "shopping-carts",
      numberOfInstances = ShoppingCart.tags.size,
      behaviorFactory = n => ProjectionBehavior(projection(ShoppingCart.tags(n))),
      settings = ShardedDaemonProcessSettings(system),
      stopMessage = Some(ProjectionBehavior.Stop))
  }

This looks very clustered. The are lots of concepts that a user needs to know and wire together.

I do think there is room for a ProjectionDaemon

def projection(tag: String) =
      CassandraProjection.atLeastOnce(
        projectionId = ProjectionId("shopping-carts", tag),
        sourceProvider(tag),
        saveOffsetAfterEnvelopes = 100,
        saveOffsetAfterDuration = 500.millis,
        handler = new ShoppingCartHandler)

val tags = List("tag-1", "tag-2", "tag-3")
val projections = tags.map(projection)

ProjectionDaemon(system).init(
  name = "shopping-carts",
  projections = projections
)

We don't need the types, we don't need numberOfInstances nor behaviorFactory. We can do it now because projection is a factory of running projections.

_Originally posted by @renatocaval in https://github.com/akka/akka-projection/pull/136#discussion_r425098548_

patriknw commented 4 years ago

We could get rid of the settings, created issue https://github.com/akka/akka/issues/29081

I started to think about if there is something we can add in Akka to support running things that are not necessarily wrapped in a Behavior.

Started thinking in terms of:

  def init[T](name: String, numberOfInstances: Int, processProvider: ProcessProvider): Unit

  trait ProcessProvider {
    def start(n: Int): Unit
    def stop(n: Int): Future[Done]
  }

but still maybe not perfect for projections

One concern about adding ProjectionDaemon is that then we need the akka-cluster-sharding-typed dependency just for this.

octonato commented 4 years ago

One concern about adding ProjectionDaemon is that then we need the akka-cluster-sharding-typed dependency just for this.

But this is an important dependency since that's The Recommended way of running it. It's like Persistence. You can run without, but not great (even dangerous).

We can add the dependency to core, but as provided. If you use the daemon, it's expected that you bring in the sharding typed.

octonato commented 4 years ago

I think the ProcessProvider won't help much. We still have to deal with the protocol message.

And if we introduce a DaemonBehavior? The ShardedDaemon should work with any Behavior, but when using DaemonBehavior you don't need to deal with the protocol.

ProjectionBehavior would be a impl of DaemonBehavior

patriknw commented 4 years ago

I think the ProcessProvider won't help much. We still have to deal with the protocol message.

We would implement the ProcessProvider interface in the Projection, so you would pass the Projection as that parameter. But there is still something that doesn't work out with the n =>.

I'm not against it, just want to exhaust other options first.

octonato commented 4 years ago

So, if we don't have to deal with the protocol when using ProcessProvider it means that somewhere we will have a DaemonBehavior that we will initialize behind the scenes with the ProcessProvider and drive it from the ShardedDaemon.

At least that's how I'm imagining this impl.

That DaemonBevahior can also act as a proxy to inspect the wrapped Behavior.

Anyway, need to try it out to discover it. We can deferred it when we start with resume/pause.

patriknw commented 4 years ago

Another angle is to have the possibility to run different types of projections within the same ShardedDaemonProcess as mentioned in https://github.com/akka/akka-projection/issues/171