chord/main.go
2025-03-06 10:14:58 -05:00

128 lines
2.6 KiB
Go

package main
import (
"context"
"errors"
"fmt"
"os"
"os/signal"
"github.com/urfave/cli/v3"
)
var app = cli.Command{
Name: "chord",
Usage: "Distributed hash table using the Chord protocol",
Commands: []*cli.Command{
{
Name: "join",
Aliases: []string{"init", "initialize"},
Usage: "Join or initialize a Chord network.",
Flags: []cli.Flag{
flagIP,
flagPort,
&cli.StringFlag{
Name: "c",
Usage: "Address of an existing node to join.",
},
},
Action: cliJoin,
},
{
Name: "leave",
Usage: "Instruct a node to leave the network.",
Flags: []cli.Flag{
flagIP,
flagPort,
&cli.StringFlag{
Name: "n",
Usage: "Node to leave.",
Required: true,
},
},
Action: cliLeave,
},
{
Name: "lookup",
Usage: "Find the node responsible for a key.",
Flags: []cli.Flag{
flagKey,
flagNode,
flagLocal,
},
Action: cliLookup,
},
{
Name: "put",
Aliases: []string{"store", "set"},
Usage: "Set a value in the network.",
Flags: []cli.Flag{
flagKey,
&cli.StringFlag{
Name: "v",
Usage: "Value to set.",
Required: true,
},
flagNode,
flagLocal,
},
Action: cliPut,
},
{
Name: "get",
Aliases: []string{"load"},
Usage: "Get a value in the network.",
Flags: []cli.Flag{
flagKey,
flagNode,
flagLocal,
},
Action: cliGet,
},
},
}
var (
flagIP = &cli.StringFlag{
Name: "ip",
Usage: "IP to bind. May include port.",
Value: "127.0.0.1:3000",
}
flagPort = &cli.UintFlag{
Name: "p",
Usage: "Port to bind. Overrides port in -ip if given.",
}
flagNode = &cli.StringFlag{
Name: "n",
Usage: "Address of any node in the network.",
Required: true,
}
flagKey = &cli.StringFlag{
Name: "k",
Usage: "Key to operate on.",
Required: true,
}
flagLocal = &cli.BoolFlag{
Name: "l",
Usage: "Stop if the key is not local to the node.",
}
)
func cliJoin(ctx context.Context, cmd *cli.Command) error { return errors.New("not implemented") }
func cliLeave(ctx context.Context, cmd *cli.Command) error { return errors.New("not implemented") }
func cliLookup(ctx context.Context, cmd *cli.Command) error { return errors.New("not implemented") }
func cliPut(ctx context.Context, cmd *cli.Command) error { return errors.New("not implemented") }
func cliGet(ctx context.Context, cmd *cli.Command) error { return errors.New("not implemented") }
func main() {
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
go func() {
<-ctx.Done()
stop()
}()
if err := app.Run(ctx, os.Args); err != nil {
fmt.Fprintln(os.Stderr, err)
}
}