-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcluster.go
More file actions
115 lines (105 loc) · 2.58 KB
/
cluster.go
File metadata and controls
115 lines (105 loc) · 2.58 KB
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
package stored
import (
"encoding/json"
"errors"
"strings"
"github.com/apple/foundationdb/bindings/go/src/fdb"
"github.com/apple/foundationdb/bindings/go/src/fdb/directory"
)
// Cluster is the main struct for handling work with fdb
type Cluster struct {
db fdb.Database
}
// ClusterStatus is status command fdb format
type ClusterStatus struct {
Client struct {
ClusterFile struct {
Path string `json:"path"`
UpToDate bool `json:"up_to_date"`
} `json:"cluster_file"`
Coordinators struct {
Coordinators []struct {
Address string `json:"address"`
Reachable bool `json:"reachable"`
} `json:"coordinators"`
QuorumReachable bool `json:"quorum_reachable"`
} `json:"coordinators"`
DatabaseStatus struct {
Available bool `json:"available"`
Healthy bool `json:"healthy"`
} `json:"database_status"`
Messages []struct {
Description string `json:"description"`
Name string `json:"name"`
} `json:"messages"`
} `json:"client"`
}
// Connect is main constructor for creating connections
func Connect(cluster string) *Cluster {
fdb.MustAPIVersion(630)
conn := Cluster{
db: fdb.MustOpenDatabase(cluster),
}
return &conn
}
// Directory created an directury that could be used to work with stored
func (c *Cluster) Directory(name string) *Directory {
subspace, err := directory.CreateOrOpen(c.db, []string{name}, nil)
if err != nil {
panic(err)
}
dir := Directory{
Name: name,
Cluster: c,
Subspace: subspace,
}
dir.init()
return &dir
}
// Status will return fdb cluster status
func (c *Cluster) Status() (*ClusterStatus, error) {
status, err := c.db.Transact(func(tr fdb.Transaction) (interface{}, error) {
keyCode := []byte("\xff\xff/status/json")
var k fdb.Key
k = keyCode
resp, err := tr.Get(k).Get()
if err != nil {
return nil, err
}
if len(resp) == 0 {
return nil, ErrNotFound
}
status := ClusterStatus{}
err = json.Unmarshal(resp, &status)
if err != nil {
return nil, err
}
return &status, nil
})
if err != nil {
return nil, err
}
return status.(*ClusterStatus), err
}
// Err return error if something wrong with cluster
func (c *Cluster) Err() error {
status, err := c.Status()
if err != nil {
return err
}
msg := []string{}
if !status.Client.DatabaseStatus.Available {
msg = append(msg, "[Unavailable]")
}
if !status.Client.DatabaseStatus.Healthy {
msg = append(msg, "[Unhealthy]")
LogJSON(status)
}
for _, errMessage := range status.Client.Messages {
msg = append(msg, errMessage.Description)
}
if len(msg) == 0 {
return nil
}
return errors.New(strings.Join(msg, " "))
}