# Case Study: Messaging Systems

## Fundamental Style for Messaging Systems

{% hint style="info" %}
Pipes and Filters describe a _fundamental architectural style for messaging systems_: individual processing steps (**Filters**) are chained together through the messaging channels (**Pipes**)
{% endhint %}

<figure><img src="https://4276734169-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F15hXGxUjZ4Oswj2kOjvJ%2Fuploads%2F3KnO8kRJZGsnqE1rVPdl%2Fpipes-and-filters-messaging.png?alt=media&#x26;token=f1c514bd-3d6f-415a-9c1d-996af5f6ab60" alt=""><figcaption><p>Source: Enterprise Integration Patterns <a href="#references">[1]</a></p></figcaption></figure>

## Elements

> **Filter ->** Each filter exposes a very simple interface: it receives messages on the inbound pipe, processes the message, and publishes the results to the outbound pipe.&#x20;
>
> **Pipe ->** The pipe connects one filter to the next, sending output messages from one filter to the next.

## Pipes

> In msessaging systems, the obvious implementation for such a pipe is the **Message Channel**.

> The pipe allows one component to send a message into the pipe so that it can be consumed later by another process that is unknown to the component.

> Message Channel provide **language**, **platform** and **location independence** between the filters.

{% hint style="success" %}
**Heuristic**

It is useful to design the components so that they communicate with an **abstract pipe interface.** The implementation of that interface can then be swapped out to use a real channel or an alternative implementation such as an in-memory queue (for purposes such as testing, for example).
{% endhint %}

{% hint style="info" %}
**Heuristic**

The pure form of Pipes and Filters allows each filter to have only a single input port and a single output port. When dealing with Messaging we can relax this property somewhat. A component may consume messages off more than one channel and also output messages to more than one channel.
{% endhint %}

## Trade-offs

### Composability, Flexibility, Extensibility

> Structure can be composed into different solutions by connecting filters to different pipes. We can add new filters, omit existing ones or rearrange them into a new sequence -- all without having to change the filters themselves.

### Performance

> One of the potential downsides of a Pipes and Filters architecture is the **larger number of required channels**.

> Publishing a message to a channel involves a **certain amount of overhead** because the data has to be translated from the application-internal format into the messaging infrastructure's own format. If we are using a long chain of filters, we are paying for the gain in flexibility with potentially lower performance due to repeated message data conversion.

### Testability

> Using Pipes and Filters also improves testability, an often overlooked benefit. We can test each individual processing steps by passing a **Test Message** to the component and comparing the results to the expected outcome.

### High-Throughput

> We can deploy multiple parallel instances of that process to improve throughput. **Competing Consumers** is needed to guarantee that each message on the channel is consumed by exactly one of N available processors. This allows us to speed up the most time-intensive process and improve overall throughput.

<figure><img src="https://4276734169-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F15hXGxUjZ4Oswj2kOjvJ%2Fuploads%2FqF89OQuq8fIkDJhssxvA%2Fpipes-and-filters-messaging-parallel.png?alt=media&#x26;token=c05e13ae-3e77-4d07-9cb5-61106f5ca5ca" alt=""><figcaption><p>Source: Enterprise Integration Patterns <a href="#references">[1]</a></p></figcaption></figure>

{% hint style="success" %}
**Heuristic**

Parallelizing filters works best if each filter is stateless.
{% endhint %}



***

## References

1. Hohpe, G., & Woolf, B. (2003). _Enterprise integration patterns: Designing, building, and deploying messaging solutions_. http://www.gbv.de/dms/tib-ub-hannover/666294666.pdf
