Skip to content
This repository has been archived by the owner on Sep 25, 2020. It is now read-only.

Developer's Guide

Jeff Wolski edited this page Jul 2, 2015 · 4 revisions

As a developer, you'll want to know how to plug ringpop into your application. The sections below may make this easier for you:

Table of Contents

API

ringpop provides a straight-forward and minimal API for application developers. The properties, functions and events part of its public interface are documented below. Anything not documented should be considered to result in undefined behavior.

Properties

  • isReady - A boolean flag used to indicate whether ringpop is ready. This property should be considered read-only.
  • joinSize - The number of nodes that must be joined during bootstrap before ringpop is ready. This should be modified before calling bootstrap in order for the mutation to be of any use. Default is 3.
  • requestProxyMaxRetries - Maximum number of retries attempted when ringpop proxies a request to an alternative destination
  • requestProxyRetrySchedule - An array of numbers used as a multiple of the amount of milliseconds to delay before the next retry

All other properties should be considered private. Any mutation of properties not listed above will result in undefined behavior.

Functions

  • bootstrap(bootstrapFileOrHosts, callback) - Seeds the hash ring, joins nodes in the seed list and starts the gossip protocol
  • handleOrProxy(key, req, res, opts) - Returns true if the key hashes to the same instance of ringpop, otherwise, returns false and proxies req to the node to which the keys hashes
  • lookup(key) - Returns the node to which the key hashes
  • whoami() - Returns the address of the running node

Events

These events are emitted from the top-level Ringpop object when:

  • ready - ringpop has been bootstrapped
  • changed - ring or membership state is changed (DEPRECATED)
  • lookup - A key has been looked up. A single argument is provided to the listener which takes the shape: { timing: Number }
  • membershipChecksumComputed - the membership's checksum has been recomputed after a membership update
  • membershipChanged - membership state has changed (status or incarnation number). A membership change may result in a ring change.
  • requestProxy.checksumsDiffer - a proxied request arrives at its destination and source/destination checksums differ
  • requestProxy.requestProxied - a request is sent over the proxy channel
  • requestProxy.retryAborted - a retry is aborted before attempted
  • requestProxy.retryAttempted - a scheduled retry expires and a retry is attempted
  • requestProxy.retryRerouted - a retry is rerouted to another destination
  • requestProxy.retryScheduled - a retry is scheduled, but not yet attempted
  • requestProxy.retrySucceeded - a request that is retried succeeds
  • requestProxy.retryFailed - a request is retried up to the maximum number of retries and fails
  • ringChanged - ring state has changed for one or more nodes either having joined or left the cluster. All ring changes are member changes, but not vice versa.
  • ringChecksumComputed - the hash ring's checksum was computed
  • ringServerAdded - a server was added to the ring
  • ringServerRemoved - a server was removed to the ring

Code Walkthrough

Instantiate ringpop by providing it the title and listening address of your application. It's important to note that the listening address of your ringpop instance is also used as a globally unique identifier for the instance within the ring. Therefore, make sure hostPort is unique.

var ringpop = new RingPop({
    app: 'myapp',
    hostPort: 'myhost:30000'
});

Then bootstrap ringpop. ringpop will use the bootstrap hosts array or file path you provide it as the seed list for joining an existing cluster:

ringpop.bootstrap(bootstrapHostsOrFile, function onBootstrapped(err, nodesJoined) {
    // bootstrap completed, failed or timed-out
});

When ringpop has joined enough nodes, it will be ready for use and emit a ready event. Applications should refuse requests until ringpop is ready.

ringpop.on('ready', function() {
    // do something
});

Applications can call ringpop's lookup function to discover which node a key hashes to. If the key hashes to the same node performing the lookup, then that node is free to process the incoming request. Otherwise, applications must forward the request to the resulting node.

var node = ringpop.lookup('cba8e0bf-412f-4edd-b842-882a361a5a7f');

if (node === ringpop.whoami()) {
    // process request
} else {
    // forward request
}

The state of the hash ring will change when nodes join, leave, fail or are revived. When ringpop detects a change, it will emit a ringChanged event, a membershipChanged event or both. A ringChanged event will be emitted when the number of nodes in the consistent hash ring changes. This type of change usually leads to some keys being rebalanced. A membershipChanged event is finer-grained and emitted whenever a member's status or incarnation number is updated. This may or not affect the underlying ring keyspace. You may be interested in one or all of these events depending upon your use case.

ringpop.on('membershipChanged', function onMembershipChanged() {
    // do something interesting
});

ringpop.on('ringChanged', function onRingChanged() {
    // do something interesting
});
Clone this wiki locally