Advanced usage

Choose UnsServ version: Extreme or Stable

Every UnsServ service including Membership offer two different versions: Extreme and Stable.

In order to choose what version is wanted, the is_extreme parameter is used. By default it is set to True So that, if True the Extreme version is instantiated.

In case the Stable version is wanted:

from unsserv import join_network
membership = await join_network(("127.0.0.1", 77771), "network.id", is_extreme=False)

“Node” data structure

The basic data structure used in UnsServ is Node, which is a namedtuple. If the services are instantiated manually, Node data structures must be used. This is the data structure representing the P2P node. It contains two fields:

  • address_info: a tuple containing the IP and the port.
  • extra: a tuple containing any other property or identifier. This field is intended for defining Use-Case specific attributes.

In order to make use of Node, first it is imported:

from unsserv.common.structs import Node

And then a node is instantiated:

node = Node(address_info("127.0.0.1", 7771))

UnsServ also publishes a high-level API for instantiating nodes:

from unsserv import get_node

node = get_node("127.0.0.1", 7771)

Manual instantiation

The importable function such as join_network, get_clustering_service, get_X_service (where X is any service) are high-level API calls. They take care of parsing nodes, and selecting the specific Protocol depending on the service and the version. However it is possible to import the protocol an instantiate it manually.

The protocols folder structure is the following:

unsserv
├── extreme
│ ├── membership ├── Newscast
│ ├── clustering ├── TMan
│ ├── aggregation ├── AntiEntropy
│ ├── sampling ├── MRWB
│ ├── dissemination
│ │ ├── one_to_many ├── LPBCast
│ │ └── many_to_many ├── Mon
│ └── searching ├── KWalker
└── stable
├── membership ├── HyParView
├── clustering ├── XBot
├── aggregation ├── AntiEntropy
├── sampling ├── RWD
├── dissemination
│ ├── one_to_many ├── Brisa
│ └── many_to_many ├── Plumtree
└── searching ├── ABloom

For example this is how the Extreme Memership is instantiated:

from unsserv.common.structs import Node
from unsserv.extreme.membership import Newscast

node = Node(address_info=("127.0.0.1", 7771))
membership = Newscast(node)
await membership.join("network.id")

Handlers

Some of the services make use of handler in order to call them whenever a value is updated. In case of Membership or Clustering the handlers are called whenever the neighbours change.

Aggregation and Dissemination services also use the handlers. In case of Aggregation for calling it when the aggregate value is updated. And the Dissemination service calls the handler for notifying the user about a broadcast.

All of this four services expose two methods for adding and removing handlers, in the form of add_X_handler(handler) and remove_X_handler(handler), where X is dependant on each service. The handler must be a function that receives a single parameter, and it can be either asynchronous or synchronous.

For example in case of Membership or Clustering service:

async def handler(neighbours):
    ...
membership.add_neighbours_handler(handler)

Or in case of Aggregation service:

def handler(aggregate_value):
    ...
aggregation.add_aggregate_handler(handler)

Configuration parameters

Each service can modify its working behavior by means of the configuration parameters.

The configuration parameters are passed as arguments when initializing/starting the service.

When using high-level API calls:

from unsserv import join_network

membership = await join_network(("127.0.0.1", 77771), "network.id", local_view_size=5)

local_view_size is a configuration parameter. Or directly initializing it:

from unsserv.extreme.membership import Newscast
...
membership = Newscast(node)
await membership.join("network.id", local_view_size=5)

Membership Extreme (Newscast)

  • local_view_size: the maximum amount of neighbours to connect with at any given time. By default 10.

  • gossiping_frequency: the frequency in seconds at which neighbours are updated. By default 0.2

  • peer_selection: the policy for selecting what neighbour to connect with for exchanging the the neighbours. The available policies are:

    • rand: uniform randomly select an available node from the view.
    • head: select the first node from the view, that is, the node that has spent the least time in the local view (as neighbor).
    • tail: select the last node from the view, that is, the node that has been in the local view the longest (as a neighbor).

    By default is rand.

  • view_selection: the policy for selecting what peer to keep when updating the neighbours and they exceed the local_view_size. The available policies are the same as in peer_selection. By default is head.

  • view_propagation: the policy for selecting how the peers exchange are done. The available policies are:

    • push: the node sends its view to the selected peer.
    • pull: the node requests the view from the selected peer.
    • pushpull: the node and selected peer exchange their respective views.

    By default is pushpull.

  • rpc_timeout: the timeout in seconds waited for a response from the neighbour. By default is 1.

