Adding data to an E-Chord network using the client interface

In this tutorial, we will be adding data to an existing E-Chord network using a basic interface. For our purposes, we will be doing this with a network running locally on a single computer. We will be using the network created in the Setting up a three-node network on a single computer tutorial.

Executing the visualizer

To begin with, execute the visualizer script at scripts/visualizer.py if you haven't already. This will show us a view of the current network state, and will update every few seconds to account for changes.

Currently, the output of the script is the following:

╔═══════════════╦═══════════════╦══════════╗
║   Successors  ║  Predecessors ║   Keys   ║
╠═══════════════╬═══════════════╬══════════╣
║  2503 -> 8230 ║ 15626 <- 8230 ║  2503: 0 ║
╠═══════════════╬═══════════════╬══════════╣
║ 8230 -> 15626 ║  8230 <- 2503 ║  8230: 0 ║
╠═══════════════╬═══════════════╬══════════╣
║ 15626 -> 2503 ║ 2503 <- 15626 ║ 15626: 0 ║
╚═══════════════╩═══════════════╩══════════╝
Total keys: 0
Stability: 100.00%

Pay attention to the third column of the table. The values in each row of that column inform us how many keys (i.e pieces of data) each node holds. As we still have not inserted any data into the network, none of the existing nodes store any keys.

Adding data using the client script

To actually store some data in our network, we must first know how to communicate with it. For this, it is necessary that we know the address of some node in the network. In our example, we inserted all three nodes by hand, so we know the addresses for each of them.

Since we passed the port numbers as arguments when running nodes, the IP address defaults to the empty IP address, which is equivalent to localhost. The port number used for the first node was 9150.

Using these, we can now execute the client.py script, located in the main repository. We use the command python3 client.py localhost 9150. This gives us access to a simple interface, which allows for basic communication with the node. By typing in help, we get the following output:

Available commands:
>lookup [key]
>insert [key] [value]
>delete [key]
>leave

Remember that the Chord protocol describes a DHT (distributed hash table). As such, we store data in key-value pairs, similar to a regular hash table. Let's insert our first pair. We'd like to insert the string "Hello" as the key, with the string "World" as a value. To do this, we execute the insert Hello World command in the client interface.

As long as the network is running and the node address we gave is valid, we should see the output Successfully stored pair.

Observing the visualizer

Let's now turn our attention back to the visualizer script. Return to the terminal window where you ran the script, and you should notice some changes:

╔═══════════════╦═══════════════╦══════════╗
║   Successors  ║  Predecessors ║   Keys   ║
╠═══════════════╬═══════════════╬══════════╣
║  2503 -> 8230 ║ 15626 <- 8230 ║  2503: 1 ║
╠═══════════════╬═══════════════╬══════════╣
║ 8230 -> 15626 ║  8230 <- 2503 ║  8230: 0 ║
╠═══════════════╬═══════════════╬══════════╣
║ 15626 -> 2503 ║ 2503 <- 15626 ║ 15626: 0 ║
╚═══════════════╩═══════════════╩══════════╝
Total keys: 1
Stability: 100.00%

The visualizer informs us that a key has indeed been added to a node with ID 2503. You might think that this is the node we contacted using its address, but there is no guarantee that this is the case! In fact, contacting a node is equivalent to contacting the entire network: we add data to and read from the entire network, not just the singular node.

Adding more data

To make this clearer, let's add more data to the network. Similarly to before, execute the insert [key] [value] command in the client interface a few times. Following this, observe the visualizer output again:

╔═══════════════╦═══════════════╦══════════╗
║   Successors  ║  Predecessors ║   Keys   ║
╠═══════════════╬═══════════════╬══════════╣
║  2503 -> 8230 ║ 15626 <- 8230 ║  2503: 1 ║
╠═══════════════╬═══════════════╬══════════╣
║ 8230 -> 15626 ║  8230 <- 2503 ║  8230: 1 ║
╠═══════════════╬═══════════════╬══════════╣
║ 15626 -> 2503 ║ 2503 <- 15626 ║ 15626: 7 ║
╚═══════════════╩═══════════════╩══════════╝
Total keys: 9
Stability: 100.00%

Notice how not all of the keys have been stored in the same node and, instead, they've been spread to the three existing nodes. It might seem like too many have been given to the node with ID 15626, but the reason as to why that happens is connected to how the protocol works and our parameters. For more information on this, visit the Chord protocol discussion page.

Reading stored data

Of course, being able to add data is useless without being able to also retrieve it. As you might have noticed in the available commands before, we can also read any of the data we store in E-Chord. To make this even more interesting, however, let's try reading some of that data from a different node, instead of the one we contacted to store it. After all, that's how we'll know the network isn't just cheating and storing everything in one node!

Run the client script again, this time with the address of another node. In our example, we used port 9152 for the third node, so let's contact that one, using the command python3 client.py localhost 9152.

We'll now try to read the first piece of data we stored. The key was Hello, and the expected value stored with it is World. Use the command lookup Hello in the client interface. You should notice the below output:

>lookup Hello
Key hello has value: world

As you can see, the network is able to locate the value corresponding to that key, even though we inserted it at a different node. In fact, the node we contact is only a "representative" of the network. There is no guarantee that anything we tell it to store will be stored at that node, nor that anything we read is necessarily stored at that node.

Don't worry about the fact that World is all lowercase. This isn't an issue with the network, but rather the client itself, which lowers the input we provide. In a real execution, this would not be an issue.

Play around with storing and reading data! Even though the client script only provides limited capabilities, you can still use the visualizer to see that anything you store is placed at a node determined by the network and is readable from every other node.

Deleting data

Of course, hash tables also provide the user with the ability to delete existing data. E-Chord is no different, in that any data previously stored can be deleted. In this case, using the client interface, we can try deleting the first key we inserted using the delete Hello command.

>delete Hello
Successfully deleted key.

The output informs us that the previously inserted key was indeed deleted. Moving over to the visualizer tab, we can see that one key is indeed missing (we had 9 before):

╔═══════════════╦═══════════════╦══════════╗
║   Successors  ║  Predecessors ║   Keys   ║
╠═══════════════╬═══════════════╬══════════╣
║  2503 -> 8230 ║ 15626 <- 8230 ║  2503: 0 ║
╠═══════════════╬═══════════════╬══════════╣
║ 8230 -> 15626 ║  8230 <- 2503 ║  8230: 1 ║
╠═══════════════╬═══════════════╬══════════╣
║ 15626 -> 2503 ║ 2503 <- 15626 ║ 15626: 7 ║
╚═══════════════╩═══════════════╩══════════╝
Total keys: 8
Stability: 100.00%

Finally, looking up the key confirms that it no longer exists in the network.

>lookup Hello
Key not found.

Conclusion

You have now successfully used the client interface to insert, read and delete data from an E-Chord network. Later on, we will also dig deeper into the underlying mechanisms for communicating with the network, allowing for more freedom in how we store and retrieve data.