Chord Socket

This is an extension of the MeshSocket which syncronizes a common dict. It works by providing some extra handlers to store data. This exposes the entire dict API.

Note

This is a fairly inefficient architecture for read intensive applications. For large databases which are infrequently changed, this is ideal. For smaller networks where there is significant access required, you should use the sync socket.

Basic Usage

There are three limitations compared to a normal dict.

  1. Keys can only be bytes-like objects
  2. Keys are automatically translated to bytes
  3. Fetching values is significantly slower than for a dict

The only API differences between this and MeshSocket are for access to this dictionary. They are as follows.

get() / __getitem__()

A value can be retrieved by using the get() method, or alternately with __getitem__(). These calls are about O(log(n)) hops, as they approximately halve their search area with each hop.

>>> foo = sock.get('test key', None)        # Returns None if there is nothing at that key
>>> bar = sock[b'test key']                 # Raises KeyError if there is nothing at that key
>>> assert bar == foo == sock[u'test key']  # Because of the translation mentioned below, these are the same key

It is important to note that keys are all translated to bytes before being used, so it is required that you use a bytes-like object. It is also safer to manually convert unicode keys to bytes, as there are sometimes inconsistencies betwen the Javascript and Python implementation. If you notice one of these, please file a bug report.

set() / __setitem__()

A value can be stored by using the set() method, or alternately with __setitem__(). Like the above, these calls are about O(log(n)) hops, as they approximately halve their search area with each hop.

>>> sock.set('test key', 'value')
>>> sock[b'test key'] = b'value'
>>> sock[u'测试'] = 'test'

Like above, keys and values are all translated to bytes before being used, so it is required that you use a bytes-like object.

__delitem__()

This deletes an association. Like the above, this call is about O(log(n)).

>>> del sock['test']

update()

The update method is simply a wrapper which updates based on a fed dict. Essentially it runs the following:

>>> for key, value in update_dict.items():
...     sock[key] = value

keys() / values() / items()

These methods are analagous to the ones in Python’s dict. The main difference is that they emulate the Python 3 behavior. So if you call these from Python 2, they will still return an iterator, rather than a list.

In addition, you should always surround values() and items() in a try-catch for KeyError and socket.error. Because the data is almost always stored on other nodes, you cannot guaruntee that an item in keys() is retrievable.

pop() / popitem()

These methods are also analagous to the ones in Python’s dict. The main difference is that, like the above, you should always surround these in a try-catch for KeyError and socket.error.

Events

In addition to the above, and those of MeshSocket, the ChordSocket object has two Events.

First there’s Event 'add'(). This is called whenever an association is added. Because the value is not necessarily stored by you, it is not given as an argument to this event.

>>> @sock.on('add')
>>> def handle_new_key(conn, key):
...     # conn is a reference to the socket
...     print("A new key was added: {}".format(key))
...

This class has one other event: Event 'delete'(). This is called every time an association is removed.

>>> sock.on('delete')
>>> def handle_deleted_key(conn, key):
...     # conn is a reference to the socket
...     print("A key was deleted: {}".format(key))
...

Advanced Usage

Refer to the mesh socket tutorial