diff --git a/chord/httpnode/client.go b/chord/httpnode/client.go index 39d9188..2267857 100644 --- a/chord/httpnode/client.go +++ b/chord/httpnode/client.go @@ -76,5 +76,34 @@ func (cl *Client) Notify(ctx context.Context, n *chord.Node, s chord.Peer) error // Neighbors requests a peer's beliefs about its own neighbors. func (cl *Client) Neighbors(ctx context.Context, p chord.Peer) (pred chord.Peer, succ []chord.Peer, err error) { - panic("not implemented") // TODO: Implement + _, addr := p.Values() + if !addr.IsValid() { + return chord.Peer{}, nil, errors.New("Neighbors with invalid peer") + } + url := url.URL{ + Scheme: "http", + Host: addr.String(), + Path: path.Join("/", cl.APIBase, "neighbors"), + } + req, err := http.NewRequestWithContext(ctx, "GET", url.String(), nil) + if err != nil { + return chord.Peer{}, nil, err + } + resp, err := cl.HTTP.Do(req) + if err != nil { + return chord.Peer{}, nil, err + } + n, err := readResponse[neighbors](resp) + if err != nil { + return chord.Peer{}, nil, fmt.Errorf("%w (%s)", err, resp.Status) + } + pred = chord.Address(n.Pred) + succ = make([]chord.Peer, 0, len(n.Succ)) + for _, addr := range n.Succ { + p := chord.Address(addr) + if p.IsValid() { + succ = append(succ, p) + } + } + return pred, succ, nil }