Skip to content

Commit

Permalink
Code reformat
Browse files Browse the repository at this point in the history
  • Loading branch information
matteocarnelos committed Oct 21, 2021
1 parent d592b2f commit 0d6bdef
Show file tree
Hide file tree
Showing 13 changed files with 261 additions and 221 deletions.
11 changes: 4 additions & 7 deletions .github/workflows/docker-cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,18 @@ jobs:
docker:
runs-on: ubuntu-latest
steps:
-
name: Login to GitHub Container Registry
uses: docker/login-action@v1
- name: Login to GitHub Container Registry
uses: docker/login-action@v1
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
-
name: Create Image Tag
- name: Create Image Tag
run: |
IMAGE_TAG=${GITHUB_REF##*/}
if [ $IMAGE_TAG = "main" ]; then IMAGE_TAG="latest"; fi
echo "IMAGE_TAG=$IMAGE_TAG" >> $GITHUB_ENV
-
name: Build and Publish Docker Image
- name: Build and Publish Docker Image
uses: docker/build-push-action@v2
with:
push: true
Expand Down
9 changes: 3 additions & 6 deletions .github/workflows/pandoc-cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,16 @@ jobs:
pandoc:
runs-on: ubuntu-latest
steps:
-
name: Checkout Repository
- name: Checkout Repository
uses: actions/checkout@v2
-
name: Create PDF Report
- name: Create PDF Report
uses: docker://pandoc/latex
with:
args: >-
-V geometry:a4paper,margin=2cm
--output=Kadlab-Report.pdf
docs/kadlab-report.md
-
name: Upload Document
- name: Upload Document
uses: actions/upload-artifact@v2
with:
path: Kadlab-Report.pdf
Expand Down
29 changes: 15 additions & 14 deletions .run/Compose Deployment.run.xml
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Compose Deployment" type="docker-deploy" factoryName="docker-compose.yml" server-name="Docker">
<deployment type="docker-compose.yml">
<settings>
<option name="composeProjectName" value="kadlab" />
<option name="envFilePath" value="" />
<option name="removeImagesOnComposeDown" value="ALL" />
<option name="removeVolumesOnComposeDown" value="true" />
<option name="commandLineOptions" value="--build" />
<option name="sourceFilePath" value="docker-compose.yml" />
</settings>
</deployment>
<method v="2" />
</configuration>
</component>
<configuration default="false" name="Compose Deployment" type="docker-deploy" factoryName="docker-compose.yml"
server-name="Docker">
<deployment type="docker-compose.yml">
<settings>
<option name="composeProjectName" value="kadlab"/>
<option name="envFilePath" value=""/>
<option name="removeImagesOnComposeDown" value="ALL"/>
<option name="removeVolumesOnComposeDown" value="true"/>
<option name="commandLineOptions" value="--build"/>
<option name="sourceFilePath" value="docker-compose.yml"/>
</settings>
</deployment>
<method v="2"/>
</configuration>
</component>
22 changes: 11 additions & 11 deletions .run/Go Test.run.xml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Go Test" type="GoTestRunConfiguration" factoryName="Go Test">
<module name="kadlab" />
<working_directory value="$PROJECT_DIR$" />
<go_parameters value="-i" />
<kind value="DIRECTORY" />
<directory value="$PROJECT_DIR$" />
<filePath value="$PROJECT_DIR$" />
<framework value="gotest" />
<method v="2" />
</configuration>
</component>
<configuration default="false" name="Go Test" type="GoTestRunConfiguration" factoryName="Go Test">
<module name="kadlab"/>
<working_directory value="$PROJECT_DIR$"/>
<go_parameters value="-i"/>
<kind value="DIRECTORY"/>
<directory value="$PROJECT_DIR$"/>
<filePath value="$PROJECT_DIR$"/>
<framework value="gotest"/>
<method v="2"/>
</configuration>
</component>
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
# Kademlia Laboratory
Go implementation of the Kademlia distributed hash table for the "Mobile and Distributed Computing Systems" course's laboratory at Luleå University of Technology.

Go implementation of the Kademlia distributed hash table for the "Mobile and Distributed Computing Systems" course's
laboratory at Luleå University of Technology.
312 changes: 171 additions & 141 deletions docs/kadlab-report.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion kademlia/bucket.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func (bucket *bucket) AddContact(contact Contact) bool {
return false
}

// GetContactAndCalcDistance returns an array of Contacts where
// GetContactAndCalcDistance returns an array of Contacts where
// the distance has already been calculated
func (bucket *bucket) GetContactAndCalcDistance(target *KademliaID) []Contact {
var contacts []Contact
Expand Down
4 changes: 2 additions & 2 deletions kademlia/contact.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func NewContact(id *KademliaID, address string) Contact {
return Contact{id, address, nil}
}

// CalcDistance calculates the distance to the target and
// CalcDistance calculates the distance to the target and
// fills the contacts distance field
func (contact *Contact) CalcDistance(target *KademliaID) {
contact.distance = contact.ID.CalcDistance(target)
Expand Down Expand Up @@ -69,7 +69,7 @@ func (candidates *ContactCandidates) Swap(i, j int) {
candidates.contacts[i], candidates.contacts[j] = candidates.contacts[j], candidates.contacts[i]
}

// Less returns true if the Contact at index i is smaller than
// Less returns true if the Contact at index i is smaller than
// the Contact at index j
func (candidates *ContactCandidates) Less(i, j int) bool {
return candidates.contacts[i].Less(&candidates.contacts[j])
Expand Down
48 changes: 29 additions & 19 deletions kademlia/kademlia.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ import (
"time"
)

const concurrencyParam = 3 // Alpha definition
const replicationParam = 20 // K definition
const republishDelayHr = 12 // Delay for the republishing routines
const concurrencyParam = 3 // Alpha definition
const replicationParam = 20 // K definition
const republishDelayHr = 12 // Delay for the republishing routines
const expirationDelayHr = 24 // Delay for the expiration routines

type Kademlia struct {
Expand All @@ -31,7 +31,7 @@ func NewKademlia(me Contact) *Kademlia {
forgetTable: sync.Map{},
Net: Network{
RPC: sync.Map{},
RT: NewRoutingTable(me),
RT: NewRoutingTable(me),
},
}
}
Expand Down Expand Up @@ -68,17 +68,17 @@ func (k *Kademlia) handleRPC(cmd string, args []string) string {
key := hex.EncodeToString(h.Sum(nil))
// If the value is loaded then it is a refresh STORE
if ch, ok := k.refreshTable.LoadOrStore(key, make(chan interface{})); ok {
ch.(chan interface{}) <-nil // Notify the refreshing routine
ch.(chan interface{}) <- nil // Notify the refreshing routine
} else { // If the value is not stored
k.hashTable.Store(key, args[0]) // Store the value
k.hashTable.Store(key, args[0]) // Store the value
ch, _ := k.refreshTable.Load(key) // Obtain a channel for the refreshing routine
go func() { // Create an anonymous parallel function
go func() { // Create an anonymous parallel function
for {
select {
case <-ch.(chan interface{}): // If it receives a "notification" it restarts the timeout
case <-time.After(expirationDelayHr * time.Hour): // If the timeout is completed
k.refreshTable.Delete(key) // The channel is deleted
k.hashTable.Delete(key) // The data is deleted
k.hashTable.Delete(key) // The data is deleted
return
}
}
Expand All @@ -89,8 +89,8 @@ func (k *Kademlia) handleRPC(cmd string, args []string) string {
key := args[0]
if data, ok := k.hashTable.Load(key); ok { // If the data is present in the hash table
ch, _ := k.refreshTable.Load(key) // Obtain the channel associated with that value
ch.(chan interface{}) <-nil // Refresh the timeout
return data.(string) // Return the value
ch.(chan interface{}) <- nil // Refresh the timeout
return data.(string) // Return the value
}
fallthrough // If not execute the following case clause
case "FIND_NODE":
Expand All @@ -116,7 +116,9 @@ func (k *Kademlia) updateStorage(contact Contact) {
if contact.Less(&k.Net.RT.me) { // If the contact is closer
// For each of the k-closest contacts to the key
for _, c := range k.Net.RT.FindClosestContacts(key, replicationParam) {
if c.ID.Equals(contact.ID) { continue } // If it is the same contact, continue to the next
if c.ID.Equals(contact.ID) {
continue
} // If it is the same contact, continue to the next
// Calculate its distance to the key
c.CalcDistance(key)
if c.Less(&k.Net.RT.me) { // If its distance is closer to the key than me
Expand All @@ -143,12 +145,16 @@ func (k *Kademlia) LookupContact(target *KademliaID) []Contact {
}
for {
var ids []KademliaID
closest.Sort() // Sort the contacts by their distance
closest.Sort() // Sort the contacts by their distance
for _, c := range closest.GetContacts(replicationParam) { // For each contact of the k-closest
if queried[c.Address] { continue } // If it has already been queried, continue to the next
if queried[c.Address] {
continue
} // If it has already been queried, continue to the next
ids = append(ids, *k.Net.SendFindContactMessage(target, &c)) // Send a FIND_NODE RPC
queried[c.Address] = true
if len(ids) == concurrencyParam { break } // If it has reached alpha contacts then finish
if len(ids) == concurrencyParam {
break
} // If it has reached alpha contacts then finish
}
if len(ids) == 0 { // If all contacts were queried
return closest.GetContacts(replicationParam)
Expand Down Expand Up @@ -180,7 +186,7 @@ func (k *Kademlia) LookupData(hash string) (interface{}, bool) {
if data, ok := k.hashTable.Load(hash); ok { // If the data is stored
// Obtain the channel associated with the refreshing routine
ch, _ := k.refreshTable.Load(hash)
ch.(chan interface{}) <-nil // Refresh the data
ch.(chan interface{}) <- nil // Refresh the data
return data.(string), true
}
target := NewKademliaID(hash)
Expand All @@ -194,12 +200,16 @@ func (k *Kademlia) LookupData(hash string) (interface{}, bool) {
}
for {
var ids []KademliaID
closest.Sort() // Sort the contacts by their distance
closest.Sort() // Sort the contacts by their distance
for _, c := range closest.GetContacts(replicationParam) { // For each contact of the k-closest
if queried[c.Address] { continue } // If it has already been queried, continue to the next
if queried[c.Address] {
continue
} // If it has already been queried, continue to the next
ids = append(ids, *k.Net.SendFindDataMessage(target.String(), &c)) // Send a FIND_VALUE RPC
queried[c.Address] = true
if len(ids) == concurrencyParam { break } // If it has reached alpha contacts then finish
if len(ids) == concurrencyParam {
break
} // If it has reached alpha contacts then finish
}
if len(ids) == 0 { // If all contacts were queried
return closest.GetContacts(replicationParam), false
Expand All @@ -210,7 +220,7 @@ func (k *Kademlia) LookupData(hash string) (interface{}, bool) {
case resp := <-ch.(chan []string): // If the node responds
for _, t := range resp { // For each string of the message
triple := strings.Split(t, ",") // Split it by commas
if len(triple) == 1 { // If the message contains only one string
if len(triple) == 1 { // If the message contains only one string
// We return the data
return triple[0], true
}
Expand Down
2 changes: 1 addition & 1 deletion kademlia/kademliaid.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func (kademliaID KademliaID) Equals(otherKademliaID *KademliaID) bool {
return true
}

// CalcDistance returns a new instance of a KademliaID that is built
// CalcDistance returns a new instance of a KademliaID that is built
// through a bitwise XOR operation betweeen kademliaID and target
func (kademliaID KademliaID) CalcDistance(target *KademliaID) *KademliaID {
result := KademliaID{}
Expand Down
24 changes: 12 additions & 12 deletions kademlia/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ import (
"time"
)

const pingTimeoutSec = 3 // Timeout for the PING RPC
const findTimeoutSec = 20 // Timeout for the FIND_NODE and FIND_VALUE RPCs
const pingTimeoutSec = 3 // Timeout for the PING RPC
const findTimeoutSec = 20 // Timeout for the FIND_NODE and FIND_VALUE RPCs
const storeTimeoutSec = 10 // Timeout for the STORE RPC
const bufferSize = 8192

type Network struct {
RPC sync.Map // Channel map for communicating with the service layer
RT *RoutingTable
ListenIP net.IP
RPC sync.Map // Channel map for communicating with the service layer
RT *RoutingTable
ListenIP net.IP
ListenPort int
}

Expand All @@ -36,8 +36,8 @@ func (n *Network) listen(handler *Kademlia) {
size, addr, _ := conn.ReadFromUDP(buf) // Listen for incoming messages
h := sha1.New()
h.Write(addr.IP.To4())
msg := string(buf[:size]) // Obtain the plain text string message
cmdLine := strings.Fields(msg) // Divide its fields
msg := string(buf[:size]) // Obtain the plain text string message
cmdLine := strings.Fields(msg) // Divide its fields
id := NewKademliaID(cmdLine[0]) // ID of the RPC
fmt.Printf("%s -> %s\n", addr.IP, msg[41:])
// Create a new contact from the sender's address
Expand All @@ -47,8 +47,8 @@ func (n *Network) listen(handler *Kademlia) {
handler.updateStorage(contact)
}
if ch, ok := n.RPC.Load(*id); ok { // If we receive a response
ch.(chan []string) <-cmdLine[1:] // Send it to the service layer
close(ch.(chan []string)) // Close the channel
ch.(chan []string) <- cmdLine[1:] // Send it to the service layer
close(ch.(chan []string)) // Close the channel
continue
}
// If it's not a response, it's an RPC
Expand All @@ -62,7 +62,7 @@ func (n *Network) listen(handler *Kademlia) {
addr.Port = n.ListenPort
conn, _ := net.DialUDP("udp", nil, addr)
msg = fmt.Sprintf("%s %s", id, resp) // Create the message
fmt.Fprintf(conn, msg) // Send the response back
fmt.Fprintf(conn, msg) // Send the response back
fmt.Printf("%s -> %s\n", msg[41:], addr.IP)
conn.Close()
}
Expand All @@ -72,7 +72,7 @@ func (n *Network) listen(handler *Kademlia) {
// in the parameters
func (n *Network) sendRPC(recipient *Contact, request string) *KademliaID {
addr := net.UDPAddr{
IP: net.ParseIP(recipient.Address),
IP: net.ParseIP(recipient.Address),
Port: n.ListenPort,
}
id := NewRandomKademliaID() // Generate an ID for the RPC
Expand Down Expand Up @@ -105,7 +105,7 @@ func (n *Network) updateRoutingTable(contact Contact) bool {
return false
case <-time.After(pingTimeoutSec * time.Second): // If the LeastRecentlySeen node does not respond
bucket.list.Remove(bucket.list.Back()) // Remove it from the k-bucket
bucket.list.PushFront(contact) // Add the new contact
bucket.list.PushFront(contact) // Add the new contact
return true
}
}
Expand Down
1 change: 0 additions & 1 deletion kademlia/routingtable.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package kademlia

const bucketSize = 20


// RoutingTable definition
// keeps a reference contact of me and an array of buckets
type RoutingTable struct {
Expand Down
14 changes: 9 additions & 5 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func handleRequest(w http.ResponseWriter, r *http.Request) {
break
}
hash := store(string(body))
w.Header().Set("Location", "/objects/" + hash)
w.Header().Set("Location", "/objects/"+hash)
code = http.StatusCreated
msg = "Object stored!"
}
Expand Down Expand Up @@ -112,12 +112,12 @@ func main() {

if !isBN { // If it is not the Bootstrap Node
fmt.Println("Joining network...")
BNIp := net.IP{ ip[0], ip[1], ip[2], BNHost } // Define the Bootstrap Node's IP
BNIp := net.IP{ip[0], ip[1], ip[2], BNHost} // Define the Bootstrap Node's IP
h = sha1.New()
h.Write(BNIp)
BNId := kademlia.NewKademliaID(hex.EncodeToString(h.Sum(nil)))
kdm.Net.RT.AddContact(kademlia.NewContact(BNId, BNIp.String())) // Add the BN to the routing table
kdm.LookupContact(me.ID) // Initiate a lookup
kdm.LookupContact(me.ID) // Initiate a lookup
fmt.Println("Network joined!")
fmt.Println()
}
Expand All @@ -133,8 +133,12 @@ func main() {
cmdLine, _ := r.Read()
var cmd string
var args []string
if len(cmdLine) > 0 { cmd = cmdLine[0] }
if len(cmdLine) > 1 { args = cmdLine[1:] }
if len(cmdLine) > 0 {
cmd = cmdLine[0]
}
if len(cmdLine) > 1 {
args = cmdLine[1:]
}
switch cmd {
case "put":
if len(args) != 1 {
Expand Down

0 comments on commit 0d6bdef

Please sign in to comment.