Membership Stable (HyParView)

It exposes the same configuration as Membership Extreme (Newscast).

And additionally:

  • ttl: when joining the neighbours randomness degree expected.
  • maintenance_sleep: how frequent neighbours are checked whether they are still alive.
  • active_view_size: the maximum amount of neighbours active nieghbours. This service uses two gorup of neighbours: passive and active. Passive are used whenever an active neighbour fails.

Clustering Extreme (TMan)

It exposes the same configuration as Membership Extreme (Newscast).

Clustering Stable (XBot)

It exposes the same configuration as Membership Stable (HyParView).

And additionally:

  • unbiased_nodes: the amount of neighbours from the active view that are not biased towards a cluster. By default is: the 20% of the active neighbours.

Aggregation Extreme & Stable (AntiEntropy)

It exposes the same configuration as Membership Extreme (Newscast).

Sampling Extreme (MRWB)

  • ttl: when sampling a node the randomness degree expected. By default is 10.
  • timeout: the timeout in seconds waited for carrying out the sampling. By default is 2.
  • maintenance_sleep: how frequent neighbours are maintained (keepalives or any other maintenace echanism). By deault is: 0.5.

Sampling Stable (RWD)

It exposes the same configuration as Sampling Extreme (MRWB).

And additionally:

  • quantum: a global parameter needed by the protocol. It must be equal or lower than 1/local_view_size. By default is: 0.1.
  • more_than_maximum: a value that must be higher than the local view size. This value is needed by the sampling protocol. By default is: 30.

Searching Extreme (KWalker)

  • ttl: when searching the precision degree expected (how likely it is to find). By default is 4.
  • timeout: the timeout in seconds waited for carrying out the search. By default is 4.
  • fanout: for each ttl, how many neighbours are queried. In total in every search: ttl*fanout nodes are queried. By default is 4.

Searching Stable (ABloom)

  • depth: when searching the precision degree expected (how likely it is to find). By default is 2.
  • timeout: the timeout in seconds waited for carrying out the search. By default is 10.
  • maintenance_sleep: how frequent neighbours are maintained (keepalives or any other maintenace echanism). By deault is: 1.

Dissemination Extreme Many-Many (LPBCast)

  • fanout: the amount of neighbours to whom the broadcast is forwarded in each hop. By default is 10.
  • buffer_limit: the amount of broadcast that are kept once received. The broadcasts are saved for discarding duplicates. By default is 100.

Dissemination Extreme One-Many (Mon)

  • timeout: the timeout in seconds waited for building a tree for broadcasting. The tree is built on-demand when data is broadcasted. By default is 5.
  • tree_life: the time in seconds that on-demand trees are maintained. by default is: 10.
  • fanout: the amount of neighbours to whom the broadcast is forwarded in each hop. By default is 10.

Dissemination Stable Many-Many (Plumtree)

  • retrieve_timeout: the timeout in seconds waited for retrieving an unreceived broadcast. When timeout expires manually is queried the broadcast origin node. By default is 3.
  • maintenance_sleep: how frequent neighbours are maintained (keepalives or any other maintenace echanism). By deault is: 1.
  • buffer_limit: the amount of broadcast that are kept once received. The broadcasts are saved for discarding duplicates. By default is 100.

Dissemination Stable One-Many (Brisa)

  • fanout: the amount of neighbours to whom the broadcast is forwarded in each hop. By default is 3.
  • maintenance_sleep: how frequent neighbours are maintained (keepalives or any other maintenace echanism). By deault is: 0.5.