DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Schema Change Management Tools: A Practical Overview
  • Providing Enum Consistency Between Application and Data
  • Architecture and Code Design, Pt. 2: Polyglot Persistence Insights To Use Today and in the Upcoming Years
  • How to Build a Full-Stack App With Next.js, Prisma, Postgres, and Fastify

Trending

  • *You* Can Shape Trend Reports: Join DZone's Software Supply Chain Security Research
  • AI-Based Threat Detection in Cloud Security
  • The Modern Data Stack Is Overrated — Here’s What Works
  • Scalable System Design: Core Concepts for Building Reliable Software
  1. DZone
  2. Data Engineering
  3. Data
  4. Pub/Sub Design Pattern in .NET Distributed Cache

Pub/Sub Design Pattern in .NET Distributed Cache

Scalable, performant messaging.

By 
Nandkishor Yadav user avatar
Nandkishor Yadav
·
Jun. 19, 22 · Tutorial
Likes (2)
Comment
Save
Tweet
Share
5.5K Views

Join the DZone community and get the full member experience.

Join For Free

The publish-Subscribe pattern also known as Pub/Sub is an indispensable tool for building enterprise-grade .NET applications. Just to refresh your memory, Pub/Sub is a messaging paradigm where the senders of messages (publisher) do not have any knowledge about the intended recipients (subscribers). Moreover, the publisher and subscriber applications do not interact with each other directly but instead depend on a common medium known as a topic. Hence, it's a loosely coupled messaging model.

Now, assume that you have multiple applications of different roles deployed within the same architecture and they need a mechanism to inform/notify each other about certain events. These events could either be transient (due to changes made on the run time) or database events (due to changes in the database). That's exactly where the publish-subscribe design pattern will help you to enable distributed events.

Enabling Distributed Events

To design a distributed event-driven architecture, developers traditionally turn towards using either of the following methods below.

Data Notifications Provided by RDBMS

If the datastore is limited to a relational database, using the database notification feature seems to be the best available option. It allows you to register your interest with the database server and notifies your applications when there is any change in the database result set due to update, add, or delete.

However, RDBMS are intrinsically unscalable and easily become a performance bottleneck in applications. You do not want to put an unnecessary load on your databases. Besides, the database notifications feature itself is inherently slow and doesn't support runtime data sharing as well.

Now you may understand why using the database as a messaging medium cannot be the best design choice for your applications.

Messaging Queues

The other option you have is to introduce a separate messaging queue in your architecture. While these messaging queues do a great job in helping you transmit messages among applications, these queues are not data-focused i.e. they do not monitor data changes in the databases or any other source. Also, these messaging queues cannot scale alongside your application tier.

Implement a Custom Solution

The last option left for you is to build your messaging platform/medium to suit your need. While this empty sandbox is very tempting at first, allowing you to develop your stuff however you want, there is complexity in terms of time and resources required. Although possible, building and managing a robust and scalable messaging platform is a very daunting task.

Now, the question remains which solution is easy to incorporate, is scalable, highly available, and also very reliable.

A Distributed Cache as a Messaging Platform

Fret not, there is an easy solution. A more modern way to incorporate a robust messaging platform is to use an in-memory distributed cache. NCache is the only truly native .NET/.NET Core distributed cache available in the market. It is an in-memory distributed cache that is extremely fast and scalable. It enables your applications to handle extreme transaction loads without your database becoming a bottleneck. You can also process data/stream in real-time with NCache 

NCache is usually deployed in the middle tier of your n-tier architecture. Take a look at the following diagram for a better understanding.

NCache deployed in an N-Tier architecture

Figure1: NCache deployed in an N-Tier architecture 


NCache is a cluster of cache servers serving tens of thousands of requests per second for your .NET applications as well as Java apps by keeping frequently used data in memory and helps avoid the majority of the database trips. 

Let’s first see how NCache is inherently suitable to act as a messaging bus with its event-driven architecture.

NCache Event-Driven Messaging

The following figure shows how NCache acts as a messaging bus for .NET and Java applications.

NCache as a Messaging Platform

Figure2: NCache as a Messaging Platform


Here NCache enables cross-platform communication by employing fast compact serialization, which converts your .NET or Java objects to binaries and then transfers them over to the cache cluster. So, this is how NCache allows your .NET applications to interact with Java applications and vice versa. For more information, take a look at portable data types.

NCache manages Pub/Sub design patterns under the name of Events and provides you with different methods to propagate your messages to other listening applications. Let’s take a look at both message types and see how a distributed cache can propagate them.

