implement leave command
This commit is contained in:
parent
73068a9c1f
commit
bd2085ee87
@ -18,6 +18,8 @@ type Client interface {
|
||||
// Bye tells p that its predecessor or successor is leaving
|
||||
// and had the given successor list.
|
||||
Bye(ctx context.Context, p, n Peer, succ []Peer) error
|
||||
// SayBye tells p to leave the network.
|
||||
SayBye(ctx context.Context, p Peer) error
|
||||
|
||||
// Get asks s for a saved value.
|
||||
Get(ctx context.Context, s Peer, id ID) (string, error)
|
||||
|
@ -203,3 +203,28 @@ func (cl *Client) Bye(ctx context.Context, p, n chord.Peer, succ []chord.Peer) e
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SayBye tells p to leave the network.
|
||||
func (cl *Client) SayBye(ctx context.Context, p chord.Peer) error {
|
||||
_, addr := p.Values()
|
||||
if !addr.IsValid() {
|
||||
return errors.New("SayBye with invalid peer")
|
||||
}
|
||||
url := url.URL{
|
||||
Scheme: "http",
|
||||
Host: addr.String(),
|
||||
Path: path.Join("/", cl.APIBase),
|
||||
}
|
||||
req, err := http.NewRequestWithContext(ctx, "DELETE", url.String(), nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
resp, err := cl.HTTP.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return errors.New(resp.Status)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -57,6 +57,7 @@ func (n *Node) Router() http.Handler {
|
||||
m.HandleFunc("POST /pred", n.notify)
|
||||
m.HandleFunc("GET /neighbors", n.neighbors)
|
||||
m.HandleFunc("POST /bye", n.bye)
|
||||
m.HandleFunc("DELETE /", n.saybye)
|
||||
return m
|
||||
}
|
||||
|
||||
@ -170,6 +171,14 @@ func (n *Node) bye(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
n.self.Leave(p, s)
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
// Close the listener so that the server will shut down.
|
||||
}
|
||||
|
||||
func (n *Node) saybye(w http.ResponseWriter, r *http.Request) {
|
||||
err := chord.Leave(r.Context(), n.client, n.self)
|
||||
if err != nil {
|
||||
writeError(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
n.l.Close()
|
||||
}
|
||||
|
12
main.go
12
main.go
@ -194,7 +194,17 @@ func cliJoin(ctx context.Context, cmd *cli.Command) error {
|
||||
return srv.Shutdown(ctx)
|
||||
}
|
||||
|
||||
func cliLeave(ctx context.Context, cmd *cli.Command) error { return errors.New("not implemented") }
|
||||
func cliLeave(ctx context.Context, cmd *cli.Command) error {
|
||||
// I'm not really clear on why this command takes a startup IP and port.
|
||||
// All we need is the node to tell to leave.
|
||||
n, err := netip.ParseAddrPort(cmd.String("n"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cl := &httpnode.Client{HTTP: http.Client{Timeout: 5 * time.Second}}
|
||||
return cl.SayBye(ctx, chord.Address(n))
|
||||
}
|
||||
|
||||
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") }
|
||||
|
Loading…
Reference in New Issue
Block a user