smashbourne
smashbourne

Reputation: 463

Streaming events and rule based trigger

Given Event-A, Event-B, Event-C that arrive (potentially out of order) within days of each other, I want to trigger processing to generate derivative Event-ABC once I know I have all events in the set.

The events are grouped by userId/sessionId

Currently I read all events from a single queue, write to database, and update metadata saying which events have been written. Once the metadata contains all events based on the rule, I trigger aggregation processing. This approach has some performance issues due to queue workers potentially hammering the same key when processing events that belong to the same group, so I am looking for alternatives.

What I would like is a more fine grained software defined routing and queueing events based on their userId/sessionId for processing. I think what I am trying to do is somewhat similar to event sourcing.

I was looking at whether Akka could help with this type of problem. With an actor per userId/sessionId it would reduce unneeded concurrency and contain trigger logic within the actor. My concern is the potentially large memory requirements when using so many Actors.

Upvotes: 0

Views: 92

Answers (2)

VoiceOfUnreason
VoiceOfUnreason

Reputation: 57194

This approach has some performance issues due to queue workers potentially hammering the same key when processing events that belong to the same group, so I am looking for alternatives.

Disclaimer: I'm not sure I understand what you are describing here, so the solution below may not be a fit.

I think what I am trying to do is somewhat similar to event sourcing.

Yes, your description sounds a lot like an event sourced process manager.

Event Handler (you might have one for each of the events types, or a single handler that subscribes to all three) receives an event.

From the userId/userSession information, it calculates a unique identifier for this instance of your process. Think hash, or named uuid, built from the unique identifier of the process.

Load the current state of the process matching the identifier. That's a data structure tracking which events have been seen before. It might just be an event stream.

apply the current event to the process state. "apply" is expected to be a no-op if this event has already been seen -- your event messages do have unique identifiers, right?

Save the updated process state. This ends the transaction.

Now observe the process state -- you might do this immediately in the event handler, or in an asynchronous process. If the process is "ready", then verb to produce Event-ABC.

The outline above follows the common pattern where you have process managers that track the state of a running process, but trigger business logic by running commands against the appropriate aggregate.

In a simpler design, you might combine "the aggregate" and "the process". The basic pattern is the same - the event handler computes the id of the aggregate, loads it, and invokes the handle event command. The aggregate updates its own state with the information contained in the event, and writes that state change into its own history. If all of the required events are accounted for, the aggregate also writes the Event-ABC into its own history.

Upvotes: 0

tomliversidge
tomliversidge

Reputation: 2369

What you're describing is more akin to a Saga or Process Manager than Event Sourcing. You need something that handles multiple messages and then reacts once a specification has been satisfied.

Akka can certainly cope with this. With Akka, you could create an actor per key and then route messages to individual actors when you receive them. I wouldn't be too concerned about memory issues as Actor systems are supposed to cope with thousands and thousands of Actors. I think you need to measure the performance of any solution you arrive at though.

You also need to consider how you deal with the servers crashing - if you keep everything in memory then you are susceptible to losing your sagas when the servers crash. This may or may not be a problem depending on your requirements (i.e. if you can recover from this). You could look into Akka Persistence if it is important to account for this.

Upvotes: 0

Related Questions