First, consider the data changes your applications need to listen to. Since NCache is also a .NET key-value store, it provides you with features to update your applications in case of any data changes within the cache. Because all of this is in memory therefore there is no performance bottleneck. These updates could either be;

  • Cache level item changes, be it update or remove.
  • Whole cache level data changes.
  • Continuous Query, where you register an SQL-like query to be watchful for if the result set changes within the cache. If it does your applications are notified.
  • Cluster changes, if any new node is added or removed, or crashed. (For administration).

NCache also allows you to register dependencies on databases including SQL, Oracle, and OleDb. This helps to keep your cache up to date with the database and thus your applications. For a full list of supported dependency types, check the database dependency. These dependencies are data change notifications registered with different data stores but you let NCache handle it. You can also combine database notifications with NCache data notifications to enrich your specific use case.

On the other hand, if you want to just propagate simple messages to complex .NET or Java objects then you should use the custom messaging feature. Here one application can produce the data and fire an event, whereas the interested listeners will receive the event almost instantaneously. For further information in this regard, you can see custom events.

NCache Pub/Sub API

NCache provides an in-memory Publisher/Subscriber (Pub/Sub) feature and a dedicated Pub/Sub Messaging store to enable real-time information sharing in .NET web applications. We will see how combining NCache and Pub/Sub can address the above challenges and eventually help your applications communicate better.

The Pub/Sub model naturally decouples publishers and subscribers by providing a channel where messages are published and subscribed by the interested users. Now when NCache acts as a messaging bus, the Pub/Sub model benefits from the underlying NCache distributed architecture and numerous handy features.

Basic Architecture

Without further ado, let's first get to know the basic components of NCache Pub/Sub and their working. The general flow of the NCache Pub/Sub messaging is like this - the publisher publishes messages on a topic using the ITopic interface. The subscribers create subscriptions to one or many topics and receive relevant messages. On successful message delivery, NCache receives the acknowledgment. Otherwise, NCache keeps retrying before the message expires (if expiration is set). Undelivered messages reside in the cache until eviction or expiration are triggered and enabled.

NCache Pub/Sub messaging

Figure 3: NCache Pub/Sub messaging


Subscription Types

NCache provides two different types of subscriptions namely, non-durable and durable subscriptions for pub/sun messaging. Furthermore, NCache enables exclusive and shared subscription policies. The relevant details are discussed below.

  • Non-Durable Subscription: By default, all subscriptions created on a topic are non-durable subscriptions. It conveys intended messages to the subscriber only until it remains connected. In case the subscriber’s connection is lost due to any reason, it doesn’t receive old messages on rejoining the network. This type of subscription is exclusive, which means that one subscription belongs to one subscriber.
  • Durable Subscription: It takes account of a message loss on subscriber disconnectivity. NCache retains the subscription of a subscriber on connection loss. Hence, a subscriber can receive the published messages of interest on reconnecting. Durable subscription offers two policies:
  1. Exclusive: One subscription belongs to one active subscriber at a time.
  2. Shared: One subscription can have more than one subscriber registered at a time and load is shared.

Getting Started with NCahce Pub/Sub

Let’s assume that there is an e-commerce store where new products are added to the store on regular basis by different vendors. Meanwhile, sales and offers are also provided on the products. The store managers and customers interested in the offered products need to stay updated about new products, products on sale, and discounts. NCache Pub/Sub feature can enable distributed notification system in this scenario. For that, NCache dedicated Pub/Sub Messaging store can be created first.

Let’s discuss the step-by-step process of achieving distributed messaging in the above scenario by using NCache Pub/Sub Messaging API.

Create a Topic

As a first step, a topic needs to be created where updates on new products can be published by different vendors. A new topic with a unique name can be created using the NCache ITopic interface. Here is how the publisher application uses the method CreateTopic to create a topic with the name newProducts.

C#
 
// Pre-condition: Cache is already connected
// Specify the topic name
string topicName = “newProducts”

// Create topic
ITopic topic = cache.MessagingService.CreateTopic(topicName);

In case a topic with the provided name already exists, an instance of the topic is returned as ITopic.

NCache allows to set topic priority while creating the topic. It is useful when certain events need to be communicated on a higher priority than others. For instance, the information about finished goods is urgent. Similarly, the update in product prices due to discount or sale can be most important being a seller/buyer. In that case, the topic priority can be set to high while creating it, and the relevant notifications can be received without any delay.

