App Design

Client Region Design

Cached data are held in regions. A region is a logical grouping of data, and acts as a map data structure. Each entry within a region is a key/value pair.

Keys

Each region entry must have a unique key. Use a simple type of string or (integer) number, as opposed to an object. Using a string key simplifies development when using the REST API.

When using a number (integer) for the key, carefully generate the code that is written in a strongly-typed language and interoperates with the app. The Node.js Client assumes that a long will be used. Code from strongly-typed languages, such as Java, must also represent keys as type long to work correctly.

One example of interoperating is when a server-side function is used. Region.executeFunction and Pool.executeFunction cause server-side code written in Java (strongly-typed) to execute. These functions may operate on region entries, and therefore must use long (or Long) as the type for an integer type of key. A second example of interoperating is when both a Node.js app and another app that is written in a strongly-typed language both operate on the same region.

number types in Node.js are double precision floats. Floating point keys are never a good implementation. Therefore, the Node.js Client converts all integer-valued number type keys into a long and provides that long value to the cluster servers when doing region operations.

Regions as Used by the App

The app accesses regions hosted on the servers by creating a cache local to the app. This local cache is called a client cache. The client cache creates regions that must match the name of the regions hosted on cluster servers. The name of the region is used to connect the client and server for communication and updates. The type of the client region determines if data is only on the servers or if data is also cached locally within the client region (within the app) in addition to being on the servers. You may choose to store data locally for applications that require extremely low latency reads. Locally cached data can introduce data inconsistency issues, because region entries updated on a server are not automatically propagated to the client’s local cache.

Client region types associate a name with a particular client region configuration.

  • PROXY forwards all region operations to the servers. No entries are locally cached. Use this client region type unless there is a compelling reason to use the other type. Use this type for all Twelve-Factor apps in order to assure stateless processes are implemented. Not caching any entries locally prevents the app from accidentally caching state.
  • CACHING_PROXY stores a locally cached copy of data in the client cache for get operations. All put operations are forwarded to servers. Locally cached data can become stale unless subscriptions are enabled and register interest is configured for the region, such that server updates are reflected in the client cache. As a best practice, local caching should only be used with small data sets that infrequently change, and only if the in-process performance is critical. Zip codes are an example of an infrequently-changing, small data set.

Concurrency

There is no limit placed by the Node.js Client upon the quantity of concurrent, outstanding promises. When more than one promise is outstanding, all block until they all resolve. Therefore, the resolution of promises can affect the timing of the resolution of other promises.

Where this blocking affects the performance of your app, consider limiting concurrency with one of these examples: