Global biotech company banner

EDA Best Practices and Usage Patterns

Share with your network!

In a previous blog post, Vaishnavi Krishnamurthy, senior engineering director at Proofpoint, introduced event-driven architecture (EDA) and some of its advantages. In this post, I’ll talk about a usage pattern and some best practices we’ve landed on when using EDA at Proofpoint.

Asynchronous request-response pattern

We often use our message bus to implement an asynchronous request-response message exchange pattern. Unlike more prevalent synchronous request-response, the requester is unaware of responder(s). Also, multiple or no responders may act on the request.

Actors in an event-driven architecture

Reviewing and expanding on the previous blog, these are the following actors in EDA:

  • Suppliers add events to the bus.
  • Consumers are informed of events on the bus.
  • The bus forwards events from suppliers to consumers.

There are two additional actors in message exchange EDA:

Requester—A supplier that asks for work to be performed; also, often a consumer of work results.

Responder—A consumer responsible for implementing work and a supplier of work results.

Event schema

Events should have a well-defined and well-documented schema. Consider having the event bus reject invalid events. The schema should include several elements:

  • Version—A versioned schema allows forward and backward compatibility. This also allows consumers and suppliers to be updated flexibly.
  • Correlation ID—A universally unique identifier to tie together the request and response; also useful for distributed tracing.
  • Timestamp—When did the request occur?
  • Tenant ID—What customer is the work on behalf of?
  • Action—What work is the supplier requesting to happen?
    • Command—The work to be done.
    • Target—The resource being acted on.
  • Requester—The identity of the requester; this could be a human or an automation process.
  • Responder—The identity of the responder.
  • Response—What action did the consumer complete?
    • Command—The work that was done. 
    • Target—The resource acted on.
    • Result—A result code; HTTP status codes might work well here.
    • Error—Any textual information that might help diagnose a problem.

Any additional elements in the schema are agreed upon by the requester and implementing responders. The event bus and related services shouldn’t be expected to understand or act on additional elements.

Event bus technology

There are many great event bus offerings. One is Kafka. It’s deployable in all major cloud platforms and available as a managed service. For the front end, use the built-in browser event system or a JavaScript package. Particularly interesting are the capabilities available with federating the enterprise event bus and the active user’s web browser event bus.

Topics, partitions and replicas

Kafka has flexibility in how topics and partitions are used. When choosing how you want to spread the processing load across your brokers, consider the following:

  • You’ll want at least one replica for each topic. More replicas will increase fault tolerance with the cost of increased storage space, network bandwidth and ingestion latency.
  • If you have a consumer per tenant and need to enforce entitlement, you’ll need to create a topic for each tenant.
  • If you need to enforce the ordering of events, create only one partition per topic.
  • If you need high throughput with parallel consumers, create a partition per consumer.
  • You’ll need a broker for every 4,000 partitions. You should keep the number of partitions for a Kafka cluster under 200,000 for zookeeper-managed clusters. The practical limit for Kraft managed clusters is still being investigated.

Responder best practice

Event responders should be idempotent; the responder should produce the same response on the first and any subsequent occurrences of identical request events. If a responder determines that the work has already been completed or no work is requested, a successful status response should still be sent.

Work status

You can easily create a service that tracks the status of all work. The service will passively listen to all request and response events. The service should update a document store, identified by the correlation ID, with the contents of each event. The document store will need indices based on what attributes the service needs to query. 

Join the team

At Proofpoint, our people—and the diversity of their lived experiences and backgrounds—are the driving force behind our success. We have a passion for protecting people, data and brands from today’s advanced threats and compliance risks

We hire the best people in the business to:

  • Build and enhance our proven security platform
  • Blend innovation and speed in a constantly evolving cloud architecture
  • Analyze new threats and offer deep insight through data-driven intelligence
  • Collaborate with our customers to help solve their toughest cybersecurity challenges

If you’re interested in learning more about career opportunities at Proofpoint, visit this page

About the author

Chas Honton is a principal engineer on the Message Intelligence Services team at Proofpoint. He has been an open-source contributor for 28 years. Chas coaches highly productive development teams that deliver engineering excellence and customer delight.