Publish Messages

Once a topic is created, the publisher application can publish relevant messages to that topic using Publish method. For that, an instance of the topic is first obtained by specifying the topic name. NCache provides the following two delivery modes while publishing messages:

  • All (default): Delivers the message to all the registered subscribers. It is useful when the information needs to be broadcasted.
  • Any: Delivers the message to any of the registered subscribers.

Furthermore, to efficiently manage the storage space of your Pub/Sub cache, you can also set expirations for messages.

In the following code, messages about new products are broadcasted by a publisher on an already existing topic newProducts.

C#
 
// Pre-condition: Cache is already connected
// Topic "newProducts" already created
string topicName = "newProducts"

// Get the topic
ITopic productTopic = cache.MessagingService.GetTopic(topicName);

// Create the object to be sent in message
Product product = FetchProductFromDB(10248);

// Create the new message with the object order
var productMessage = new Message(product);

// Publish the order with delivery option set as all
orderTopic.Publish(productMessage, DeliveryOption.All, true);

Subscribe for Topic Messages

Once the topic is created, a subscriber application can receive the messages published to that topic by getting a subscription. Since different types of subscriptions are supported, a subscriber interested in a non-durable subscription can use the CreateSubscription method. For durable subscriptions, the CreateDurableSubscription method can be used.

The code below shows how a subscriber application can create a subscription for the topic newProducts. MessageReceived the callback is registered to perform any intended operation on being notified. For instance, a subscriber can update product prices in the MessageReceived callback on receiving a sale notification.

C#
 
// Pre-condition: Cache is already connected
// Topic "newProducts" already created
string topicName = "newProducts"

// Get the topic
ITopic productTopic = cache.MessagingService.GetTopic(topicName);

// Create and register subscribers for topic newProducts
// MessageReceived callback is specified
ITopicSubscription orderSubscriber = orderTopic.CreateSubscription(MessageReceived);

In the above example, a non-durable subscription is created. Besides, a subscriber can create a durable subscription when there is a need to receive the old messages from subscribed topic/topics on reconnection.

NCache also provides a pattern-based method of subscription where NCache supports multiple wildcards to subscribe for single/multiple topics falling under the provided pattern.

Register Notifications

NCache empowers the publishers to know the status of messages and the availability of topics. The following notifications can be registered by the publisher applications:

  • MessageDeliveryFailure: Notifies the publisher if a message has failed to deliver because of any issue.
  • OnTopicDeleted: Notifies a publisher when a message gets deleted.

Here is how simply the publisher can register for these two types of notifications.

C#
 
// You have an instance productTopic of existing topic

// Register message delivery failure
productTopic.MessageDeliveryFailure += OnFailureMessageReceived;

//Register topic deletion notification
productTopic.OnTopicDeleted = TopicDeleted;

By following the above steps a basic Pub/Sub Messaging architecture can be integrated into any ASP.NET/.NET Core application.

Conclusion

To this point, you are familiar with the NCache Pub/Sub feature. Let’s summarize what benefits Ncache Pub/Sub offers to handle the limitations of existing solutions.

  • Due to the linear scalability, NCache Pub/Sub can handle the increasing number of subscription requests by adding cache servers and performing load balancing on the go. The scaling up occurs transparently to the users without hindering the communication process. Hence, you can easily scale up your communication performance using NCache Pub/Sub.
  • NCache Pub/Sub facilitates durable subscriptions, message delivery retires and delivery failure notifications to avoid message loss. Moreover, the distributed and replicated architecture of NCache ensures the high availability of NCache that accommodates subscribers' connectivity in dynamic environments. All together these features ensure reliable communication.
  • Since NCache is an in-memory distributed cache, the message store residing in the cache is inherently fast. In addition, NCache allows expiration and evictions on items residing in the cache to intelligently manage the storage space.

The scalability, reliability, and storage efficiency of NCache together with loose coupling and async messaging mode of Pub/Sub make NCache Pub/Sub feature highly promising for distributed messaging in the future .NET/.NET Core applications.

Database Design Distributed cache Relational database application Cache (computing) Data (computing) Delivery (commerce) .NET

Published at DZone with permission of Nandkishor Yadav. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Schema Change Management Tools: A Practical Overview
  • Providing Enum Consistency Between Application and Data
  • Architecture and Code Design, Pt. 2: Polyglot Persistence Insights To Use Today and in the Upcoming Years
  • How to Build a Full-Stack App With Next.js, Prisma, Postgres, and Fastify

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!