Performance considerations creating multiple events

Events usually require sending notifications via various media. Sending notifications may be a time consuming task for medium to large scale applications. This document describes the problem and, using email notification as an example, shows tactics to reduce the impact on performance.

Sending e-mails

One of the most used alternatives to sending notifications is via e-mail. So the easiest way to process a new event should be: identify it, create it and notify whoever is required. Sounds nice but does not scale in medium to large applications. Let's take a look at the problem and different ways to face it.

To send an e-mail a program basically has to connect to an e-mail server, send the e-mail, and disconnect. As connecting to and disconnecting from an e-mail server is time consuming it is recomended to send e-mails asynchronously.

A good alternative, then, may be to send e-mails in a separate thread, using a Submit command, for example. A new thread that connects, sends an disconnects, is created for each e-mail to send.

This solution, however, may face serious problems when a burst of e-mails have to be sent. If queued, queues may be very long. If executed in parallel the process may fail, as e-mail servers usually limit the number of connections from a given origin.

The most scalable alternative is to queue the e-mail request and have a service program that connects to the e-mail server, sends all e-mails in the queue, and disconnects. There may be several programs like this, running in parallel, if required.

Coding for performance

The API described in the document Creating an Event handles event creation and the related notifications processing in a single call. This is the easiest but least scalable solution as shown above.

The first step to scale up is to change calls to NewEvent to NewEventBatch (both have the same parameters). This change creates the event but leaves corresponding notifications for later processing.

Processing notifications

To process all pending notifications generated by any event, developers have to invoke the "ExecuteNewNotificationsActions" procedure.

The "ExecuteNewNotificationsActions" procedure sends all pending notifications. Notifications related to events that have expired or been canceled are not considered. A set of notification identifiers can be sent as a parameter. This parameter is relevant for web notifications only and, if it's not empty, the specified web notifications are processed only.

ExecuteNewNotificationsActions calls strategy

The following are a few strategies that may be used to call ExecuteNewNotificationsActions procedure.

Create events and call ExecuteNewNotificationsActions synchronously

This option is suitable when multiple events are created together in the application logic and the developer intends to process all notifications as soon as possible. It works well, particularly when the application has a limited number of users and event types, and the creation of associated events is concentrated in a few parts of the knowledge base.

It does not scale well.

Create events and call ExecuteNewNotificationsActions asynchronously

This option scales better and provides fastest response times than the previous one as notification processing is moved to another process. Usually this asynchronous processing is achived using the Submit command.

Create events and wait for the next scheduled execution of ExecuteNewNotificationsActions

This, highly scalable approach, runs ExecuteNewNotificationsActions on a timely basis (say every minute, for example) using the Operating System scheduling alternatives.

Events are created as needed and the corresponding notifications are processed the next time the scheduled ExecuteNewNotificationsActions process is executed.

The ExecuteNewNotificationsActions procedure should be called by a Main, Command line procedure that is scheduled to run on a timely basis.