How to make time-sensitive requests to Reactive servers

To interact with our events-stream and view-counts services, you will need to time your API requests based on the Reactive's server clock to get the results you expect. Doing so is a simple two-step process.

First, get the difference between your client's clock time and Reactive's server time through:

  1. Getting the Reactive server time through our time endpoint.
  2. Then compare that time to the current client time to get the offset between your client's clock and Reactive's clock servers.
  3. Finally, add 25 milliseconds to the offset to ensure you're calling within the correct interval.

Here's a function that illustrates these steps:

/**
 * Calculates the delay required to sync the client's clock with Reactive's server's clocks.
 * @returns {integer} delay
 */
const getServerTimeDelay = async () => {
  const currentServerTime = await getTime();
  const now = Date.now(); // must come after getTime to ensure the closest sync and that clients are always in the past.

  const CLOCK_TIME_SERVER_DRIFT_BUFFER = 25;
  const delay = now - currentServerTime + CLOCK_TIME_SERVER_DRIFT_BUFFER;
  return delay;
};

Second, based on this offset, schedule your requests to Reactive on the required interval. For example:

/**
 * Make requests to Reactive based on the server interval. 
 * 
 * @param {function} requestFunction - This method represents the API call to Reactive's servers. 
 * @param {integer} interval - This is the duration in milliseconds of the interval that the requestFunction should be called for. For the events-stream service, this should be 250. For the view-counts service, this value should be 1000. 
 * @param {integer} offset - This should be the client clock offset from the Reactive server clock as calculated above.
 */
const makeTimeSensitiveRequestsOnInterval = (requestFunction, interval, offset) => {
  const currentServerTime = Date.now() - offset
  const timeUntilNextInterval = interval - (currentServerTime % interval)
  const schedulingFunction = () => {
    setInterval(requestFunction, interval)
  }

  /** 
   * Wait until the server interval starts on Reactive's servers, then make
   * requests each interval. 
   */
  setTimeout(timeUntilNextInterval, timeUntilNextInterval)
}