Skip to content

Added context to Check method of Checker interface #29

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions checker.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
package health

import (
"context"
"sync"
)

// Checker is a interface used to provide an indication of application health.
type Checker interface {
Check() Health
Check(ctx context.Context) Health
}

// CheckerFunc is an adapter to allow the use of
// ordinary go functions as Checkers.
type CheckerFunc func() Health
type CheckerFunc func(ctx context.Context) Health

func (f CheckerFunc) Check() Health {
return f()
func (f CheckerFunc) Check(ctx context.Context) Health {
return f(ctx)
}

type checkerItem struct {
Expand Down Expand Up @@ -51,7 +52,7 @@ func (c *CompositeChecker) AddChecker(name string, checker Checker) {

// Check returns the combination of all checkers added
// if some check is not up, the combined is marked as down
func (c CompositeChecker) Check() Health {
func (c CompositeChecker) Check(ctx context.Context) Health {
health := NewHealth()
health.Up()

Expand All @@ -67,7 +68,7 @@ func (c CompositeChecker) Check() Health {
wg.Add(1)
item := item
go func() {
ch <- state{h: item.checker.Check(), name: item.name}
ch <- state{h: item.checker.Check(ctx), name: item.name}
wg.Done()
}()
}
Expand Down
25 changes: 14 additions & 11 deletions checker_test.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package health

import "testing"
import (
"context"
"testing"
)

type outOfServiceTestChecker struct{}

func (c outOfServiceTestChecker) Check() Health {
func (c outOfServiceTestChecker) Check(ctx context.Context) Health {
health := NewHealth()
health.OutOfService()

Expand All @@ -13,7 +16,7 @@ func (c outOfServiceTestChecker) Check() Health {

type upTestChecker struct{}

func (c upTestChecker) Check() Health {
func (c upTestChecker) Check(ctx context.Context) Health {
health := NewHealth()
health.Up()

Expand All @@ -22,7 +25,7 @@ func (c upTestChecker) Check() Health {

type downTestChecker struct{}

func (c downTestChecker) Check() Health {
func (c downTestChecker) Check(ctx context.Context) Health {
health := NewHealth()
health.Down()

Expand All @@ -47,7 +50,7 @@ func Test_CompositeChecker_Check_Up(t *testing.T) {
c := NewCompositeChecker()
c.AddChecker("upTestChecker", upTestChecker{})

health := c.Check()
health := c.Check(context.Background())

if !health.IsUp() {
t.Errorf("health.IsUp() == %t, wants %t", health.IsUp(), true)
Expand All @@ -58,7 +61,7 @@ func Test_CompositeChecker_Check_Down(t *testing.T) {
c := NewCompositeChecker()
c.AddChecker("downTestChecker", downTestChecker{})

health := c.Check()
health := c.Check(context.Background())

if !health.IsDown() {
t.Errorf("health.IsDown() == %t, wants %t", health.IsDown(), true)
Expand All @@ -69,7 +72,7 @@ func Test_CompositeChecker_Check_OutOfService(t *testing.T) {
c := NewCompositeChecker()
c.AddChecker("outOfServiceTestChecker", outOfServiceTestChecker{})

health := c.Check()
health := c.Check(context.Background())

if !health.IsDown() {
t.Errorf("health.IsDown() == %t, wants %t", health.IsDown(), true)
Expand All @@ -81,7 +84,7 @@ func Test_CompositeChecker_Check_Down_combined(t *testing.T) {
c.AddChecker("downTestChecker", downTestChecker{})
c.AddChecker("upTestChecker", upTestChecker{})

health := c.Check()
health := c.Check(context.Background())

if !health.IsDown() {
t.Errorf("health.IsDown() == %t, wants %t", health.IsDown(), true)
Expand All @@ -93,7 +96,7 @@ func Test_CompositeChecker_Check_Up_combined(t *testing.T) {
c.AddChecker("upTestChecker", upTestChecker{})
c.AddChecker("upTestChecker", upTestChecker{})

health := c.Check()
health := c.Check(context.Background())

if !health.IsUp() {
t.Errorf("health.IsUp() == %t, wants %t", health.IsUp(), true)
Expand Down Expand Up @@ -125,14 +128,14 @@ func Test_CompositeChecker_AddInfo_null_map(t *testing.T) {
}

func TestCheckerFunc_Check(t *testing.T) {
f := CheckerFunc(func() Health {
f := CheckerFunc(func(ctx context.Context) Health {
h := NewHealth()
h.Up()

return h
})

h := f.Check()
h := f.Check(context.Background())

if !h.IsUp() {
t.Errorf("h.IsUp() == %t, wants %t", h.IsUp(), true)
Expand Down
2 changes: 1 addition & 1 deletion handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ func NewHandler() Handler {
func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
w.Header().Add("Content-Type", "application/json")

health := h.CompositeChecker.Check()
health := h.CompositeChecker.Check(r.Context())

if health.IsDown() {
w.WriteHeader(http.StatusServiceUnavailable)
Expand Down
29 changes: 14 additions & 15 deletions url/checker.go
Original file line number Diff line number Diff line change
@@ -1,47 +1,46 @@
package url

import (
"context"
"net/http"
"time"

"github.com/dimiro1/health"
)

// Checker is a checker that check a given URL
type Checker struct {
URL string
Timeout time.Duration
URL string
}

// NewChecker returns a new url.Checker with the given URL
func NewChecker(url string) Checker {
return Checker{URL: url, Timeout: 5 * time.Second}
}

// NewCheckerWithTimeout returns a new url.Checker with the given URL and given timeout
func NewCheckerWithTimeout(url string, timeout time.Duration) Checker {
return Checker{URL: url, Timeout: timeout}
return Checker{URL: url}
}

// Check makes a HEAD request to the given URL
// If the request returns something different than StatusOK,
// The status is set to StatusBadRequest and the URL is considered Down
func (u Checker) Check() health.Health {
client := http.Client{
Timeout: u.Timeout,
func (u Checker) Check(ctx context.Context) health.Health {
health := health.NewHealth()

req, err := http.NewRequest("HEAD", u.URL, nil)
if err != nil {
health.Down().AddInfo("code", http.StatusBadRequest)
return health
}

health := health.NewHealth()
req = req.WithContext(ctx)

resp, err := client.Head(u.URL)
client := http.Client{}

resp, err := client.Do(req)

if resp != nil {
defer resp.Body.Close()
}

if err != nil {
health.Down().AddInfo("code", http.StatusBadRequest)

return health
}

Expand Down
16 changes: 0 additions & 16 deletions url/checker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,10 @@ import (
"net/http/httptest"
"strings"
"testing"
"time"

"github.com/dimiro1/health"
)

func Test_NewCheckerWithTimeout(t *testing.T) {
timeout := 2 * time.Second
url := "http://www.google.com/"

c := NewCheckerWithTimeout(url, timeout)

if c.Timeout != timeout {
t.Errorf("NewCheckerWithTimeout().Timeout == %d, wants %d", c.Timeout, timeout)
}

if c.URL != url {
t.Errorf("NewCheckerWithTimeout().URL == %s, wants %s", c.URL, url)
}
}

func Test_Checker_Check_Up(t *testing.T) {
mux := http.NewServeMux()

Expand Down