Message-IDs for Handling Concurrency

This post serves as a guide for how you can use a Message identification (Message-IDs) on your messages (events and commands) to handle concurrency.

This post is in a series related to messaging. The overview is available in my Message Properties post.

YouTube

If you haven’t already check out my YouTube channel.

Message-IDs

Each message, regardless of it being an event or a command, should contain a way to identify its specific instance of that message. This is as simple as adding a GUID/UUID to your messages:

No other message (event/command) should ever use this ID (unless you’re also using a message owner). It’s a one time only usage that should be unique.

The producer of the event should be creating this ID before it publishes it. It shouldn’t be hydrated by some middle party.

Concurrency

Most systems support at least once messaging. Meaning, they will deliver a message to the consumer at least once. This means it can be delivered more than once.

Message handlers should be reentrant. You should be able to invoke multiple instances of a message handler concurrently and safely.

Meaning if the exact same instance of an InventoryAdjusted event was invoked twice (with the same ID), at the same time, the outcome would be the inventory on hand would increase by 10, not 20.

We can achieve this by having our message handler use the message ID apart of the same transaction it’s using apart of its state change.

Here’s an example using pseudo C#

The example above is using a unique key on Handler and MessageID columns in the Concurrency table. When we either try to insert the record or commit the transaction, it will fail if the unique constraint fails.

Events

Since an event can have multiple consumers/handlers is the reason why I’ve included the name of the handler as apart of the unique constraint. This is to demonstrate if you were using the same concurrency table for multiple handlers. In the case of event handlers, you want each handler to process the event, but not more than once each.

If you were using this for commands, you wouldn’t need to record the handler, just the MessageID.

Related Links

Follow @CodeOpinion on Twitter

Software Architecture & Design

Get all my latest YouTube Vidoes and Blog Posts on Software Architecture & Design

Event Versioning Guidelines

Event Versioning Guidelines

This post serves as a guideline for how to handle versioning for messages, specifically in most cases, events. This Event Versioning Guidelines post is in a series related to messaging. You can find the overview in my Message Properties post.

Backward Compatible

Generally, adding additional properties to an event will not cause a versioning conflict with the event consumer.

Meaning if we have a contract that defines the shape of our event, as long as we don’t break that contract, the existing event consumers will be able to process our new event and will ignore the additional properties.

Also, if you are persisting events to an event/data store, you must be able to upcast an old stored event to our new version.

This isn’t that crazy of a concept. If you think about a relational database, when you need to add a new column, you generally will create the new column as having a default NULL value. The difference is you won’t backfill the existing events by replacing NULL with an actual value. Rather you handle the NULL value in your application code.

If you must change the contract, then you must create a new version of that event and cause a breaking change.

Version Number

One option for defining a new event is to include a version number within the event itself. Event consumers can then use this version number to determine how they should handle or process the event.

Regardless of backward compatibility, you can use a version number alongside your event name to indicate to consumers which contract to an event they are processing.

As an example using Semantic Versioning to define our events:

New Event

Most of the time if an event is not backward compatible, you likely have an entirely new event. And because of this, the name of the new event is likely different from the old event.

What’s tricky is to determine if this new event replaces the old event. Is the new event a discovery of an actual business event or is it simply a new understanding that replaces an existing concept?

Double Publish

If an event isn’t backward compatible, you might want to publish both v1 and v2 of the event that occurred.

Meaning the publisher writes both versions (v1 and v2) to the message queue or event stream.

One issue with this approach is consumers must understand this. They must understand they should only process one or the other. They either must process v1 and ignore v2, or process v2 and ignore v1.

This isn’t that big of a deal when the consumers aren’t replaying (re-processing) existing events from an event store. If you are using an event store and replaying events for a projection, you likely do not want to double publish. The reason being is processing both could have a negative impact.

If you’re not replaying events, then you’re consumers have to implement the new version you’re publishing. At the same time, they can remove the handling of the old event.

It’s not that odd to double publish by creating a new event and deprecate an old event and remove it once all consumers have handled the new event.

Event Versioning Guidelines

If you have any additional event versioning guidelines that I have omitted, please let me know on Twitter or in the comments.

Related Links

Follow @CodeOpinion on Twitter

Software Architecture & Design

Get all my latest YouTube Vidoes and Blog Posts on Software Architecture & Design

Message Naming Guidelines

Message Naming Guidelines

As with many things in software development, naming can be difficult. The name of a message can be incredibly important which is why naming of your messages should be taken with consideration. This post is to be used for message naming guidelines with dos and don’ts based on my prior experiences of the good, the bad, and the ugly.

This blog post is in a series related to messaging.  You can find the overview in my Message Properties post.

YouTube

If you haven’t already, check out my YouTube channel where I’m covering this blog post in video form.

Commands vs Events

Commands and Events are the types of messages I generally deal with within a system. We need to differentiate between commands and events because they will be named differently depending on which one they are.

Commands

Commands are messages with the intent to change the state of the system. They are actions to be performed that have side effects. They may be created by an end-user or another part of the system that could be automated. They are a way to execute behavior.

I try to avoid using Create, Update, Delete, Save prefix as the verb. Rather I try to focus on the business process and the intent of the user to initiate the state transition. This can be one of the verbs mentioned above, but try and dig deeper to reveal the actual intent.

My general guideline for naming is a verb and a noun. Basically the action against a thing.

Do

PlaceOrder
GenerateInvoice
ApplyDiscount

Don’t

Order
SaveInvoice
Discount

Events

Events are statements of fact. They are named in the past tense. They are named this way because they have already occurred. Events are things that have happened within a system. They are the result (not in method return sense) of an executed command.

I try to avoid Created, Updated, Deleted suffix as the verb. Trying to stay way from CRUD naming to get to the essence of what actually occurred from a business process view.

My general guideline for naming an event is a noun and a verb. As mentioned the verbs are past tense.

Do

OrderPlaced
OrderInvoiced
DiscountApplied

Don’t

Ordered
InvoiceCreated
Discounted

Suffix

I generally prefer using a suffix of Command or Event to your types/classes. Ultimately, my only guideline is to be consistent in doing so. If you choose to suffix, always do it, if not, don’t ever do it. Consistency is key.

Examples

PlaceOrder vs PlaceOrderCommand

OrderPlaced vs OrderPlacedEvent

Serialization

If you are persisting events to an event store, document store, or relational database, you’re likely serializing your event objects.

Consumers of those events will then pull those serialized event objects out of the store and try and deserialize them back to an event object you want it to be in the original type.

For example, in .NET you might be serializing using JSON.NET;

The issue now is how do you deserialize this string back to an OrderPlaced type?

Don’t

The first reaction may be to include the CLR Type name alongside the JSON. You can accomplish this by using the TypeNameHandling setting the serializing:

This would result in a $type property that points to the CLR type. When deserializing this string, you can now get it back as the original type.

I discourage using the explicit CLR type information alongside the event because you are very likely going to either rename, change the namespace, or assembly of an event. And at this point, you won’t be able to deserialize using this information.

Do

Include and persist a separate piece of static data alongside your serialized event to define what the name of the event is. This should be concrete and manually mapped from this string to a specific type you want to deserialize to. This allows you to move the specific event type to any assembly, namespace or even rename.

You can see an example of this in my SQLStreamStore demo/sample application.

Message Naming Guidelines

If you have any additional message naming guidelines that I have omitted, please let me know on Twitter or in the comments.

Related Links

Follow @CodeOpinion on Twitter

Software Architecture & Design

Get all my latest YouTube Vidoes and Blog Posts on Software Architecture & Design