Skip to content

Commit f334919

Browse files
davissp14Shaun Davis
and
Shaun Davis
authored
Check framework (#32)
* Check rewrite using new basic Health Check framework * Removing unused method Co-authored-by: Shaun Davis <[email protected]>
1 parent d35a992 commit f334919

File tree

10 files changed

+744
-164
lines changed

10 files changed

+744
-164
lines changed

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ module github.com/fly-examples/postgres-ha
33
go 1.16
44

55
require (
6+
github.com/jackc/pgtype v1.6.2 // indirect
67
github.com/jackc/pgx/v4 v4.10.1
78
github.com/kr/pretty v0.2.0 // indirect
89
github.com/pkg/errors v0.8.1

pkg/check/check.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package check
2+
3+
import (
4+
"fmt"
5+
"time"
6+
)
7+
8+
type CheckFunction func() (string, error)
9+
type Check struct {
10+
Name string
11+
CheckFunc CheckFunction
12+
startTime time.Time
13+
endTime time.Time
14+
message string
15+
err error
16+
}
17+
18+
func (c *Check) Process() {
19+
c.startTime = time.Now()
20+
c.message, c.err = c.CheckFunc()
21+
c.endTime = time.Now()
22+
}
23+
24+
func (c *Check) Error() string {
25+
return c.err.Error()
26+
}
27+
28+
func (c *Check) Passed() bool {
29+
if c.startTime.IsZero() || c.endTime.IsZero() {
30+
return false
31+
}
32+
return c.err == nil
33+
}
34+
35+
func (c *Check) ExecutionTime() time.Duration {
36+
if !c.endTime.IsZero() {
37+
return RoundDuration(c.endTime.Sub(c.startTime), 2)
38+
}
39+
return RoundDuration(time.Now().Sub(c.startTime), 2)
40+
}
41+
42+
func (c *Check) Result() string {
43+
if c.startTime.IsZero() {
44+
return fmt.Sprintf("[-] %s: %s", c.Name, "Not processed")
45+
}
46+
if !c.startTime.IsZero() && c.endTime.IsZero() {
47+
return fmt.Sprintf("[✗] %s: %s (%s)", c.Name, "Timed out", c.ExecutionTime())
48+
}
49+
if c.Passed() {
50+
return fmt.Sprintf("[✓] %s: %s (%s)", c.Name, c.message, c.ExecutionTime())
51+
} else {
52+
return fmt.Sprintf("[✗] %s: %s (%s)", c.Name, c.err.Error(), c.ExecutionTime())
53+
}
54+
}
55+
56+
func (c *Check) RawResult() string {
57+
if c.Passed() {
58+
return c.message
59+
}
60+
return c.err.Error()
61+
}

pkg/check/check_suite.go

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
package check
2+
3+
import (
4+
"context"
5+
"errors"
6+
"fmt"
7+
"strings"
8+
"time"
9+
)
10+
11+
type OnCompletionHook func()
12+
type CheckSuite struct {
13+
Name string
14+
Checks []*Check
15+
OnCompletion OnCompletionHook
16+
ErrOnSetup error
17+
executionTime time.Duration
18+
processed bool
19+
clean bool
20+
}
21+
22+
func NewCheckSuite(name string) *CheckSuite {
23+
return &CheckSuite{Name: name}
24+
}
25+
26+
func (h *CheckSuite) Process(parentCtx context.Context) {
27+
ctx, cancel := context.WithCancel(parentCtx)
28+
start := time.Now()
29+
for _, check := range h.Checks {
30+
check.Process()
31+
}
32+
h.executionTime = RoundDuration(time.Since(start), 2)
33+
h.processed = true
34+
h.runOnCompletion()
35+
cancel()
36+
37+
select {
38+
case <-ctx.Done():
39+
// Handle timeout
40+
if errors.Is(ctx.Err(), context.DeadlineExceeded) {
41+
h.executionTime = RoundDuration(time.Since(start), 2)
42+
h.processed = true
43+
h.runOnCompletion()
44+
}
45+
}
46+
}
47+
48+
func (h *CheckSuite) runOnCompletion() {
49+
if h.clean {
50+
return
51+
}
52+
if h.OnCompletion != nil {
53+
h.OnCompletion()
54+
}
55+
h.clean = true
56+
}
57+
58+
func (h *CheckSuite) AddCheck(name string, checkFunc CheckFunction) *Check {
59+
check := &Check{Name: name, CheckFunc: checkFunc}
60+
h.Checks = append(h.Checks, check)
61+
return check
62+
}
63+
64+
func (h *CheckSuite) Passed() bool {
65+
for _, check := range h.Checks {
66+
if !check.Passed() {
67+
return false
68+
}
69+
}
70+
return true
71+
}
72+
73+
func (h *CheckSuite) Result() string {
74+
checkStr := []string{}
75+
for _, check := range h.Checks {
76+
checkStr = append(checkStr, check.Result())
77+
}
78+
return strings.Join(checkStr, "\n")
79+
}
80+
81+
func (h *CheckSuite) RawResult() string {
82+
checkStr := []string{}
83+
for _, check := range h.Checks {
84+
checkStr = append(checkStr, check.RawResult())
85+
}
86+
return strings.Join(checkStr, "\n")
87+
}
88+
89+
// Print will send output straight to stdout.
90+
func (h *CheckSuite) Print() {
91+
if h.processed {
92+
for _, check := range h.Checks {
93+
fmt.Println(check.Result())
94+
}
95+
fmt.Printf("Total execution time of %q checks: %s\n", h.Name, h.executionTime)
96+
} else {
97+
if len(h.Checks) > 0 {
98+
fmt.Printf("%q hasn't been processed. %d check(s) pending evaluation.\n", h.Name, len(h.Checks))
99+
} else {
100+
fmt.Printf("%q has no checks to evaluate.\n", h.Name)
101+
}
102+
}
103+
}

0 commit comments

Comments
 (0)