Home

Awesome

topology

Different network topologies

This repository is meant to show implementations of various network topologies, preferably distributed implementations.

Ideas

Fully connected

Every node in the network connects to every other node. This is "efficient" because every message only has to travel one jump.

But does not scale at all, whatsoever.

Star

Every node in the network connects to a single central hub. This is a centralized model and doesn't scale unless you group subparts of your network or limit the size of your network.

As long as all the other nodes in the network know about each other and the central node they should be able to elect a new central node if the center goes down.

Ring

A ring network is actually distributed except every node can become a failure point unless you can reconnect over the gaps.

Tree

Every node is connected to more then one node. And the maximum time it takes for a message to propagate is O(log n).

However if any node goes down it isolates all its descendants.

Grid

It takes some time for information to propagate and filling holes in the grid is complex.

However it's conceptually simple.

HyperCube

Like a grid but has 4 dimensions. There are more connections between peers so it's more efficient

Mesh / Random network / Small world network

Like a fully connected network but not fully connected. This means you have some number of connections per node but not all of them. With an emphasis on no structure.

A good algorithm has shorter jump distances then hypercubes.

Preventing network splits

When you construct any network which isn't fully connected there is a good chance that the network will split into two or more parts because connecting nodes go down.

One solution is to throw servers at the network to keep it together. This is far from optimum.

Another is to use send address announcements to nodes within a certain amount of jumps. This allows small islands to become larger by opening newer connections and favouring new connections that are further away hoping to expand the network size.

Random walks

More reading needed

Probably means asking nearby nodes for other their nearby nodes and continiously randomly choosing new nodes to go talk to.

This assumes that as you make more hops the odds are you will be further away. You can do this walking until you need a new connection because one of your peers dropped and can then connect to a far away random peer immediately.

Chaos nets.

Read more.

Examples

All the network topologies in this module will be implemented with the following api:

topology(channel, options, onConnection)

var topology = require("...")

topology({
    createNode: function createNode() {}
    , createPeers: function createPeers() {}
}, {
    namespace: namespace
    , id: id
}, function (stream) {
    ...
})

options consists of an optional namespace and an optional id.

The id is the id for the current node in the topology which defaults to a uuid. You may want to overwrite this with say a port if your using TCP as your channel.

The namespace is a namespace parameter passed to node.connect which allows you to basically ask the node to multiplex for you. This only relevant if your node supports multi plexing by default (like webRTC and datachannels)

The channel consists of a createPeers method which should return a Peers object that looks like peer-nodes and of a createNode method which has should return a node that has .listen and .connect method like peer-connection-network

The onConnection callback fires when we have a streaming connection to another node in the network

fully connected

A fully connected network will connect to every other peer in the network.

This means it uses the channel to create a node for itself then connects to every peer that it hears about through the peers object.

In this example we replicate a scuttlebutt model over the network

Because we use signal-channel for the networking and because signal-channel can be used on either node.js or browser with the same API the below snippet works in browsers and node without any code changes

var fully = require("../../fully")
    , SignalChannel = require("signal-channel")
    , Model = require("scuttlebutt/model")

    , m = Model()
    , channel = SignalChannel("unique namespace")
    , key = Math.random() * 10
    , value = Math.random() * 10

m.on("update", function (update) {
    console.log("updated!", update)
})

m.set(key, value)
console.log("set key", key, "to", value)

fully(channel, function (conn, opener) {
    var peerId = conn.peerId

    if (opener) {
        hookUp(conn.createStream("model"))
    } else {
        conn.on("connection", function (stream) {
            if (stream.meta === "model") {
                hookUp(stream)
            }
        })
    }

    console.log("connected to", peerId)

    function hookUp(stream) {
        stream
            .pipe(m.createStream())
            .pipe(stream)
    }
})

References

Installation

npm install topology

Contributors

MIT Licenced