clientv3: AlarmList and AlarmDisarm
parent
dd5b73cfee
commit
c91b2d098d
|
@ -184,7 +184,7 @@ func newClient(cfg *Config) (*Client, error) {
|
||||||
client.Lease = NewLease(client)
|
client.Lease = NewLease(client)
|
||||||
client.Watcher = NewWatcher(client)
|
client.Watcher = NewWatcher(client)
|
||||||
client.Auth = NewAuth(client)
|
client.Auth = NewAuth(client)
|
||||||
client.Maintenance = &maintenance{c: client}
|
client.Maintenance = NewMaintenance(client)
|
||||||
if cfg.Logger != nil {
|
if cfg.Logger != nil {
|
||||||
logger.Set(cfg.Logger)
|
logger.Set(cfg.Logger)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -15,15 +15,26 @@
|
||||||
package clientv3
|
package clientv3
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"sync"
|
||||||
|
|
||||||
pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
|
pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
|
"google.golang.org/grpc"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
DefragmentResponse pb.DefragmentResponse
|
DefragmentResponse pb.DefragmentResponse
|
||||||
|
AlarmResponse pb.AlarmResponse
|
||||||
|
AlarmMember pb.AlarmMember
|
||||||
)
|
)
|
||||||
|
|
||||||
type Maintenance interface {
|
type Maintenance interface {
|
||||||
|
// AlarmList gets all active alarms.
|
||||||
|
AlarmList(ctx context.Context) (*AlarmResponse, error)
|
||||||
|
|
||||||
|
// AlarmDisarm disarms a given alarm.
|
||||||
|
AlarmDisarm(ctx context.Context, m *AlarmMember) (*AlarmResponse, error)
|
||||||
|
|
||||||
// Defragment defragments storage backend of the etcd member with given endpoint.
|
// Defragment defragments storage backend of the etcd member with given endpoint.
|
||||||
// Defragment is only needed when deleting a large number of keys and want to reclaim
|
// Defragment is only needed when deleting a large number of keys and want to reclaim
|
||||||
// the resources.
|
// the resources.
|
||||||
|
@ -36,6 +47,72 @@ type Maintenance interface {
|
||||||
|
|
||||||
type maintenance struct {
|
type maintenance struct {
|
||||||
c *Client
|
c *Client
|
||||||
|
|
||||||
|
mu sync.Mutex
|
||||||
|
conn *grpc.ClientConn // conn in-use
|
||||||
|
remote pb.MaintenanceClient
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewMaintenance(c *Client) Maintenance {
|
||||||
|
conn := c.ActiveConnection()
|
||||||
|
return &maintenance{
|
||||||
|
c: c,
|
||||||
|
conn: conn,
|
||||||
|
remote: pb.NewMaintenanceClient(conn),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *maintenance) AlarmList(ctx context.Context) (*AlarmResponse, error) {
|
||||||
|
req := &pb.AlarmRequest{
|
||||||
|
Action: pb.AlarmRequest_GET,
|
||||||
|
MemberID: 0, // all
|
||||||
|
Alarm: pb.AlarmType_NONE, // all
|
||||||
|
}
|
||||||
|
for {
|
||||||
|
resp, err := m.getRemote().Alarm(ctx, req)
|
||||||
|
if err == nil {
|
||||||
|
return (*AlarmResponse)(resp), nil
|
||||||
|
}
|
||||||
|
if isHalted(ctx, err) {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err = m.switchRemote(err); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *maintenance) AlarmDisarm(ctx context.Context, am *AlarmMember) (*AlarmResponse, error) {
|
||||||
|
req := &pb.AlarmRequest{
|
||||||
|
Action: pb.AlarmRequest_DEACTIVATE,
|
||||||
|
MemberID: am.MemberID,
|
||||||
|
Alarm: am.Alarm,
|
||||||
|
}
|
||||||
|
|
||||||
|
if req.MemberID == 0 && req.Alarm == pb.AlarmType_NONE {
|
||||||
|
ar, err := m.AlarmList(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
ret := AlarmResponse{}
|
||||||
|
for _, am := range ar.Alarms {
|
||||||
|
dresp, derr := m.AlarmDisarm(ctx, (*AlarmMember)(am))
|
||||||
|
if derr != nil {
|
||||||
|
return nil, derr
|
||||||
|
}
|
||||||
|
ret.Alarms = append(ret.Alarms, dresp.Alarms...)
|
||||||
|
}
|
||||||
|
return &ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := m.getRemote().Alarm(ctx, req)
|
||||||
|
if err == nil {
|
||||||
|
return (*AlarmResponse)(resp), nil
|
||||||
|
}
|
||||||
|
if !isHalted(ctx, err) {
|
||||||
|
go m.switchRemote(err)
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *maintenance) Defragment(ctx context.Context, endpoint string) (*DefragmentResponse, error) {
|
func (m *maintenance) Defragment(ctx context.Context, endpoint string) (*DefragmentResponse, error) {
|
||||||
|
@ -50,3 +127,21 @@ func (m *maintenance) Defragment(ctx context.Context, endpoint string) (*Defragm
|
||||||
}
|
}
|
||||||
return (*DefragmentResponse)(resp), nil
|
return (*DefragmentResponse)(resp), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *maintenance) getRemote() pb.MaintenanceClient {
|
||||||
|
m.mu.Lock()
|
||||||
|
defer m.mu.Unlock()
|
||||||
|
return m.remote
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *maintenance) switchRemote(prevErr error) error {
|
||||||
|
m.mu.Lock()
|
||||||
|
defer m.mu.Unlock()
|
||||||
|
newConn, err := m.c.retryConnection(m.conn, prevErr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
m.conn = newConn
|
||||||
|
m.remote = pb.NewMaintenanceClient(m.conn)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue