Introducing a new channel type: store realtime data values with Cache Channels

Cache-channels-realtime-results-1-blog.png

Announcing a new channel type for Pusher Channels

Introduction

Today we’re announcing a new channel type for use in Pusher Channels applications: cache channels.

What is a cache channel?

A cache channel remembers the last triggered event and sends it as the first event to new subscribers. This means that you can now use Pusher Channels as a realtime key-value store. Cache channels also provide a convenient way of working with changing data.

Representing data with Pusher Channels

Pusher channels are used for two things:

  • Event streams: representing instantaneous events, e.g. a channel mouse-clicks.
  • Variables: represents a varying value, e.g. channels like btc-usd, carlocation-123 or gamestate-123.

Channels model event streams very well. Many Pusher users are running applications with very high frequency updates – live location tracking and gaming are good examples of this. In these scenarios, users tend only to care about the latest value of a datapoint which is served so frequently that any cached event would be obsolete almost as soon as it was written.

But until today, channels could be awkward for representing variables. Changes to the value would be broadcast over the channels as they occur, but without implementing some complexity in your back-end to fetch initial state, clients subscribing to channels with variable frequency updates – such as a sports app displaying live match scores – would have to wait for an indeterminate amount of time to understand the current value.

A user joining a sports app to follow a football match would not want to wait for a new goal to know what the current score was.

Previously this initial state would have to be served up in the page itself, or the latest value would need to be requested by the client.

This results in three difficulties:

  • Unnecessary server requests
  • Higher time-to-first-event
  • Application complexity (in order to fetch the data and solve the scalability and latency issues)

How do cache channels solve this?

With cache channels, you can avoid the “fetch initial state” workaround and reduce some of the overhead in accommodating variable frequency updates on “normal” Pusher channels. When the client subscribes to a cache channel, they receive the latest value that has been cached. This simplifies things quite significantly and users working with variable values should be able to delete some code by using cache channels.

Let’s compare cache channels to the “fetch initial state” workaround:

  • Fewer server requests: Your server only gets a request if there’s a cache miss.
  • No more missed updates due to network reconnect: Re-subscription will get the latest cached value, so the client does not have to re-fetch it from your server.
  • Lower initial latency: For a cache hit, the time to initial value is two network hops.

How do I implement a cache channel?

Cache channels use the same publish/subscribe API you already know.

Cache channels begin with the prefix cache- or private-cache-, e.g. cache-carlocation-123. In all other respects, the API is exactly the same:

1// Trigger an event - this will be cached
2pusher.trigger('cache-carlocation-123', 'update', {lat: 51, lng: 0.2});
3
4// Subscribing - this will immediately get the above update
5const carLocationChan = pusher.subscribe('cache-carlocation-123');
6carLocationChan.bind('update', function (loc) {
7    // Display the location on a map
8});

When an event is triggered on a cache channel, Pusher Channels caches this event. When a client subscribes to a cache channel, if a cached value exists, this is sent to the client as the first event on that channel.

Data storage

The feature is designed to be a convenient way for clients to fetch the latest value from the edge of the network. It is not a permanent store of data. This is generally our preferred approach to handling your data: only holding it for as long as it makes it convenient for you to build your apps. If you’d rather we don’t store any data, you will not need to use this feature.

The data is ephemeral and the cache is removed after 30 minutes. Usually, new data will be coming in regularly to replace the latest value, but in some scenarios a client may request something that has already been purged. This acts like a traditional “cache miss”. In these circumstances, we can make a request to an endpoint on your server to get the value the client was looking for, while still supplying the simplified subscription interface.

Handling cache misses

A cache channel’s value is cached for up to 30 minutes after the value is published. If, when a client subscribes to a cache channel, there is no cached value, the cache should be re-populated. There are two ways to handle this:

Approach 1: cache_miss webhooks

If a client subscribes to a cache channel and there is no value available, Pusher Channels will send a webhook to your server. You can configure this in your dashboard:

Pusher-channels-handing-cache-misses.png

Received webhooks will look like:

1{
2  "time_ms": 1327078148132,
3  "events": [
4    { "name": "cache_miss", "channel": "cache-carlocation-123" }
5  ]
6}

When your server receives a cache_miss webhook, it should trigger a new event on this channel, thus re-populating the cache.

For more details, refer to Webhooks in Channels docs.

Approach 2: pusher:cache_miss events

In addition to a webhook event, if a client subscribes to a cache channel and there is no value available, Pusher Channels will send the subscribing client a pusher:cache_miss event. The client can use this to ask your server to re-trigger the event:

1carLocationChan.bind('pusher:cache_miss', function () {
2  fetch('/trigger/cache-carlocation-123', {method: 'POST'});
3});

Go through the Channels docs to find out more about channel types.

At the moment of writing this article, cache channels are available now as a beta release. If you have questions, feedback or would like to take part in user testing reviews, please get in touch with our beta support team.

Pusher Channels is a hosted data messaging API, which has everything you need to build engaging, dynamic realtime apps. Sign up to start building data and event streams with Pusher Channels, or look at our docs and tutorials to learn more.