-
Notifications
You must be signed in to change notification settings - Fork 86
/
health.go
87 lines (76 loc) · 2.68 KB
/
health.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
package reporting
import (
"github.com/sirupsen/logrus"
"golang.org/x/sync/singleflight"
"github.com/operator-framework/operator-metering/pkg/db"
"github.com/operator-framework/operator-metering/pkg/hive"
"github.com/operator-framework/operator-metering/pkg/presto"
)
type PrestoHealthChecker struct {
logger logrus.FieldLogger
queryer db.Queryer
tableManager HiveTableManager
databaseName, tableName string
// ensures only at most a single testRead query is running against Presto
// at one time
healthCheckSingleFlight singleflight.Group
}
func NewPrestoHealthChecker(logger logrus.FieldLogger, queryer db.Queryer, tableManager HiveTableManager, databaseName, tableName string) *PrestoHealthChecker {
return &PrestoHealthChecker{
logger: logger,
queryer: queryer,
tableManager: tableManager,
databaseName: databaseName,
tableName: tableName,
}
}
func (checker *PrestoHealthChecker) TestWriteToPrestoSingleFlight() bool {
const key = "presto-write"
v, _, _ := checker.healthCheckSingleFlight.Do(key, func() (interface{}, error) {
defer checker.healthCheckSingleFlight.Forget(key)
healthy := checker.TestWriteToPresto()
return healthy, nil
})
healthy := v.(bool)
return healthy
}
func (checker *PrestoHealthChecker) TestReadFromPrestoSingleFlight() bool {
const key = "presto-read"
v, _, _ := checker.healthCheckSingleFlight.Do(key, func() (interface{}, error) {
defer checker.healthCheckSingleFlight.Forget(key)
healthy := checker.TestReadFromPresto()
return healthy, nil
})
healthy := v.(bool)
return healthy
}
func (checker *PrestoHealthChecker) TestReadFromPresto() bool {
_, err := presto.ExecuteSelect(checker.queryer, "SELECT * FROM system.runtime.nodes")
if err != nil {
checker.logger.WithError(err).Debugf("cannot query Presto system.runtime.nodes table")
return false
}
return true
}
func (checker *PrestoHealthChecker) TestWriteToPresto() bool {
logger := checker.logger.WithField("component", "testWriteToPresto")
columns := []hive.Column{{Name: "check_time", Type: "TIMESTAMP"}}
params := hive.TableParameters{
Database: checker.databaseName,
Name: checker.tableName,
Columns: columns,
}
err := checker.tableManager.CreateTable(params, true)
if err != nil {
logger.WithError(err).Errorf("cannot create Presto table %s", checker.tableName)
return false
}
// Hive does not support timezones, and now() returns a
// TIMESTAMP WITH TIMEZONE so we cast the return of now() to a TIMESTAMP.
err = presto.InsertInto(checker.queryer, checker.tableName, "VALUES (cast(now() AS TIMESTAMP))")
if err != nil {
logger.WithError(err).Errorf("cannot insert into Presto table %s", checker.tableName)
return false
}
return true
}