Push Notifications
A notification in a message you can display to
the user outside of your application's normal UI. When you tell the system to
issue a notification, it first appears as an icon in the notification area. To
see the details of the notification, the user opens the notification drawer.
Both the notification area and the notification drawer are system-controlled
areas that the user can view at any time. System will also display the
notification as a TOAST when user is
logged-in along with increment in the notification drawer.
Lightweight Event Driven
Notification System
1.1
Event Generation
The event generation phase happens while processing the
response to a user request. As such, we wanted to ensure that there was little or
no impact on the response times from where notification is called/generated. To
ensure this was the case, all we will do is store the minimum amount of data
possible/lightweight message on the queue. We store the minimum amount of data
possible or a lightweight object, just a few identifiers, so it shall not slow
down the response just to kick off a push notification. Everything after this
initial message drop on the queue action is processed out by another consumer
which shall produce no impact on site performance.
All calls to the notification shall drop quickly drop a
message on the queue.
1.2
Event Targeting
This is the event targeting phase which will receive event from the
queue. We may or may not have more than one worker reading from the queue. When
a worker receives an event, it loads up any additional information necessary (additional processing) to act on the notification. E.g. for
checking to see what users should be notified, whether those users have devices
that are registered to receive notifications or if they’ve opted out of
notifications of this type etc.
1.3
Message Delivery
The web has been largely built around the so-called
request/response paradigm of HTTP. A client loads up a web page and then
nothing happens until the user clicks onto the next page. AJAX started to make
the web feel more dynamic. Still, all HTTP communication was steered by the
client, which required user interaction or periodic polling to load new data
from the server. All of these work-arounds share one problem: They carry the
overhead of HTTP and also numerous unnecessary HTTP connections when there
isn’t actually any update available with the server. Because of this we decided
to use NODE JS along with Web Sockets. Node JS will receive the event from
queue when it’s published. The WebSocket connection is a persistent connection
between the client and the server and both parties can start sending data at
any time. The Web Socket connection here will be established at the user login.
Based on to whom message belongs and logged in user, the connected Web Socket
will deliver the notification on the UI. Shall be only one dedicated Web Socket
connection per browser. Single web socket connection can be used not only just
dropping notifications but performing other tasks too based on events. This
phase will take care of persistence too.
Scalability and Availability
Ques 1.
: How do we ensure that the delivery to MQs are
both scalable and highly available?
Ques 2.
: What if the Node JS Worker crashes?
1.
The first step to ensuring a service is scalable
is to divide the workload.
2.
Workload is divided across two queues configured
in ActiveMQ. Already having specialization in managing/configuring
ActiveMQ which is a very powerful message broker with advanced features for
enhanced availability, scalability, performance and reliability. To provide
more scalability on ActiveMQ Brokers, we can allow many brokers to be connected
into a network.
3. Java
Queue Consumer: Spring DMLC took its inspiration from MDBs, it did not
replicate these disadvantages; quite the opposite, in fact. The Spring DMLC is
commonly used to create what have become known as Message-Driven POJOs (MDP).
MDPs offer all of the same functionality as MDBs but without the disadvantages
listed above. The Spring DMLC provides many features including Caching JMS
resources, dynamically grow and shrink consumers, re-establishes connection on
non-availability of broker etc.
4.
Node Consumer: ActiveMQ is written in Java and
has a full-fledged JMS client, but its STOMP support and RESTful API let us
interface with the messaging queue quite nicely using Node.js. Node.js is
single threaded and currently we would go with only one Node JS Worker and if
required can divide the workload across individual Node.js processes anyway, so
this can work out well. Configuring our Node.js processes in this way makes it
easy to scale horizontally. Whenever we need to add more processing power to
the cluster, we can just add more servers. If only one and individual Node JS
instance is down, message would still be persisting with the broker.
With Node, you’ll find that STOMP is a great choice of protocol for subscribing to queues. Using node-stomp as a STOMP CLIENT as a way of connecting to queues.
With Node, you’ll find that STOMP is a great choice of protocol for subscribing to queues. Using node-stomp as a STOMP CLIENT as a way of connecting to queues.
a.
Ability to support different STOMP protocol
versions.
b.
ACK and NACK support
5.
Web Socket: The WebSocket API enables web
applications to handle bidirectional communications with server-side process in
a straightforward way. Socket-io certainly makes working with Websockets very
easy. It abstracts many transports, including AJAX long-polling and WebSockets,
into a single API. It allows developers to send and receive data without
worrying about cross-browser compatibility. Socket.IO provides both server-side
and client-side components with similar APIs. Limiting to the user, we would be
using Web Socket for now only send data from the server so it would be Unidirectional.
6.
UI: Socket-io client and JQuery.
Notification Persistence, Quick
& Guaranteed Delivery
All notifications will ultimately make to a persistence
store. User shall be shown same Notifications in the notification drawer
irrespective of the device usage. Persistence shall also allow to keep track of
the notifications delivered or not delivered to the user and mark
appropriately. This shall provide support to deliver the pending notifications
to the user when he is not available or logged-in to the next time when he logs
in.
The choice is MongoDB.
MongoDB being a No-SQL database works with documents and
collections.
The
persistence shall have minimal or no impact on the notification ‘time to reach’
to the user.
1.1
Being Quick
·
Notifications are usually a highly read object,
so we want to be able to get the list of currently unread notifications very
quickly, not try and calculate on the fly.
·
Being Event-Driven, notifications (intended/subscribed)
are delivered to users available in real-time as soon as event is generated
(prior persisting).
·
The event targeting phase needs to make sure to
drop a lightweight notification object on the queue along with list of intended
recipient users.
1.2
Guaranteed Delivery
For guaranteed delivery of the notifications when user is
not logged-in or auto logged-off by the system and for making notifications
available all the time irrespective of the user device. System will persist and
will make available the notifications next time user logs in.
Comments
Post a Comment