Skip to content

Commit a4456a4

Browse files
WIP
Signed-off-by: Tim Vaillancourt <tim@timvaillancourt.com>
1 parent 80b472c commit a4456a4

File tree

7 files changed

+158
-7
lines changed

7 files changed

+158
-7
lines changed

go/vt/events/eventer/eventer.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package eventer
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/spf13/pflag"
7+
8+
"vitess.io/vitess/go/vt/events"
9+
"vitess.io/vitess/go/vt/log"
10+
"vitess.io/vitess/go/vt/servenv"
11+
)
12+
13+
var eventerName string
14+
15+
func RegisterFlags(fs *pflag.FlagSet) {
16+
fs.StringVar(&eventerName, "eventer", eventerName, "the eventer to be used to broadcast internal events")
17+
}
18+
19+
type Eventer interface {
20+
DeleteTablet(ev *events.DeleteTabletEvent)
21+
EmergencyReparentShard(ev *events.EmergencyReparentShardEvent)
22+
PlannedReparentShard(ev *events.PlannedReparentShardEvent)
23+
}
24+
25+
type NewEventer func() (Eventer, error)
26+
27+
var eventers = make(map[string]NewEventer)
28+
29+
func RegisterEventer(name string, eventerFunc NewEventer) {
30+
if eventers[name] != nil {
31+
log.Fatalf("eventer %v already registered", name)
32+
}
33+
eventers[name] = eventerFunc
34+
}
35+
36+
func Get() (Eventer, error) {
37+
if eventerFunc, ok := eventers[eventerName]; ok {
38+
return eventerFunc()
39+
}
40+
return nil, fmt.Errorf("no eventer %v registered", eventerName)
41+
}
42+
43+
func init() {
44+
servenv.OnParse(func(fs *pflag.FlagSet) {
45+
RegisterFlags(fs)
46+
})
47+
}

go/vt/events/eventer/log.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package eventer
2+
3+
import (
4+
"vitess.io/vitess/go/vt/events"
5+
"vitess.io/vitess/go/vt/log"
6+
)
7+
8+
type LogEventer struct{}
9+
10+
func NewLogEventer() (Eventer, error) {
11+
return &LogEventer{}, nil
12+
}
13+
14+
func (le *LogEventer) DeleteTablet(ev *events.DeleteTabletEvent) {
15+
log.Infof("Received DeleteTabletEvent: %v", ev)
16+
}
17+
18+
func (le *LogEventer) EmergencyReparentShard(ev *events.EmergencyReparentShardEvent) {
19+
log.Infof("Received EmergencyReparentShardEvent: %v", ev)
20+
}
21+
22+
func (le *LogEventer) PlannedReparentShard(ev *events.PlannedReparentShardEvent) {
23+
log.Infof("Received PlannedReparentShardEvent: %v", ev)
24+
}
25+
26+
func init() {
27+
RegisterEventer("log", NewLogEventer)
28+
}

go/vt/events/events.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package events
2+
3+
type SourceType string
4+
5+
const (
6+
SourceVtctld SourceType = "vtctld"
7+
SourceVtorc SourceType = "vtorc"
8+
)
9+
10+
type Source struct {
11+
Type SourceType `json:"type"`
12+
Hostname string `json:"hostname"`
13+
}
14+
15+
func NewSourceVtctld(hostname string) Source {
16+
return Source{
17+
Type: SourceVtctld,
18+
Hostname: hostname,
19+
}
20+
}

go/vt/events/reparents.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package events
2+
3+
import (
4+
"time"
5+
6+
topodatapb "vitess.io/vitess/go/vt/proto/topodata"
7+
"vitess.io/vitess/go/vt/topo"
8+
)
9+
10+
type EmergencyReparentShardEvent struct {
11+
Source Source `json:"source"`
12+
Time time.Time `json:"time"`
13+
ShardInfo topo.ShardInfo `json:"shard_info"`
14+
OldPrimary *topodatapb.Tablet `json:"old_primary"`
15+
NewPrimary *topodatapb.Tablet `json:"new_primary"`
16+
Error error `json:"error"`
17+
}
18+
19+
type PlannedReparentShardEvent struct {
20+
Source Source `json:"source"`
21+
Time time.Time `json:"time"`
22+
ShardInfo topo.ShardInfo `json:"shard_info"`
23+
OldPrimary *topodatapb.Tablet `json:"old_primary"`
24+
NewPrimary *topodatapb.Tablet `json:"new_primary"`
25+
Error error `json:"error"`
26+
}

go/vt/events/tablets.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package events
2+
3+
import (
4+
"time"
5+
6+
topodatapb "vitess.io/vitess/go/vt/proto/topodata"
7+
)
8+
9+
// DeleteTabletEvent represents a DeleteTablet event from vtctl.
10+
type DeleteTabletEvent struct {
11+
Source Source `json:"source"`
12+
Time time.Time `json:"time"`
13+
Tablet *topodatapb.Tablet `json:"tablet"`
14+
Error error `json:"error"`
15+
}

