Challenge #1: Echo

I recently came across this set of distributed systems challenges called 'Gossip Glomers' by the guys at fly.io. The page looked great and I thought I'd give these challenges a shot.

The first challenge is straightforward. The description page holds your hand along the way.

We'll start by initialising our Go module and creating our main.go file.

$ go mod init github.com/nchengyeeshen/echo
$ touch main.go

In our main.go file, we'll have these lines to start with.

package main

import (
    "encoding/json"
    "log"

    maelstrom "github.com/jepsen-io/maelstrom/demo/go"
)

func main() {
    n := maelstrom.NewNode()
}

So far so good. Now the instructions tell us to write a handler for an "echo" message, so let's do that.

n.Handle("echo", func(msg maelstrom.Message) error {
    var body struct {
        Type string `json:"type"`
        Echo string `json:"echo"`
    }
    if err := json.Unmarshal(msg.Body, &body); err != nil {
        return err
    }

    body.Type = "echo_ok"
    return n.Reply(msg, body)
})

Where I differ from the instructions is in the type for body. The instructions use a loosely-typed map[string]any, whereas I've chosen to use a stricter typed struct.

Now we have to run our node to get somewhere. Putting all that code together, we get something along the lines of this.

package main

import (
    "encoding/json"
    "log"

    maelstrom "github.com/jepsen-io/maelstrom/demo/go"
)

func main() {
    n := maelstrom.NewNode()

    n.Handle("echo", func(msg maelstrom.Message) error {
        var body struct {
            Type string `json:"type"`
            Echo string `json:"echo"`
        }
        if err := json.Unmarshal(msg.Body, &body); err != nil {
            return err
        }

        body.Type = "echo_ok"
        return n.Reply(msg, body)
    })

    if err := n.Run(); err != nil {
        log.Fatal(err)
    }
}

After installing the maelstrom binary, we can compile our Go binary and run it.

I chose to write a one-liner that compiles the binary and run it using maelstrom.

$ go build -o echo . && maelstrom test -w echo --bin ./echo --node-count 1 --time-limit 10

After all the tests, it looks like we're all good!

Everything looks good! ヽ(‘ー`)ノ

This first challenge is introductory and probably doesn't merit its own blog post, but I added it for completeness. See y'all in the next one.