Skip to content
Rowan Seymour edited this page Jul 18, 2016 · 4 revisions

CasePro deployments may accumulate millions of messages and need to provide fast searchable access to them by users with different access restrictions.

Message Views

Inbox

This is the view of all labelled non-archived messages that a user has access to. Org-level users have access to all labels so they see all messages with any label. Partner-level users may see the same if their partner org isn't restricted, or may see messages with a subset of the org's labels.

To optimize this view, a Message.has_labels flag is maintained using database-level triggers, and a partial index then uses that to include only labelled messages:

CREATE INDEX msgs_inbox ON msgs_message(org_id, created_on DESC) 
WHERE is_active = TRUE AND is_handled = TRUE AND is_archived = FALSE AND has_labels = TRUE;

Filtering by label currently relies on msgs_message_labels and its indexes being in memory to be performant. At some point it may be necessary to have some fields from Message mirrored on to that table so that partial indexes can be used.

Daily Counts

The charts of replies sent per month at the org, partner and user levels are generated from per-day counts of replies (statistics.DailyCount). To avoid deadlocks, new items are always recorded by inserting a new count of 1 rather than updating an existing count for that day. When counts are read from the database, they are summed for each day or month. A scheduled background process is then responsible for squashing those counts into a single count per day, so that the count table doesn't get too big.

Total Counts

Total counts can be calculated from the daily counts but in some cases (e.g. all labels displayed on the inbox page with their counts), it's better to maintain a separate total count (statistics.TotalCount).

Label Counts

These are maintained with database-level triggers on msgs_message and msgs_message_labels.

Testing

There is a utility command perftest which is designed to be run on a real world database. It has a set of views which it will measure access time to, logged in as different users - an administrator user from each org, and a user from each partner org.

$ python manage.py perftest
Problems...
 > /outgoing/search_replies/?page=1 15.535 secs (org='Org #1', partner='')
 > /message/search/?folder=archived&page=1 5.430 secs (org='Other Org', partner='McPartners Ltd')
Clone this wiki locally