go/vt/vtctl/grpcvtctldserver/server.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ import (
4242
"vitess.io/vitess/go/trace"
4343
"vitess.io/vitess/go/vt/callerid"
4444
"vitess.io/vitess/go/vt/concurrency"
45+
"vitess.io/vitess/go/vt/events/eventer"
4546
hk "vitess.io/vitess/go/vt/hook"
4647
"vitess.io/vitess/go/vt/key"
4748
"vitess.io/vitess/go/vt/log"
@@ -90,26 +91,29 @@ type VtctldServer struct {
9091
ts *topo.Server
9192
tmc tmclient.TabletManagerClient
9293
ws *workflow.Server
94+
ev eventer.Eventer
9395
}
9496

9597
// NewVtctldServer returns a new VtctldServer for the given topo server.
96-
func NewVtctldServer(env *vtenv.Environment, ts *topo.Server) *VtctldServer {
98+
func NewVtctldServer(env *vtenv.Environment, ts *topo.Server, ev eventer.Eventer) *VtctldServer {
9799
tmc := tmclient.NewTabletManagerClient()
98100

99101
return &VtctldServer{
100102
ts: ts,
101103
tmc: tmc,
102104
ws: workflow.NewServer(env, ts, tmc),
105+
ev: ev,
103106
}
104107
}
105108

106109
// NewTestVtctldServer returns a new VtctldServer for the given topo server
107110
// AND tmclient for use in tests. This should NOT be used in production.
108-
func NewTestVtctldServer(ts *topo.Server, tmc tmclient.TabletManagerClient) *VtctldServer {
111+
func NewTestVtctldServer(ts *topo.Server, tmc tmclient.TabletManagerClient, ev eventer.Eventer) *VtctldServer {
109112
return &VtctldServer{
110113
ts: ts,
111114
tmc: tmc,
112115
ws: workflow.NewServer(vtenv.NewTestEnv(), ts, tmc),
116+
ev: ev,
113117
}
114118
}
115119

@@ -1122,7 +1126,7 @@ func (s *VtctldServer) DeleteTablets(ctx context.Context, req *vtctldatapb.Delet
11221126
span.Annotate("allow_primary", req.AllowPrimary)
11231127

11241128
for _, alias := range req.TabletAliases {
1125-
if err2 := deleteTablet(ctx, s.ts, alias, req.AllowPrimary); err2 != nil {
1129+
if err2 := deleteTablet(ctx, s.ts, s.ev, alias, req.AllowPrimary); err2 != nil {
11261130
err = err2
11271131
return nil, err
11281132
}
@@ -5029,8 +5033,8 @@ func (s *VtctldServer) WorkflowUpdate(ctx context.Context, req *vtctldatapb.Work
50295033
}
50305034

50315035
// StartServer registers a VtctldServer for RPCs on the given gRPC server.
5032-
func StartServer(s *grpc.Server, env *vtenv.Environment, ts *topo.Server) {
5033-
vtctlservicepb.RegisterVtctldServer(s, NewVtctldServer(env, ts))
5036+
func StartServer(s *grpc.Server, env *vtenv.Environment, ts *topo.Server, ev eventer.Eventer) {
5037+
vtctlservicepb.RegisterVtctldServer(s, NewVtctldServer(env, ts, ev))
50345038
}
50355039

50365040
// getTopologyCell is a helper method that returns a topology cell given its path.

go/vt/vtctl/grpcvtctldserver/topo.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ import (
2222
"time"
2323

2424
"vitess.io/vitess/go/trace"
25+
"vitess.io/vitess/go/vt/events"
26+
"vitess.io/vitess/go/vt/events/eventer"
2527
"vitess.io/vitess/go/vt/log"
2628
"vitess.io/vitess/go/vt/topo"
2729
"vitess.io/vitess/go/vt/topo/topoproto"
@@ -205,7 +207,7 @@ func deleteShardCell(ctx context.Context, ts *topo.Server, keyspace string, shar
205207
return nil
206208
}
207209

208-
func deleteTablet(ctx context.Context, ts *topo.Server, alias *topodatapb.TabletAlias, allowPrimary bool) (err error) {
210+
func deleteTablet(ctx context.Context, ts *topo.Server, ev eventer.Eventer, alias *topodatapb.TabletAlias, allowPrimary bool) (err error) {
209211
span, ctx := trace.NewSpan(ctx, "VtctldServer.deleteTablet")
210212
defer span.Finish()
211213

@@ -257,7 +259,16 @@ func deleteTablet(ctx context.Context, ts *topo.Server, alias *topodatapb.Tablet
257259
}
258260

259261
// Remove the tablet record and its replication graph entry.
260-
if err := topotools.DeleteTablet(ctx, ts, tablet.Tablet); err != nil {
262+
err = topotools.DeleteTablet(ctx, ts, tablet.Tablet)
263+
if ev != nil {
264+
ev.DeleteTablet(&events.DeleteTabletEvent{
265+
Source: events.NewSourceVtctld("TODO"),
266+
Time: time.Now(),
267+
Tablet: tablet.Tablet,
268+
Error: err,
269+
})
270+
}
271+
if err != nil {
261272
return err
262273
}
263274

0 commit comments

Comments
 (0)