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
|
// Bye tells p that its predecessor or successor is leaving
|
||||||
// and had the given successor list.
|
// and had the given successor list.
|
||||||
Bye(ctx context.Context, p, n Peer, succ []Peer) error
|
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 asks s for a saved value.
|
||||||
Get(ctx context.Context, s Peer, id ID) (string, error)
|
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
|
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("POST /pred", n.notify)
|
||||||
m.HandleFunc("GET /neighbors", n.neighbors)
|
m.HandleFunc("GET /neighbors", n.neighbors)
|
||||||
m.HandleFunc("POST /bye", n.bye)
|
m.HandleFunc("POST /bye", n.bye)
|
||||||
|
m.HandleFunc("DELETE /", n.saybye)
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,6 +171,14 @@ func (n *Node) bye(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
n.self.Leave(p, s)
|
n.self.Leave(p, s)
|
||||||
w.WriteHeader(http.StatusNoContent)
|
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()
|
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)
|
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 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 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 cliGet(ctx context.Context, cmd *cli.Command) error { return errors.New("not implemented") }
|
||||||
|
@ -16,4 +16,8 @@ THIRD=$!
|
|||||||
|
|
||||||
sleep 5
|
sleep 5
|
||||||
# Each node logs its predecessor and successors. At this point, we see the ring.
|
# Each node logs its predecessor and successors. At this point, we see the ring.
|
||||||
|
|
||||||
|
# Test leaving.
|
||||||
|
./chord-node leave -n 127.0.0.1:3000
|
||||||
|
|
||||||
kill $FIRST $SECOND $THIRD
|
kill $FIRST $SECOND $THIRD
|
||||||
|
Loading…
Reference in New Issue
Block a user