Skip to content

Commit

Permalink
Return same not-found response from dh and non-dh clients (#124)
Browse files Browse the repository at this point in the history
The Client and DHashClient need to return the same response when no results are found. Return empty response for not found to preserve compatability with clients that expect non-nil response.

Fixes #53
  • Loading branch information
gammazero authored Sep 24, 2023
1 parent 3bc33f6 commit 93ca455
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 34 deletions.
47 changes: 22 additions & 25 deletions find/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,35 @@ func New(baseURL string, options ...Option) (*Client, error) {
}, nil
}

// Find looks up content entries by multihash.
// Find looks up content entries by multihash. If no results are found then an
// empty response without error is returned.
func (c *Client) Find(ctx context.Context, m multihash.Multihash) (*model.FindResponse, error) {
u := c.findURL.JoinPath(m.B58String())
req, err := http.NewRequestWithContext(ctx, http.MethodGet, u.String(), nil)
if err != nil {
return nil, err
}

return c.sendRequest(req)
req.Header.Set("Content-Type", "application/json")
resp, err := c.c.Do(req)
if err != nil {
return nil, err
}
// Handle failed requests
if resp.StatusCode != http.StatusOK {
if resp.StatusCode == http.StatusNotFound {
return &model.FindResponse{}, nil
}
return nil, fmt.Errorf("find query failed: %v", http.StatusText(resp.StatusCode))
}

defer resp.Body.Close()
b, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}

return model.UnmarshalFindResponse(b)
}

func (c *Client) ListProviders(ctx context.Context) ([]*model.ProviderInfo, error) {
Expand Down Expand Up @@ -154,26 +174,3 @@ func (c *Client) GetStats(ctx context.Context) (*model.Stats, error) {

return model.UnmarshalStats(body)
}

func (c *Client) sendRequest(req *http.Request) (*model.FindResponse, error) {
req.Header.Set("Content-Type", "application/json")
resp, err := c.c.Do(req)
if err != nil {
return nil, err
}
// Handle failed requests
if resp.StatusCode != http.StatusOK {
if resp.StatusCode == http.StatusNotFound {
return &model.FindResponse{}, nil
}
return nil, fmt.Errorf("batch find query failed: %v", http.StatusText(resp.StatusCode))
}

defer resp.Body.Close()
b, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}

return model.UnmarshalFindResponse(b)
}
20 changes: 14 additions & 6 deletions find/client/dhash_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ func (c *DHashClient) PCache() *pcache.ProviderCache {
}

// Find launches FindAsync in a separate go routine and assembles the result
// into FindResponse as if it was a synchronous invocation.
// into FindResponse as if it was a synchronous invocation. If no results are
// found then an empty response without error is returned.
func (c *DHashClient) Find(ctx context.Context, mh multihash.Multihash) (*model.FindResponse, error) {
resChan := make(chan model.ProviderResult)
errChan := make(chan error, 1)
Expand All @@ -107,18 +108,25 @@ func (c *DHashClient) Find(ctx context.Context, mh multihash.Multihash) (*model.
errChan <- c.FindAsync(ctx, mh, resChan)
}()

mhr := model.MultihashResult{
Multihash: mh,
}
var providerResults []model.ProviderResult
for pr := range resChan {
mhr.ProviderResults = append(mhr.ProviderResults, pr)
providerResults = append(providerResults, pr)
}
err := <-errChan
if err != nil {
return nil, err
}
if len(providerResults) == 0 {
return &model.FindResponse{}, nil
}

return &model.FindResponse{
MultihashResults: []model.MultihashResult{mhr},
MultihashResults: []model.MultihashResult{
{
Multihash: mh,
ProviderResults: providerResults,
},
},
}, nil
}

Expand Down
13 changes: 10 additions & 3 deletions find/client/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ import (

// Finder is the interface implemented by all find clients.
type Finder interface {
// Find queries for provider content records for a single multihash.
// Find queries for provider content records for a single multihash. If no
// results are found then an empty response without error is returned.
Find(context.Context, multihash.Multihash) (*model.FindResponse, error)
}

// FindBatch is a convenience function to lookup results for multiple
// multihashes. This works with either the Client or DHashClient. If no results
// are found, then an error is not returned and there are no results in the
// response.
// are found then an empty response without error is returned.
func FindBatch(ctx context.Context, finder Finder, mhs []multihash.Multihash) (*model.FindResponse, error) {
var resp *model.FindResponse
for i := range mhs {
Expand All @@ -31,11 +31,18 @@ func FindBatch(ctx context.Context, finder Finder, mhs []multihash.Multihash) (*
}
return nil, err
}
if r == nil || len(r.MultihashResults) == 0 {
// multihash not found
continue
}
if resp == nil {
resp = r
} else {
resp.MultihashResults = append(resp.MultihashResults, r.MultihashResults...)
}
}
if resp == nil {
resp = &model.FindResponse{}
}
return resp, nil
}

0 comments on commit 93ca455

Please sign in to comment.