Skip to content

Commit

Permalink
Add tracker healthcheck client
Browse files Browse the repository at this point in the history
  • Loading branch information
Anton-Kalpakchiev committed Nov 13, 2024
1 parent ab090d4 commit b5627eb
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 2 deletions.
21 changes: 20 additions & 1 deletion tracker/announceclient/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
Expand All @@ -23,6 +23,7 @@ import (
"time"

"github.com/uber/kraken/core"
"github.com/uber/kraken/lib/backend"
"github.com/uber/kraken/lib/hashring"
"github.com/uber/kraken/utils/httputil"
)
Expand Down Expand Up @@ -58,6 +59,8 @@ type Response struct {

// Client defines a client for announcing and getting peers.
type Client interface {
// CheckHealth calls a tracker's health endpoint.
CheckHealth() error
Announce(
d core.Digest,
h core.InfoHash,
Expand Down Expand Up @@ -89,6 +92,18 @@ func getEndpoint(version int, addr string, h core.InfoHash) (method, url string)
return "POST", fmt.Sprintf("http://%s/announce/%s", addr, h.String())
}

func (c *client) CheckHealth() error {
addr := c.ring.Locations(backend.ReadinessCheckDigest)[0]
_, err := httputil.Get(
fmt.Sprintf("http://%s/health", addr),
httputil.SendTimeout(2*time.Second),
httputil.SendTLS(c.tls))
if err != nil {
return fmt.Errorf("tracker not ready: %v", err)
}
return nil
}

// Announce announces the torrent identified by (d, h) with the number of
// downloaded bytes. Returns a list of all other peers announcing for said torrent,
// sorted by priority, and the interval for the next announce.
Expand Down Expand Up @@ -142,6 +157,10 @@ func Disabled() Client {
return DisabledClient{}
}

func (c DisabledClient) CheckHealth() error {
return nil
}

// Announce always returns error.
func (c DisabledClient) Announce(
d core.Digest, h core.InfoHash, complete bool, version int) ([]*core.PeerInfo, time.Duration, error) {
Expand Down
47 changes: 46 additions & 1 deletion tracker/trackerserver/announce_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
Expand All @@ -16,6 +16,7 @@ package trackerserver
import (
"errors"
"fmt"
"regexp"
"testing"
"time"

Expand All @@ -33,6 +34,50 @@ func newAnnounceClient(pctx core.PeerContext, addr string) announceclient.Client
return announceclient.New(pctx, hashring.NoopPassiveRing(hostlist.Fixture(addr)), nil)
}

func TestCheckHealth(t *testing.T) {
for _, tc := range []struct {
name string
serverIsUp bool
expectedErrMsgRegex string
}{
{
name: "success",
serverIsUp: true,
expectedErrMsgRegex: "",
},
{
name: "failure",
serverIsUp: false,
expectedErrMsgRegex: `tracker not ready: network error: Get "http://127\.0\.0\.1:\d+/health": dial tcp 127\.0\.0\.1:\d+: connect: connection refused`,
},
} {
t.Run(tc.name, func(t *testing.T) {
require := require.New(t)

mocks, cleanup := newServerMocks(t, Config{})
defer cleanup()

addr, stop := testutil.StartServer(mocks.handler())
if tc.serverIsUp {
defer stop()
} else {
stop()
}

pctx := core.PeerContextFixture()
client := newAnnounceClient(pctx, addr)

err := client.CheckHealth()
if tc.expectedErrMsgRegex == "" {
require.NoError(err)
} else {
r, _ := regexp.Compile(tc.expectedErrMsgRegex)
require.True(r.MatchString(err.Error()))
}
})
}
}

func TestAnnounceSinglePeerResponse(t *testing.T) {
for _, version := range []int{announceclient.V1, announceclient.V2} {
t.Run(fmt.Sprintf("V%d", version), func(t *testing.T) {
Expand Down

0 comments on commit b5627eb

Please sign in to comment.