Event Patterns

Table of Contents

Event Patterns

Below I describe some patterns I’ve implemented. I think the big trick in event patterns is to not distort them with more prevalent patterns. During my short time I’ve benefitted from event driven architectures, hybridized with other architectures, and lazily perverted event driven designs to simpler to understand ones. I think it’s an exercise in will, wisdom and knowledge to know when to keep it quality vs comfortable.

This post doesn’t include anything related to subject/topic naming, nor payload patterns. However, I’ll probably make separate posts relating to those.

🫡

Event

This pattern decouples the creator of data and the interested in data.

A more familiar pattern may be a server-client relationship. Where a server creates or has data of interest by clients. The server meticulously crafts an API taking into account its clients needs. The coupling between the server and the client is generally moderate to high and their linkage is their contract.

This pattern is not a server-client relationship, and it is very tempting to pervert it as one. This relationship makes the creator, owner, and expert of the data the one to publish it, generally with less concern for whom the downstream consumers of it are. It makes past-tense data of fact available and anyone interested by subscribe to where it is published and consume it.

This is an advantageous pattern when data created is of high interest. In a server-client relationship, the client, often polling, needs to understand when the data is available and then fetch it. This can often create a fair amount of noise and unnecessary load on a server with such data. Decoupling this relationship and availability of data scales well.

Here, have a diagram:

event

Command

This pattern is an imperative request that something happen. Often, but not always, the requester relies on the result of the request. As such, coupling is generally high.

Well, why not just do a request reply pattern? Point taken. However, benefits of the distribution, async and eventual consistency inherent to an event driven system may be appealing. You probably just need a simple synchronous request reply. However, if you start hitting ETL complexity, computationally intense, or asynchronous flows where the process model is imperative, this is good to have as an option.

Here, have a diagram:

Command

Deferred Processing

This pattern decouples the receiving and processing of data. It’s common to implement a pattern like fetching data from an external provider, or to configure a webhook with them to post to you. In many cases it is reasonable to process the data synchronously with receiving it.

However, if something unplanned happens, we may have to to implement compensating logic for some kind of resilience. As an example, if we get a payload in a shape we’re not expecting and it causes a failure, what happens then? Generally, if processing synchronously, we may lose the data. A second example to consider is an elasticity problem. We’re suddenly receiving more data than we can synchronously process. The webhooks may try again, but if we’re polling and we “fall behind”, we may lose data.

Enter Asynchronous Ingestion or Deferred Processing. In either of the aforementioned examples, and more not stated, if we decouple receiving from processing and couple receiving with some kind of persistence layer, say an event bus, we may obviate the problem, reduce it’s impact, or get compensatory functionality from decoupling + persistence layer from the pattern.

Here, have a diagram:

deferred processing