diff --git a/controller.go b/controller.go new file mode 100644 index 000000000..c28fcb73d --- /dev/null +++ b/controller.go @@ -0,0 +1,46 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package weaver + +import ( + "context" + "fmt" + + "github.com/ServiceWeaver/weaver/internal/control" + "github.com/ServiceWeaver/weaver/runtime/protos" +) + +// controller is a component hosted in every weavelet. Deployers make calls to this component to +// fetch information about the weavelet, and to make it do various things. +type controller control.Controller + +// noopController is a no-op implementation of controller. It exists solely to cause +// controller to be registered as a component. The actual implementation is provided +// by internal/weaver/remoteweavelet.go +type noopController struct { + Implements[controller] +} + +var _ controller = &noopController{} + +// GetHealth implements controller interface. +func (*noopController) GetHealth(context.Context, *protos.GetHealthRequest) (*protos.GetHealthReply, error) { + return nil, fmt.Errorf("controller.GetHealth not implemented") +} + +// UpdateComponents implements controller interface. +func (*noopController) UpdateComponents(context.Context, *protos.UpdateComponentsRequest) (*protos.UpdateComponentsReply, error) { + return nil, fmt.Errorf("controller.UpdateComponents not implemented") +} diff --git a/godeps.txt b/godeps.txt index 21298a24b..faf86d81e 100644 --- a/godeps.txt +++ b/godeps.txt @@ -3,6 +3,7 @@ github.com/ServiceWeaver/weaver context errors fmt + github.com/ServiceWeaver/weaver/internal/control github.com/ServiceWeaver/weaver/internal/reflection github.com/ServiceWeaver/weaver/internal/weaver github.com/ServiceWeaver/weaver/metrics @@ -300,6 +301,9 @@ github.com/ServiceWeaver/weaver/internal/config fmt reflect strings +github.com/ServiceWeaver/weaver/internal/control + context + github.com/ServiceWeaver/weaver/runtime/protos github.com/ServiceWeaver/weaver/internal/env fmt strings @@ -701,6 +705,7 @@ github.com/ServiceWeaver/weaver/internal/weaver github.com/DataDog/hyperloglog github.com/ServiceWeaver/weaver/internal/cond github.com/ServiceWeaver/weaver/internal/config + github.com/ServiceWeaver/weaver/internal/control github.com/ServiceWeaver/weaver/internal/env github.com/ServiceWeaver/weaver/internal/envelope/conn github.com/ServiceWeaver/weaver/internal/metrics @@ -712,6 +717,7 @@ github.com/ServiceWeaver/weaver/internal/weaver github.com/ServiceWeaver/weaver/runtime github.com/ServiceWeaver/weaver/runtime/codegen github.com/ServiceWeaver/weaver/runtime/colors + github.com/ServiceWeaver/weaver/runtime/deployers github.com/ServiceWeaver/weaver/runtime/logging github.com/ServiceWeaver/weaver/runtime/metrics github.com/ServiceWeaver/weaver/runtime/protos @@ -812,21 +818,32 @@ github.com/ServiceWeaver/weaver/runtime/colors strings github.com/ServiceWeaver/weaver/runtime/deployers context + fmt github.com/ServiceWeaver/weaver/internal/net/call log/slog net + path/filepath + sync github.com/ServiceWeaver/weaver/runtime/envelope bufio context errors fmt + github.com/ServiceWeaver/weaver + github.com/ServiceWeaver/weaver/internal/control github.com/ServiceWeaver/weaver/internal/envelope/conn + github.com/ServiceWeaver/weaver/internal/net/call github.com/ServiceWeaver/weaver/internal/pipe github.com/ServiceWeaver/weaver/runtime + github.com/ServiceWeaver/weaver/runtime/codegen + github.com/ServiceWeaver/weaver/runtime/deployers github.com/ServiceWeaver/weaver/runtime/metrics + github.com/ServiceWeaver/weaver/runtime/protomsg github.com/ServiceWeaver/weaver/runtime/protos + go.opentelemetry.io/otel/trace golang.org/x/sync/errgroup io + log/slog os strconv sync @@ -983,12 +1000,14 @@ github.com/ServiceWeaver/weaver/weavertest github.com/ServiceWeaver/weaver/internal/weaver github.com/ServiceWeaver/weaver/runtime github.com/ServiceWeaver/weaver/runtime/codegen + github.com/ServiceWeaver/weaver/runtime/deployers github.com/ServiceWeaver/weaver/runtime/envelope github.com/ServiceWeaver/weaver/runtime/logging github.com/ServiceWeaver/weaver/runtime/protos github.com/google/uuid golang.org/x/exp/maps golang.org/x/sync/errgroup + log/slog os reflect regexp @@ -1072,11 +1091,14 @@ github.com/ServiceWeaver/weaver/website/blog/deployers/multi github.com/ServiceWeaver/weaver/runtime/logging github.com/ServiceWeaver/weaver/runtime/protos github.com/google/uuid + os sync github.com/ServiceWeaver/weaver/website/blog/deployers/pipes context flag fmt + github.com/ServiceWeaver/weaver/runtime + github.com/ServiceWeaver/weaver/runtime/deployers github.com/ServiceWeaver/weaver/runtime/protomsg github.com/ServiceWeaver/weaver/runtime/protos github.com/google/uuid diff --git a/internal/control/controller.go b/internal/control/controller.go new file mode 100644 index 000000000..fe8fca235 --- /dev/null +++ b/internal/control/controller.go @@ -0,0 +1,35 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package control + +import ( + "context" + + "github.com/ServiceWeaver/weaver/runtime/protos" +) + +// Controller is the interface for the weaver.controller component. It is present in +// its own package so other packages do not need to copy the interface definition. +// +// Arguments and results are protobufs to allow deployers to evolve independently of +// application binaries. +type Controller interface { + // GetHealth returns the health of the weavelet. + GetHealth(context.Context, *protos.GetHealthRequest) (*protos.GetHealthReply, error) + + // UpdateComponents updates the weavelet with the latest set of components it + // should be running. + UpdateComponents(context.Context, *protos.UpdateComponentsRequest) (*protos.UpdateComponentsReply, error) +} diff --git a/internal/envelope/conn/conn_test.go b/internal/envelope/conn/conn_test.go index a414b02b9..eb5031263 100644 --- a/internal/envelope/conn/conn_test.go +++ b/internal/envelope/conn/conn_test.go @@ -28,6 +28,7 @@ import ( "github.com/ServiceWeaver/weaver/internal/reflection" "github.com/ServiceWeaver/weaver/metrics" "github.com/ServiceWeaver/weaver/runtime/codegen" + "github.com/ServiceWeaver/weaver/runtime/deployers" "github.com/ServiceWeaver/weaver/runtime/protos" "github.com/google/uuid" "go.opentelemetry.io/otel/trace" @@ -106,6 +107,7 @@ func makeConnections(t *testing.T, handler conn.EnvelopeHandler) (*conn.Envelope App: "app", DeploymentId: uuid.New().String(), Id: uuid.New().String(), + ControlSocket: deployers.NewUnixSocketPath(t.TempDir()), InternalAddress: "localhost:0", } diff --git a/internal/envelope/conn/weavelet_conn.go b/internal/envelope/conn/weavelet_conn.go index 428500939..60b51a2ec 100644 --- a/internal/envelope/conn/weavelet_conn.go +++ b/internal/envelope/conn/weavelet_conn.go @@ -41,7 +41,7 @@ type WeaveletHandler interface { // UpdateComponents updates the set of components the weavelet should be // running. Currently, the set of components only increases over time. - UpdateComponents(*protos.UpdateComponentsRequest) (*protos.UpdateComponentsReply, error) + UpdateComponents(context.Context, *protos.UpdateComponentsRequest) (*protos.UpdateComponentsReply, error) // UpdateRoutingInfo updates a component's routing information. UpdateRoutingInfo(*protos.UpdateRoutingInfoRequest) (*protos.UpdateRoutingInfoReply, error) @@ -200,7 +200,7 @@ func (w *WeaveletConn) handleMessage(handler WeaveletHandler, msg *protos.Envelo }() return nil case msg.UpdateComponentsRequest != nil: - reply, err := handler.UpdateComponents(msg.UpdateComponentsRequest) + reply, err := handler.UpdateComponents(context.Background(), msg.UpdateComponentsRequest) return w.conn.send(&protos.WeaveletMsg{ Id: -msg.Id, Error: errstring(err), diff --git a/internal/net/call/stub.go b/internal/net/call/stub.go index acdc3db99..0f0c7f40c 100644 --- a/internal/net/call/stub.go +++ b/internal/net/call/stub.go @@ -41,7 +41,7 @@ var _ codegen.Stub = &stub{} func NewStub(name string, reg *codegen.Registration, conn Connection, tracer trace.Tracer, injectRetries int) codegen.Stub { return &stub{ conn: conn, - methods: makeStubMethods(name, reg), // XXX Remove reg.Name arg from makeStubMethods + methods: makeStubMethods(name, reg), tracer: tracer, injectRetries: injectRetries, } diff --git a/internal/testdeployer/remoteweavelet_test.go b/internal/testdeployer/remoteweavelet_test.go index f2b2ab054..b07215544 100644 --- a/internal/testdeployer/remoteweavelet_test.go +++ b/internal/testdeployer/remoteweavelet_test.go @@ -28,6 +28,7 @@ import ( "github.com/ServiceWeaver/weaver/internal/weaver" "github.com/ServiceWeaver/weaver/runtime" "github.com/ServiceWeaver/weaver/runtime/codegen" + "github.com/ServiceWeaver/weaver/runtime/deployers" "github.com/ServiceWeaver/weaver/runtime/envelope" "github.com/ServiceWeaver/weaver/runtime/logging" "github.com/ServiceWeaver/weaver/runtime/protomsg" @@ -212,6 +213,7 @@ func deployWithInfo(t *testing.T, ctx context.Context, placement map[string][]st for name := range placement { info := protomsg.Clone(info) info.Id = uuid.New().String() + info.ControlSocket = deployers.NewUnixSocketPath(t.TempDir()) weavelet, err := spawn(ctx, info, d) if err != nil { t.Fatal(err) @@ -244,7 +246,7 @@ func (d *deployer) ActivateComponent(ctx context.Context, req *protos.ActivateCo replicas := []string{} for _, name := range d.placedAt[req.Component] { weavelet := d.weavelets[name] - if _, err := weavelet.wlet.UpdateComponents(components); err != nil { + if _, err := weavelet.wlet.UpdateComponents(ctx, components); err != nil { return nil, err } replicas = append(replicas, weavelet.env.WeaveletInfo().DialAddr) @@ -416,6 +418,7 @@ func TestLocalhostWeaveletAddress(t *testing.T) { d := deployWithInfo(t, context.Background(), colocated, &protos.EnvelopeInfo{ App: "remoteweavelet_test.go", DeploymentId: fmt.Sprint(os.Getpid()), + ControlSocket: deployers.NewUnixSocketPath(t.TempDir()), InternalAddress: "localhost:12345", }) defer d.shutdown() @@ -443,6 +446,7 @@ func TestHostnameWeaveletAddress(t *testing.T) { d := deployWithInfo(t, context.Background(), colocated, &protos.EnvelopeInfo{ App: "remoteweavelet_test.go", DeploymentId: fmt.Sprint(os.Getpid()), + ControlSocket: deployers.NewUnixSocketPath(t.TempDir()), InternalAddress: net.JoinHostPort(ips[0].String(), "12345"), }) defer d.shutdown() @@ -488,7 +492,7 @@ func TestFailActivateComponent(t *testing.T) { return nil, err } components := &protos.UpdateComponentsRequest{Components: []string{req.Component}} - if _, err := d.weavelets["1"].wlet.UpdateComponents(components); err != nil { + if _, err := d.weavelets["1"].wlet.UpdateComponents(ctx, components); err != nil { return nil, err } return &protos.ActivateComponentReply{}, nil @@ -607,7 +611,7 @@ func TestUpdateMissingComponents(t *testing.T) { // Update the weavelet with components that don't exist. components := &protos.UpdateComponentsRequest{Components: []string{"foo", "bar"}} - if _, err := d.weavelets["1"].wlet.UpdateComponents(components); err == nil { + if _, err := d.weavelets["1"].wlet.UpdateComponents(context.Background(), components); err == nil { t.Fatal("unexpected success") } @@ -623,7 +627,7 @@ func TestUpdateExistingComponents(t *testing.T) { components := &protos.UpdateComponentsRequest{ Components: []string{componenta, componentb, componentc}, } - if _, err := d.weavelets["1"].wlet.UpdateComponents(components); err != nil { + if _, err := d.weavelets["1"].wlet.UpdateComponents(context.Background(), components); err != nil { t.Fatal(err) } @@ -756,7 +760,7 @@ func TestUpdateBadRoutingInfo(t *testing.T) { componentc: d.weavelets["3"], } weavelet := weavelets[req.Component] - if _, err := weavelet.wlet.UpdateComponents(components); err != nil { + if _, err := weavelet.wlet.UpdateComponents(ctx, components); err != nil { return nil, err } diff --git a/internal/tool/multi/deployer.go b/internal/tool/multi/deployer.go index 6e5aff754..0596ae324 100644 --- a/internal/tool/multi/deployer.go +++ b/internal/tool/multi/deployer.go @@ -23,7 +23,6 @@ import ( "log/slog" "net" "net/http" - "path/filepath" "slices" "sync" "syscall" @@ -60,6 +59,7 @@ type deployer struct { ctx context.Context ctxCancel context.CancelFunc deploymentId string + tmpDir string // Private directory for this weavelet/envelope udsPath string // Path to Unix domain socket config *MultiConfig started time.Time @@ -147,7 +147,7 @@ func newDeployer(ctx context.Context, deploymentId string, config *MultiConfig, } // Make Unix domain socket listener for serving hosted system components. - udsPath := filepath.Join(tmpDir, "socket") + udsPath := deployers.NewUnixSocketPath(tmpDir) uds, err := net.Listen("unix", udsPath) if err != nil { return nil, err @@ -157,6 +157,7 @@ func newDeployer(ctx context.Context, deploymentId string, config *MultiConfig, d := &deployer{ ctx: ctx, ctxCancel: cancel, + tmpDir: tmpDir, udsPath: udsPath, logger: logger, caCert: caCert, @@ -357,7 +358,9 @@ func (d *deployer) startColocationGroup(g *group) error { }, }, } - e, err := envelope.NewEnvelope(d.ctx, info, d.config.App) + e, err := envelope.NewEnvelope(d.ctx, info, d.config.App, envelope.Options{ + Logger: d.logger, + }) if err != nil { return err } diff --git a/internal/tool/ssh/impl/babysitter.go b/internal/tool/ssh/impl/babysitter.go index 28b2e0912..db579c641 100644 --- a/internal/tool/ssh/impl/babysitter.go +++ b/internal/tool/ssh/impl/babysitter.go @@ -97,7 +97,9 @@ func RunBabysitter(ctx context.Context) error { Sections: info.App.Sections, RunMain: info.RunMain, } - e, err := envelope.NewEnvelope(ctx, wlet, info.App) + e, err := envelope.NewEnvelope(ctx, wlet, info.App, envelope.Options{ + Logger: b.logger, + }) if err != nil { return err } diff --git a/internal/weaver/remoteweavelet.go b/internal/weaver/remoteweavelet.go index a71c55de9..c0aeaf815 100644 --- a/internal/weaver/remoteweavelet.go +++ b/internal/weaver/remoteweavelet.go @@ -28,12 +28,14 @@ import ( "sync" "github.com/ServiceWeaver/weaver/internal/config" + "github.com/ServiceWeaver/weaver/internal/control" "github.com/ServiceWeaver/weaver/internal/envelope/conn" "github.com/ServiceWeaver/weaver/internal/net/call" "github.com/ServiceWeaver/weaver/internal/register" "github.com/ServiceWeaver/weaver/internal/traceio" "github.com/ServiceWeaver/weaver/runtime" "github.com/ServiceWeaver/weaver/runtime/codegen" + "github.com/ServiceWeaver/weaver/runtime/deployers" "github.com/ServiceWeaver/weaver/runtime/logging" "github.com/ServiceWeaver/weaver/runtime/protos" "github.com/ServiceWeaver/weaver/runtime/retry" @@ -55,6 +57,8 @@ type RemoteWeaveletOptions struct { // coordinates with a deployer over a set of Unix pipes to start other // components remotely. It is the weavelet used by all deployers, except for // the single process deployer. +// +// RemoteWeavelet must implement the weaver.controller component interface. type RemoteWeavelet struct { ctx context.Context // shuts down the weavelet when canceled servers *errgroup.Group // background servers @@ -73,6 +77,8 @@ type RemoteWeavelet struct { listeners map[string]*listener // listeners, by name } +var _ control.Controller = (*RemoteWeavelet)(nil) + type redirect struct { component *component target string @@ -140,12 +146,16 @@ func NewRemoteWeavelet(ctx context.Context, regs []*codegen.Registration, bootst if err != nil { return nil, err } - // TODO(mwhittaker): Pass handler to Serve, not NewWeaveletConn. + w.conn, err = conn.NewWeaveletConn(toWeavelet, toEnvelope) if err != nil { return nil, fmt.Errorf("new weavelet conn: %w", err) } info := w.conn.EnvelopeInfo() + controlSocket, err := net.Listen("unix", info.ControlSocket) + if err != nil { + return nil, err + } // Set up logging. w.syslogger = w.logger("weavelet", "serviceweaver/system", "") @@ -214,6 +224,13 @@ func NewRemoteWeavelet(ctx context.Context, regs []*codegen.Registration, bootst return nil }) + // Serve the control component. + servers.Go(func() error { + return deployers.ServeComponents(ctx, controlSocket, w.syslogger, map[string]any{ + "github.com/ServiceWeaver/weaver/controller": w, + }) + }) + // Serve RPC requests from other weavelets. servers.Go(func() error { server := &server{Listener: w.conn.Listener(), wlet: w} @@ -448,8 +465,13 @@ func (w *RemoteWeavelet) GetLoad(*protos.GetLoadRequest) (*protos.GetLoadReply, return &protos.GetLoadReply{Load: report}, nil } -// UpdateComponents implements the conn.WeaverHandler interface. -func (w *RemoteWeavelet) UpdateComponents(req *protos.UpdateComponentsRequest) (*protos.UpdateComponentsReply, error) { +// GetHealth implements the weaver.controller interface. +func (w *RemoteWeavelet) GetHealth(ctx context.Context, req *protos.GetHealthRequest) (*protos.GetHealthReply, error) { + return &protos.GetHealthReply{Status: protos.HealthStatus_HEALTHY}, nil +} + +// UpdateComponents implements weaver.controller and conn.WeaverHandler interfaces. +func (w *RemoteWeavelet) UpdateComponents(ctx context.Context, req *protos.UpdateComponentsRequest) (*protos.UpdateComponentsReply, error) { var errs []error var components []*component var shortened []string diff --git a/runtime/deployers/serve.go b/runtime/deployers/serve.go index 73781154c..8a9c2e65e 100644 --- a/runtime/deployers/serve.go +++ b/runtime/deployers/serve.go @@ -17,8 +17,11 @@ package deployers import ( "context" + "fmt" "log/slog" "net" + "path/filepath" + "sync" "github.com/ServiceWeaver/weaver/internal/net/call" ) @@ -52,3 +55,22 @@ func (f *fixedListener) Accept() (net.Conn, *call.HandlerMap, error) { c, err := f.Listener.Accept() return c, f.handlers, err } + +var ( + pathMu sync.Mutex + pathCounter int64 +) + +// NewUnixSocketPath returns the path to use for a new Unix domain socket. +// The path exists in dir, which should be a directory entirely owned by this +// process, with a short full path-name, typically created by runtime.NewTempDir(). +func NewUnixSocketPath(dir string) string { + pathMu.Lock() + defer pathMu.Unlock() + + // Since dir is private to this process, we can generate unique paths by + // using a simple incrementing counter. We keep the names small since + // Unix domain socket paths have a short maximum length. + pathCounter++ + return filepath.Join(dir, fmt.Sprintf("_uds%d", pathCounter)) +} diff --git a/runtime/envelope/envelope.go b/runtime/envelope/envelope.go index bb3f30bf3..e2329251a 100644 --- a/runtime/envelope/envelope.go +++ b/runtime/envelope/envelope.go @@ -22,16 +22,26 @@ import ( "errors" "fmt" "io" + "log/slog" "os" "strconv" "sync" + "github.com/ServiceWeaver/weaver/internal/control" "github.com/ServiceWeaver/weaver/internal/envelope/conn" + "github.com/ServiceWeaver/weaver/internal/net/call" "github.com/ServiceWeaver/weaver/internal/pipe" "github.com/ServiceWeaver/weaver/runtime" + "github.com/ServiceWeaver/weaver/runtime/codegen" + "github.com/ServiceWeaver/weaver/runtime/deployers" "github.com/ServiceWeaver/weaver/runtime/metrics" + "github.com/ServiceWeaver/weaver/runtime/protomsg" "github.com/ServiceWeaver/weaver/runtime/protos" + "go.opentelemetry.io/otel/trace" "golang.org/x/sync/errgroup" + + // We rely on the weaver.controller component registrattion entry. + _ "github.com/ServiceWeaver/weaver" ) // EnvelopeHandler handles messages from the weavelet. Values passed to the @@ -99,30 +109,70 @@ type Envelope struct { // Fields below are constant after construction. ctx context.Context ctxCancel context.CancelFunc + tmpDir string weavelet *protos.EnvelopeInfo config *protos.AppConfig conn *conn.EnvelopeConn // conn to weavelet cmd *pipe.Cmd // command that started the weavelet stdoutPipe io.ReadCloser // stdout pipe from the weavelet stderrPipe io.ReadCloser // stderr pipe from the weavelet + controller control.Controller // Stub that talks to the weavelet controller mu sync.Mutex // guards the following fields profiling bool // are we currently collecting a profile? } +// Options contains optional arguments for the envelope. +type Options struct { + // Logger is used for logging internal messages. If nil, a default logger is used. + Logger *slog.Logger + + // Tracer is used for tracing internal calls. If nil, internal calls are not traced. + Tracer trace.Tracer +} + // NewEnvelope creates a new envelope, starting a weavelet subprocess and // establishing a bidirectional connection with it. The weavelet process can be // stopped at any time by canceling the passed-in context. // // You can issue RPCs *to* the weavelet using the returned Envelope. To start // receiving messages *from* the weavelet, call [Serve]. -func NewEnvelope(ctx context.Context, wlet *protos.EnvelopeInfo, config *protos.AppConfig) (*Envelope, error) { +func NewEnvelope(ctx context.Context, wlet *protos.EnvelopeInfo, config *protos.AppConfig, options Options) (*Envelope, error) { ctx, cancel := context.WithCancel(ctx) + defer func() { cancel() }() // cancel may be changed below if we want to delay it + + if options.Logger == nil { + options.Logger = slog.Default() + } + + // Make a temporary directory for unix domain sockets. + tmpDir, err := runtime.NewTempDir() + if err != nil { + return nil, err + } + runtime.OnExitSignal(func() { os.RemoveAll(tmpDir) }) // Cleanup when process exits + + // Arrange to delete tmpDir if this function returns an error. + removeDir := true // Cleared on a successful return + defer func() { + if removeDir { + os.RemoveAll(tmpDir) + } + }() + + wlet = protomsg.Clone(wlet) + wlet.ControlSocket = deployers.NewUnixSocketPath(tmpDir) + controller, err := getController(ctx, wlet.ControlSocket, options) + if err != nil { + return nil, err + } e := &Envelope{ - ctx: ctx, - ctxCancel: cancel, - weavelet: wlet, - config: config, + ctx: ctx, + ctxCancel: cancel, + tmpDir: tmpDir, + weavelet: wlet, + config: config, + controller: controller, } // Form the weavelet command. @@ -184,6 +234,9 @@ func NewEnvelope(ctx context.Context, wlet *protos.EnvelopeInfo, config *protos. e.conn = conn e.stdoutPipe = outpipe e.stderrPipe = errpipe + + removeDir = false // Serve() is now responsible for deletion + cancel = func() {} // Delay real context cancellation return e, nil } @@ -193,6 +246,9 @@ func NewEnvelope(ctx context.Context, wlet *protos.EnvelopeInfo, config *protos. // the connection by cancelling the context passed to [NewEnvelope]. This // method never returns a non-nil error. func (e *Envelope) Serve(h EnvelopeHandler) error { + // Cleanup when we are done with the envelope. + defer os.RemoveAll(e.tmpDir) + var running errgroup.Group var stopErr error @@ -298,7 +354,11 @@ func (e *Envelope) GetLoad() (*protos.LoadReport, error) { // UpdateComponents updates the weavelet with the latest set of components it // should be running. func (e *Envelope) UpdateComponents(components []string) error { - return e.conn.UpdateComponentsRPC(components) + req := &protos.UpdateComponentsRequest{ + Components: components, + } + _, err := e.controller.UpdateComponents(context.TODO(), req) + return err } // UpdateRoutingInfo updates the weavelet with a component's most recent @@ -341,3 +401,24 @@ func dropNewline(line []byte) []byte { } return line } + +// getController returns a controller that forwards calls to the controller component +// in the weavelet at the specified socket. +func getController(ctx context.Context, socket string, options Options) (control.Controller, error) { + const controllerName = "github.com/ServiceWeaver/weaver/controller" + controllerReg, ok := codegen.Find(controllerName) + if !ok { + return nil, fmt.Errorf("controller component (%s) not found", controllerName) + } + controlEndpoint := call.Unix(socket) + resolver := call.NewConstantResolver(controlEndpoint) + opts := call.ClientOptions{Logger: options.Logger} + conn, err := call.Connect(ctx, resolver, opts) + if err != nil { + return nil, err + } + // We skip waitUntilReady() and rely on automatic retries of methods + stub := call.NewStub(controllerName, controllerReg, conn, options.Tracer, 0) + obj := controllerReg.ClientStubFn(stub, "envelope") + return obj.(control.Controller), nil +} diff --git a/runtime/envelope/envelope_test.go b/runtime/envelope/envelope_test.go index 541cb8793..37e17882d 100644 --- a/runtime/envelope/envelope_test.go +++ b/runtime/envelope/envelope_test.go @@ -195,7 +195,7 @@ func (*handlerForTest) VerifyServerCertificate(context.Context, *protos.VerifySe func TestWeaveletExit(t *testing.T) { ctx := context.Background() wlet, config := wlet("/usr/bin/env", "bash", "-c", `echo "hello from stdout"; echo "hello from stderr" >&2 && exit 1`) - _, err := NewEnvelope(ctx, wlet, config) + _, err := NewEnvelope(ctx, wlet, config, Options{}) if err == nil { t.Fatal("expected error") } @@ -227,7 +227,7 @@ func TestStartStop(t *testing.T) { var started atomic.Bool args := append([]string{test.subcommand}, test.args...) wlet, config := wlet(executable, args...) - e, err := NewEnvelope(ctx, wlet, config) + e, err := NewEnvelope(ctx, wlet, config, Options{}) if err != nil { t.Fatal(err) } @@ -290,7 +290,7 @@ func TestBigPrints(t *testing.T) { n := 10000 wlet, config := wlet(executable, "bigprint", strconv.Itoa(n)) - e, err := NewEnvelope(ctx, wlet, config) + e, err := NewEnvelope(ctx, wlet, config, Options{}) if err != nil { t.Fatal(err) } @@ -312,7 +312,7 @@ func TestBigPrints(t *testing.T) { func TestCancel(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) wlet, config := wlet(executable, "loop") - e, err := NewEnvelope(ctx, wlet, config) + e, err := NewEnvelope(ctx, wlet, config, Options{}) if err != nil { t.Fatal(err) } @@ -385,7 +385,7 @@ func writeTraces(conn *conn.WeaveletConn) error { func TestTraces(t *testing.T) { wlet, config := wlet(executable, "writetraces") ctx, cancel := context.WithCancel(context.Background()) - e, err := NewEnvelope(ctx, wlet, config) + e, err := NewEnvelope(ctx, wlet, config, Options{}) if err != nil { t.Fatal(err) } @@ -428,7 +428,7 @@ func TestRPCBeforeServe(t *testing.T) { // weavelet-initiated messages. ctx, cancel := context.WithCancel(context.Background()) wlet, config := wlet(executable, "writetraces") - e, err := NewEnvelope(ctx, wlet, config) + e, err := NewEnvelope(ctx, wlet, config, Options{}) if err != nil { t.Fatal(err) } @@ -467,7 +467,7 @@ func TestRPCBeforeServe(t *testing.T) { func startEnvelope(ctx context.Context, t *testing.T) (*Envelope, chan error) { wlet, config := wlet(executable, "serve_conn") - e, err := NewEnvelope(ctx, wlet, config) + e, err := NewEnvelope(ctx, wlet, config, Options{}) if err != nil { t.Fatal(err) } diff --git a/runtime/protos/runtime.pb.go b/runtime/protos/runtime.pb.go index 2b203ee35..c298d01c3 100644 --- a/runtime/protos/runtime.pb.go +++ b/runtime/protos/runtime.pb.go @@ -735,8 +735,11 @@ type EnvelopeInfo struct { // an arbitrary port (don't set the port number). However, for deployers where // listeners are prestarted (e.g., Kubernetes deployers), the port number // should be propagated from the deployer. - InternalAddress string `protobuf:"bytes,10,opt,name=internal_address,json=internalAddress,proto3" json:"internal_address,omitempty"` - Redirects []*EnvelopeInfo_Redirect `protobuf:"bytes,12,rep,name=redirects,proto3" json:"redirects,omitempty"` + InternalAddress string `protobuf:"bytes,10,opt,name=internal_address,json=internalAddress,proto3" json:"internal_address,omitempty"` + // Unix domain socket path where weavelet should serve Control component + // method calls. + ControlSocket string `protobuf:"bytes,13,opt,name=control_socket,json=controlSocket,proto3" json:"control_socket,omitempty"` + Redirects []*EnvelopeInfo_Redirect `protobuf:"bytes,12,rep,name=redirects,proto3" json:"redirects,omitempty"` } func (x *EnvelopeInfo) Reset() { @@ -820,6 +823,13 @@ func (x *EnvelopeInfo) GetInternalAddress() string { return "" } +func (x *EnvelopeInfo) GetControlSocket() string { + if x != nil { + return x.ControlSocket + } + return "" +} + func (x *EnvelopeInfo) GetRedirects() []*EnvelopeInfo_Redirect { if x != nil { return x.Redirects @@ -4230,7 +4240,7 @@ var file_runtime_protos_runtime_proto_rawDesc = []byte{ 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x1e, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xc7, 0x03, 0x0a, 0x0c, 0x45, 0x6e, 0x76, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xee, 0x03, 0x0a, 0x0c, 0x45, 0x6e, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x70, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x61, 0x70, 0x70, 0x12, 0x23, 0x0a, 0x0d, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, @@ -4245,377 +4255,379 @@ var file_runtime_protos_runtime_proto_rawDesc = []byte{ 0x74, 0x6c, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x6d, 0x74, 0x6c, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x6e, 0x61, 0x6c, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x3c, 0x0a, 0x09, 0x72, 0x65, - 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x73, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, - 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x45, 0x6e, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, - 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x52, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x52, 0x09, 0x72, - 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x73, 0x1a, 0x3b, 0x0a, 0x0d, 0x53, 0x65, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x5a, 0x0a, 0x08, 0x52, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, - 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x12, - 0x16, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x22, 0x56, 0x0a, 0x0c, 0x57, 0x65, 0x61, 0x76, 0x65, 0x6c, 0x65, 0x74, 0x49, 0x6e, 0x66, - 0x6f, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x69, 0x61, 0x6c, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x69, 0x61, 0x6c, 0x41, 0x64, 0x64, 0x72, 0x12, 0x29, - 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x0f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x53, 0x65, 0x6d, 0x56, 0x65, 0x72, - 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x4a, 0x0a, 0x06, 0x53, 0x65, 0x6d, - 0x56, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x05, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x69, 0x6e, - 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x12, - 0x14, 0x0a, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, - 0x70, 0x61, 0x74, 0x63, 0x68, 0x22, 0x12, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x48, 0x65, 0x61, 0x6c, - 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x3f, 0x0a, 0x0e, 0x47, 0x65, 0x74, - 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x2d, 0x0a, 0x06, 0x73, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x72, 0x75, - 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x13, 0x0a, 0x11, 0x47, 0x65, - 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, - 0x40, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x70, - 0x6c, 0x79, 0x12, 0x2d, 0x0a, 0x06, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x4d, 0x65, 0x74, - 0x72, 0x69, 0x63, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x06, 0x75, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x22, 0x64, 0x0a, 0x0c, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x12, 0x26, 0x0a, 0x04, 0x64, 0x65, 0x66, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x12, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, - 0x44, 0x65, 0x66, 0x52, 0x04, 0x64, 0x65, 0x66, 0x73, 0x12, 0x2c, 0x0a, 0x06, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x72, 0x75, 0x6e, 0x74, - 0x69, 0x6d, 0x65, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, - 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x22, 0xf5, 0x01, 0x0a, 0x09, 0x4d, 0x65, 0x74, 0x72, - 0x69, 0x63, 0x44, 0x65, 0x66, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x04, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x03, 0x74, 0x79, 0x70, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x13, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, - 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x54, 0x79, 0x70, 0x65, 0x52, 0x03, 0x74, 0x79, 0x70, - 0x12, 0x12, 0x0a, 0x04, 0x68, 0x65, 0x6c, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x68, 0x65, 0x6c, 0x70, 0x12, 0x36, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x05, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x4d, - 0x65, 0x74, 0x72, 0x69, 0x63, 0x44, 0x65, 0x66, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x16, 0x0a, 0x06, - 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x01, 0x52, 0x06, 0x62, 0x6f, - 0x75, 0x6e, 0x64, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, - 0x4b, 0x0a, 0x0b, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x0e, - 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, - 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x18, 0x03, - 0x20, 0x03, 0x28, 0x04, 0x52, 0x06, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x22, 0xad, 0x02, 0x0a, - 0x0e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x12, - 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x69, 0x64, 0x12, - 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x03, 0x74, 0x79, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x13, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, - 0x63, 0x54, 0x79, 0x70, 0x65, 0x52, 0x03, 0x74, 0x79, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x65, - 0x6c, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x65, 0x6c, 0x70, 0x12, 0x3b, - 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, - 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x53, - 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x62, - 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x01, 0x52, 0x06, 0x62, 0x6f, 0x75, - 0x6e, 0x64, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x07, 0x20, 0x01, - 0x28, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x04, 0x52, 0x06, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x6e, 0x61, 0x6c, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x6f, + 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x5f, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x18, 0x0d, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x53, 0x6f, 0x63, 0x6b, 0x65, + 0x74, 0x12, 0x3c, 0x0a, 0x09, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x73, 0x18, 0x0c, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x45, + 0x6e, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x52, 0x65, 0x64, 0x69, + 0x72, 0x65, 0x63, 0x74, 0x52, 0x09, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x73, 0x1a, + 0x3b, 0x0a, 0x0d, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x10, 0x0a, 0x0e, - 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x37, - 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x27, - 0x0a, 0x04, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x72, + 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x5a, 0x0a, 0x08, + 0x52, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6d, 0x70, + 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6d, + 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x18, + 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x56, 0x0a, 0x0c, 0x57, 0x65, 0x61, 0x76, + 0x65, 0x6c, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x69, 0x61, 0x6c, + 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x69, 0x61, + 0x6c, 0x41, 0x64, 0x64, 0x72, 0x12, 0x29, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, + 0x2e, 0x53, 0x65, 0x6d, 0x56, 0x65, 0x72, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x22, 0x4a, 0x0a, 0x06, 0x53, 0x65, 0x6d, 0x56, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x61, + 0x6a, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x6d, 0x61, 0x6a, 0x6f, 0x72, + 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x22, 0x12, 0x0a, 0x10, + 0x47, 0x65, 0x74, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x22, 0x3f, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x70, + 0x6c, 0x79, 0x12, 0x2d, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x48, 0x65, 0x61, + 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x22, 0x13, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x40, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, + 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x2d, 0x0a, 0x06, 0x75, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x52, 0x06, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x22, 0x64, 0x0a, 0x0c, 0x4d, 0x65, 0x74, 0x72, + 0x69, 0x63, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x26, 0x0a, 0x04, 0x64, 0x65, 0x66, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, + 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x44, 0x65, 0x66, 0x52, 0x04, 0x64, 0x65, 0x66, 0x73, + 0x12, 0x2c, 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x14, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, + 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x22, 0xf5, + 0x01, 0x0a, 0x09, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x44, 0x65, 0x66, 0x12, 0x0e, 0x0a, 0x02, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x12, 0x25, 0x0a, 0x03, 0x74, 0x79, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x13, 0x2e, + 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x54, 0x79, + 0x70, 0x65, 0x52, 0x03, 0x74, 0x79, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x65, 0x6c, 0x70, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x65, 0x6c, 0x70, 0x12, 0x36, 0x0a, 0x06, 0x6c, + 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x44, 0x65, 0x66, 0x2e, + 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, + 0x65, 0x6c, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x18, 0x06, 0x20, + 0x03, 0x28, 0x01, 0x52, 0x06, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, + 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x4b, 0x0a, 0x0b, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x04, 0x52, 0x06, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x73, 0x22, 0xad, 0x02, 0x0a, 0x0e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x53, 0x6e, + 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x03, 0x74, 0x79, + 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x13, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x54, 0x79, 0x70, 0x65, 0x52, 0x03, 0x74, 0x79, + 0x70, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x65, 0x6c, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x68, 0x65, 0x6c, 0x70, 0x12, 0x3b, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, + 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x2e, 0x4c, + 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, + 0x6c, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x18, 0x06, 0x20, 0x03, + 0x28, 0x01, 0x52, 0x06, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x04, + 0x52, 0x06, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, + 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x22, 0x10, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x61, 0x64, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x37, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x61, 0x64, + 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x27, 0x0a, 0x04, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x4c, 0x6f, + 0x61, 0x64, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x04, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0xcf, + 0x03, 0x0a, 0x0a, 0x4c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x34, 0x0a, + 0x05, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x4c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x70, 0x6f, 0x72, - 0x74, 0x52, 0x04, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0xcf, 0x03, 0x0a, 0x0a, 0x4c, 0x6f, 0x61, 0x64, - 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x34, 0x0a, 0x05, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, - 0x4c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x4c, 0x6f, 0x61, 0x64, 0x73, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x05, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x1a, 0x5b, 0x0a, 0x0a, - 0x4c, 0x6f, 0x61, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x37, 0x0a, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x72, 0x75, - 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x4c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x4c, 0x6f, 0x61, 0x64, 0x52, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x5c, 0x0a, 0x0d, 0x43, 0x6f, 0x6d, - 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x4c, 0x6f, 0x61, 0x64, 0x12, 0x31, 0x0a, 0x04, 0x6c, 0x6f, - 0x61, 0x64, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, - 0x6d, 0x65, 0x2e, 0x4c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x53, 0x6c, - 0x69, 0x63, 0x65, 0x4c, 0x6f, 0x61, 0x64, 0x52, 0x04, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x18, 0x0a, - 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, - 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x1a, 0x95, 0x01, 0x0a, 0x09, 0x53, 0x6c, 0x69, 0x63, - 0x65, 0x4c, 0x6f, 0x61, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x65, - 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x65, 0x6e, 0x64, 0x12, 0x12, 0x0a, - 0x04, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x04, 0x6c, 0x6f, 0x61, - 0x64, 0x12, 0x38, 0x0a, 0x06, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x20, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x4c, 0x6f, 0x61, 0x64, - 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x4c, - 0x6f, 0x61, 0x64, 0x52, 0x06, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x73, - 0x69, 0x7a, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x1a, - 0x38, 0x0a, 0x0c, 0x53, 0x75, 0x62, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x4c, 0x6f, 0x61, 0x64, 0x12, - 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, - 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x01, 0x52, 0x04, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0x74, 0x0a, 0x11, 0x47, 0x65, 0x74, - 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x37, - 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x50, - 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x66, - 0x69, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x26, 0x0a, 0x0f, 0x63, 0x70, 0x75, 0x5f, 0x64, - 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x0d, 0x63, 0x70, 0x75, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x73, 0x22, - 0x25, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x70, - 0x6c, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x53, 0x0a, 0x18, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x37, 0x0a, 0x0c, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x6e, - 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, - 0x6d, 0x65, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, - 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x18, 0x0a, 0x16, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, - 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x92, 0x01, 0x0a, 0x0b, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, - 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, - 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, - 0x65, 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x70, - 0x6c, 0x69, 0x63, 0x61, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x70, - 0x6c, 0x69, 0x63, 0x61, 0x73, 0x12, 0x33, 0x0a, 0x0a, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, - 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x72, 0x75, 0x6e, 0x74, - 0x69, 0x6d, 0x65, 0x2e, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x0a, - 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x94, 0x01, 0x0a, 0x0a, 0x41, - 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x31, 0x0a, 0x06, 0x73, 0x6c, 0x69, - 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x72, 0x75, 0x6e, 0x74, - 0x69, 0x6d, 0x65, 0x2e, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x53, - 0x6c, 0x69, 0x63, 0x65, 0x52, 0x06, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, - 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x76, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x1a, 0x39, 0x0a, 0x05, 0x53, 0x6c, 0x69, 0x63, 0x65, 0x12, - 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, - 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, - 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, - 0x73, 0x22, 0x39, 0x0a, 0x17, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6f, - 0x6e, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1e, 0x0a, 0x0a, - 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x0a, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x17, 0x0a, 0x15, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x73, - 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x50, 0x0a, 0x18, 0x41, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, - 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x12, - 0x16, 0x0a, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x64, 0x22, 0x18, 0x0a, 0x16, 0x41, 0x63, 0x74, 0x69, 0x76, - 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6c, - 0x79, 0x22, 0x2f, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, - 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, - 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x22, 0x33, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, - 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x18, 0x0a, - 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, - 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x4d, 0x0a, 0x15, 0x45, 0x78, 0x70, 0x6f, 0x72, - 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, - 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, - 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x50, 0x0a, 0x13, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, - 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x23, 0x0a, - 0x0d, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x41, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x1b, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x53, - 0x65, 0x6c, 0x66, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x3f, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x66, - 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, - 0x12, 0x12, 0x0a, 0x04, 0x63, 0x65, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, - 0x63, 0x65, 0x72, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x3f, 0x0a, 0x1e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, - 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x65, 0x72, 0x74, - 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x09, 0x63, 0x65, - 0x72, 0x74, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x22, 0x3e, 0x0a, 0x1c, 0x56, 0x65, 0x72, 0x69, 0x66, - 0x79, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, - 0x74, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x70, 0x6f, - 0x6e, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6d, - 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x6a, 0x0a, 0x1e, 0x56, 0x65, 0x72, 0x69, 0x66, - 0x79, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, - 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x65, 0x72, - 0x74, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x09, 0x63, - 0x65, 0x72, 0x74, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x12, 0x29, 0x0a, 0x10, 0x74, 0x61, 0x72, 0x67, - 0x65, 0x74, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, - 0x65, 0x6e, 0x74, 0x22, 0x1e, 0x0a, 0x1c, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x53, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, - 0x70, 0x6c, 0x79, 0x22, 0xef, 0x01, 0x0a, 0x08, 0x4c, 0x6f, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x12, 0x10, 0x0a, 0x03, 0x61, 0x70, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x61, - 0x70, 0x70, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, - 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x6f, - 0x64, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x12, 0x1f, - 0x0a, 0x0b, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x10, 0x52, 0x0a, 0x74, 0x69, 0x6d, 0x65, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x12, - 0x14, 0x0a, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x07, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, - 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x10, 0x0a, - 0x03, 0x6d, 0x73, 0x67, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x12, - 0x14, 0x0a, 0x05, 0x61, 0x74, 0x74, 0x72, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, - 0x61, 0x74, 0x74, 0x72, 0x73, 0x22, 0x3c, 0x0a, 0x0d, 0x4c, 0x6f, 0x67, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x2b, 0x0a, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, - 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, - 0x65, 0x2e, 0x4c, 0x6f, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x65, 0x6e, 0x74, 0x72, - 0x69, 0x65, 0x73, 0x22, 0x2f, 0x0a, 0x0a, 0x54, 0x72, 0x61, 0x63, 0x65, 0x53, 0x70, 0x61, 0x6e, - 0x73, 0x12, 0x21, 0x0a, 0x04, 0x73, 0x70, 0x61, 0x6e, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x0d, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x52, 0x04, - 0x73, 0x70, 0x61, 0x6e, 0x22, 0xb9, 0x10, 0x0a, 0x04, 0x53, 0x70, 0x61, 0x6e, 0x12, 0x12, 0x0a, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x72, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x07, 0x74, 0x72, 0x61, 0x63, 0x65, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, - 0x73, 0x70, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x73, - 0x70, 0x61, 0x6e, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x0e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, - 0x73, 0x70, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x70, - 0x61, 0x72, 0x65, 0x6e, 0x74, 0x53, 0x70, 0x61, 0x6e, 0x49, 0x64, 0x12, 0x26, 0x0a, 0x04, 0x6b, - 0x69, 0x6e, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x72, 0x75, 0x6e, 0x74, - 0x69, 0x6d, 0x65, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x2e, 0x4b, 0x69, 0x6e, 0x64, 0x52, 0x04, 0x6b, - 0x69, 0x6e, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x6d, 0x69, 0x63, - 0x72, 0x6f, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x10, 0x52, 0x0b, 0x73, 0x74, 0x61, 0x72, 0x74, - 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x6e, 0x64, 0x5f, 0x6d, 0x69, - 0x63, 0x72, 0x6f, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x10, 0x52, 0x09, 0x65, 0x6e, 0x64, 0x4d, - 0x69, 0x63, 0x72, 0x6f, 0x73, 0x12, 0x37, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, - 0x74, 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x75, 0x6e, 0x74, - 0x69, 0x6d, 0x65, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, - 0x74, 0x65, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x28, - 0x0a, 0x05, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, - 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x2e, 0x4c, 0x69, 0x6e, - 0x6b, 0x52, 0x05, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x12, 0x2b, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, - 0x74, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, - 0x6d, 0x65, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x65, - 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x2c, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, - 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, - 0x53, 0x70, 0x61, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x12, 0x29, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x12, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x53, 0x70, 0x61, - 0x6e, 0x2e, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x2f, - 0x0a, 0x07, 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x15, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x2e, 0x4c, - 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x52, 0x07, 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x12, - 0x32, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x16, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x53, 0x70, 0x61, 0x6e, - 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x12, 0x36, 0x0a, 0x17, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x5f, 0x61, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0e, - 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x41, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2c, 0x0a, 0x12, 0x64, - 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x5f, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, - 0x4c, 0x69, 0x6e, 0x6b, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2e, 0x0a, 0x13, 0x64, 0x72, 0x6f, - 0x70, 0x70, 0x65, 0x64, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x18, 0x10, 0x20, 0x01, 0x28, 0x03, 0x52, 0x11, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x28, 0x0a, 0x10, 0x63, 0x68, 0x69, - 0x6c, 0x64, 0x5f, 0x73, 0x70, 0x61, 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x11, 0x20, - 0x01, 0x28, 0x03, 0x52, 0x0e, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x53, 0x70, 0x61, 0x6e, 0x43, 0x6f, - 0x75, 0x6e, 0x74, 0x1a, 0x8a, 0x04, 0x0a, 0x09, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, - 0x6b, 0x65, 0x79, 0x12, 0x33, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x53, 0x70, 0x61, - 0x6e, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x2e, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0xb5, 0x03, 0x0a, 0x05, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x12, 0x36, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x22, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x2e, - 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x2e, - 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x03, 0x6e, 0x75, - 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x48, 0x00, 0x52, 0x03, 0x6e, 0x75, 0x6d, 0x12, 0x12, - 0x0a, 0x03, 0x73, 0x74, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x03, 0x73, - 0x74, 0x72, 0x12, 0x3e, 0x0a, 0x04, 0x6e, 0x75, 0x6d, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x28, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x2e, - 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x2e, - 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x00, 0x52, 0x04, 0x6e, 0x75, - 0x6d, 0x73, 0x12, 0x3e, 0x0a, 0x04, 0x73, 0x74, 0x72, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x28, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x2e, - 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x2e, - 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x00, 0x52, 0x04, 0x73, 0x74, - 0x72, 0x73, 0x1a, 0x20, 0x0a, 0x0a, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, - 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x75, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x04, 0x52, 0x04, - 0x6e, 0x75, 0x6d, 0x73, 0x1a, 0x20, 0x0a, 0x0a, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4c, 0x69, - 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x74, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x04, 0x73, 0x74, 0x72, 0x73, 0x22, 0x7f, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, - 0x0a, 0x07, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x42, - 0x4f, 0x4f, 0x4c, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x49, 0x4e, 0x54, 0x36, 0x34, 0x10, 0x02, - 0x12, 0x0b, 0x0a, 0x07, 0x46, 0x4c, 0x4f, 0x41, 0x54, 0x36, 0x34, 0x10, 0x03, 0x12, 0x0a, 0x0a, - 0x06, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x04, 0x12, 0x0c, 0x0a, 0x08, 0x42, 0x4f, 0x4f, - 0x4c, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x05, 0x12, 0x0d, 0x0a, 0x09, 0x49, 0x4e, 0x54, 0x36, 0x34, - 0x4c, 0x49, 0x53, 0x54, 0x10, 0x06, 0x12, 0x0f, 0x0a, 0x0b, 0x46, 0x4c, 0x4f, 0x41, 0x54, 0x36, - 0x34, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x07, 0x12, 0x0e, 0x0a, 0x0a, 0x53, 0x54, 0x52, 0x49, 0x4e, - 0x47, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x08, 0x42, 0x07, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x1a, 0xab, 0x01, 0x0a, 0x04, 0x4c, 0x69, 0x6e, 0x6b, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x72, 0x61, - 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x74, 0x72, 0x61, - 0x63, 0x65, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x73, 0x70, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x73, 0x70, 0x61, 0x6e, 0x49, 0x64, 0x12, 0x37, 0x0a, - 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x53, 0x70, 0x61, 0x6e, - 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, - 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x36, 0x0a, 0x17, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, - 0x64, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, - 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x1a, 0xad, - 0x01, 0x0a, 0x05, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, - 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x10, 0x52, 0x0a, 0x74, 0x69, 0x6d, 0x65, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x12, 0x37, 0x0a, - 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x53, 0x70, 0x61, 0x6e, - 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, - 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x36, 0x0a, 0x17, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, - 0x64, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, - 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x1a, 0x73, - 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2d, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, - 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x43, 0x6f, 0x64, - 0x65, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x24, 0x0a, - 0x04, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x09, 0x0a, 0x05, 0x55, 0x4e, 0x53, 0x45, 0x54, 0x10, 0x00, - 0x12, 0x09, 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x01, 0x12, 0x06, 0x0a, 0x02, 0x4f, - 0x4b, 0x10, 0x02, 0x1a, 0x54, 0x0a, 0x05, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x63, - 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, - 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x55, 0x72, 0x6c, 0x1a, 0x56, 0x0a, 0x07, 0x4c, 0x69, 0x62, - 0x72, 0x61, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x75, 0x72, 0x6c, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x55, 0x72, - 0x6c, 0x1a, 0x62, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x1d, 0x0a, - 0x0a, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x09, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x55, 0x72, 0x6c, 0x12, 0x37, 0x0a, 0x0a, - 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, + 0x74, 0x2e, 0x4c, 0x6f, 0x61, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x05, 0x6c, 0x6f, + 0x61, 0x64, 0x73, 0x1a, 0x5b, 0x0a, 0x0a, 0x4c, 0x6f, 0x61, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x6b, 0x65, 0x79, 0x12, 0x37, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x4c, 0x6f, 0x61, + 0x64, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, + 0x74, 0x4c, 0x6f, 0x61, 0x64, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, + 0x1a, 0x5c, 0x0a, 0x0d, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x4c, 0x6f, 0x61, + 0x64, 0x12, 0x31, 0x0a, 0x04, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x1d, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x4c, 0x6f, 0x61, 0x64, 0x52, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x53, 0x6c, 0x69, 0x63, 0x65, 0x4c, 0x6f, 0x61, 0x64, 0x52, 0x04, + 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x1a, 0x95, + 0x01, 0x0a, 0x09, 0x53, 0x6c, 0x69, 0x63, 0x65, 0x4c, 0x6f, 0x61, 0x64, 0x12, 0x14, 0x0a, 0x05, + 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x73, 0x74, 0x61, + 0x72, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x03, 0x65, 0x6e, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x01, 0x52, 0x04, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x38, 0x0a, 0x06, 0x73, 0x70, 0x6c, 0x69, + 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x4c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x53, 0x75, + 0x62, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x4c, 0x6f, 0x61, 0x64, 0x52, 0x06, 0x73, 0x70, 0x6c, 0x69, + 0x74, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x1a, 0x38, 0x0a, 0x0c, 0x53, 0x75, 0x62, 0x73, 0x6c, 0x69, + 0x63, 0x65, 0x4c, 0x6f, 0x61, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x12, 0x0a, 0x04, + 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x04, 0x6c, 0x6f, 0x61, 0x64, + 0x22, 0x74, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x37, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, + 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x54, 0x79, 0x70, + 0x65, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x26, + 0x0a, 0x0f, 0x63, 0x70, 0x75, 0x5f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, + 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x63, 0x70, 0x75, 0x44, 0x75, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x73, 0x22, 0x25, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, + 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, + 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x53, 0x0a, + 0x18, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x49, 0x6e, + 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x37, 0x0a, 0x0c, 0x72, 0x6f, 0x75, + 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x14, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, + 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x49, 0x6e, + 0x66, 0x6f, 0x22, 0x18, 0x0a, 0x16, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x75, 0x74, + 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x92, 0x01, 0x0a, + 0x0b, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1c, 0x0a, 0x09, + 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x18, 0x03, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x12, 0x33, 0x0a, 0x0a, + 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x13, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x41, 0x73, 0x73, 0x69, 0x67, + 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x0a, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, + 0x74, 0x22, 0x94, 0x01, 0x0a, 0x0a, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, + 0x12, 0x31, 0x0a, 0x06, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x19, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x41, 0x73, 0x73, 0x69, 0x67, + 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x53, 0x6c, 0x69, 0x63, 0x65, 0x52, 0x06, 0x73, 0x6c, 0x69, + 0x63, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x1a, 0x39, 0x0a, + 0x05, 0x53, 0x6c, 0x69, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x1a, 0x0a, 0x08, + 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, + 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x22, 0x39, 0x0a, 0x17, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, + 0x6e, 0x74, 0x73, 0x22, 0x17, 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6d, + 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x50, 0x0a, 0x18, + 0x41, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, + 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6d, 0x70, + 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6d, + 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x64, 0x22, 0x18, + 0x0a, 0x16, 0x41, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, + 0x65, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x2f, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x4c, + 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x33, 0x0a, 0x17, 0x47, 0x65, 0x74, + 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, + 0x65, 0x70, 0x6c, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x4d, + 0x0a, 0x15, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x69, 0x73, 0x74, 0x65, + 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x69, 0x73, 0x74, 0x65, + 0x6e, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x50, 0x0a, + 0x13, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x52, + 0x65, 0x70, 0x6c, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x5f, 0x61, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x72, 0x6f, + 0x78, 0x79, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, + 0x1b, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x66, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x3f, 0x0a, 0x17, + 0x47, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x66, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x65, 0x72, 0x74, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x63, 0x65, 0x72, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6b, + 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x3f, 0x0a, + 0x1e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x1d, 0x0a, 0x0a, 0x63, 0x65, 0x72, 0x74, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0c, 0x52, 0x09, 0x63, 0x65, 0x72, 0x74, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x22, 0x3e, + 0x0a, 0x1c, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x65, + 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x1e, + 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x6a, + 0x0a, 0x1e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x65, + 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x65, 0x72, 0x74, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0c, 0x52, 0x09, 0x63, 0x65, 0x72, 0x74, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x12, + 0x29, 0x0a, 0x10, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, + 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, + 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x22, 0x1e, 0x0a, 0x1c, 0x56, 0x65, + 0x72, 0x69, 0x66, 0x79, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0xef, 0x01, 0x0a, 0x08, 0x4c, + 0x6f, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x70, 0x70, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x61, 0x70, 0x70, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, + 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6d, 0x69, + 0x63, 0x72, 0x6f, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x10, 0x52, 0x0a, 0x74, 0x69, 0x6d, 0x65, + 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x12, 0x0a, 0x04, + 0x66, 0x69, 0x6c, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, + 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, + 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x09, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x74, 0x74, 0x72, 0x73, 0x18, + 0x0a, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x61, 0x74, 0x74, 0x72, 0x73, 0x22, 0x3c, 0x0a, 0x0d, + 0x4c, 0x6f, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x2b, 0x0a, + 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x4c, 0x6f, 0x67, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x52, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x22, 0x2f, 0x0a, 0x0a, 0x54, 0x72, + 0x61, 0x63, 0x65, 0x53, 0x70, 0x61, 0x6e, 0x73, 0x12, 0x21, 0x0a, 0x04, 0x73, 0x70, 0x61, 0x6e, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, + 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x52, 0x04, 0x73, 0x70, 0x61, 0x6e, 0x22, 0xb9, 0x10, 0x0a, 0x04, + 0x53, 0x70, 0x61, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x72, 0x61, 0x63, + 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x74, 0x72, 0x61, 0x63, + 0x65, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x73, 0x70, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x73, 0x70, 0x61, 0x6e, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x0e, + 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x70, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x53, 0x70, 0x61, 0x6e, + 0x49, 0x64, 0x12, 0x26, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x12, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x2e, + 0x4b, 0x69, 0x6e, 0x64, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x74, + 0x61, 0x72, 0x74, 0x5f, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x10, + 0x52, 0x0b, 0x73, 0x74, 0x61, 0x72, 0x74, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x12, 0x1d, 0x0a, + 0x0a, 0x65, 0x6e, 0x64, 0x5f, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x10, 0x52, 0x09, 0x65, 0x6e, 0x64, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x12, 0x37, 0x0a, 0x0a, + 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x73, 0x22, 0x59, 0x0a, 0x04, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x0f, 0x0a, - 0x0b, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0c, - 0x0a, 0x08, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x4e, 0x41, 0x4c, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, - 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x4c, 0x49, 0x45, - 0x4e, 0x54, 0x10, 0x03, 0x12, 0x0c, 0x0a, 0x08, 0x50, 0x52, 0x4f, 0x44, 0x55, 0x43, 0x45, 0x52, - 0x10, 0x04, 0x12, 0x0c, 0x0a, 0x08, 0x43, 0x4f, 0x4e, 0x53, 0x55, 0x4d, 0x45, 0x52, 0x10, 0x05, - 0x2a, 0x47, 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0b, 0x0a, - 0x07, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x59, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x55, 0x4e, - 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x59, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x54, 0x45, 0x52, - 0x4d, 0x49, 0x4e, 0x41, 0x54, 0x45, 0x44, 0x10, 0x03, 0x2a, 0x40, 0x0a, 0x0a, 0x4d, 0x65, 0x74, - 0x72, 0x69, 0x63, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x49, 0x4e, 0x56, 0x41, 0x4c, - 0x49, 0x44, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x10, - 0x01, 0x12, 0x09, 0x0a, 0x05, 0x47, 0x41, 0x55, 0x47, 0x45, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, - 0x48, 0x49, 0x53, 0x54, 0x4f, 0x47, 0x52, 0x41, 0x4d, 0x10, 0x03, 0x2a, 0x31, 0x0a, 0x0b, 0x50, - 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0f, 0x0a, 0x0b, 0x55, 0x6e, - 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x48, - 0x65, 0x61, 0x70, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, 0x43, 0x50, 0x55, 0x10, 0x02, 0x42, 0x30, - 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x57, 0x65, 0x61, 0x76, 0x65, 0x72, 0x2f, 0x77, 0x65, 0x61, 0x76, 0x65, - 0x72, 0x2f, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x28, 0x0a, 0x05, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x18, 0x09, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x53, + 0x70, 0x61, 0x6e, 0x2e, 0x4c, 0x69, 0x6e, 0x6b, 0x52, 0x05, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x12, + 0x2b, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x13, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x2e, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x2c, 0x0a, 0x06, + 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x72, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x29, 0x0a, 0x05, 0x73, 0x63, + 0x6f, 0x70, 0x65, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x2e, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x52, 0x05, + 0x73, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x2f, 0x0a, 0x07, 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, + 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, + 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x2e, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x52, 0x07, 0x6c, + 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x12, 0x32, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x36, 0x0a, 0x17, 0x64, 0x72, + 0x6f, 0x70, 0x70, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, 0x64, 0x72, 0x6f, + 0x70, 0x70, 0x65, 0x64, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x43, 0x6f, 0x75, + 0x6e, 0x74, 0x12, 0x2c, 0x0a, 0x12, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x5f, 0x6c, 0x69, + 0x6e, 0x6b, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, + 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x4c, 0x69, 0x6e, 0x6b, 0x43, 0x6f, 0x75, 0x6e, 0x74, + 0x12, 0x2e, 0x0a, 0x13, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x5f, 0x65, 0x76, 0x65, 0x6e, + 0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x10, 0x20, 0x01, 0x28, 0x03, 0x52, 0x11, 0x64, + 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, + 0x12, 0x28, 0x0a, 0x10, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x5f, 0x73, 0x70, 0x61, 0x6e, 0x5f, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x11, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x63, 0x68, 0x69, 0x6c, + 0x64, 0x53, 0x70, 0x61, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x1a, 0x8a, 0x04, 0x0a, 0x09, 0x41, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x33, 0x0a, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x1a, + 0xb5, 0x03, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x36, 0x0a, 0x04, 0x74, 0x79, 0x70, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, + 0x65, 0x12, 0x12, 0x0a, 0x03, 0x6e, 0x75, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x48, 0x00, + 0x52, 0x03, 0x6e, 0x75, 0x6d, 0x12, 0x12, 0x0a, 0x03, 0x73, 0x74, 0x72, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x48, 0x00, 0x52, 0x03, 0x73, 0x74, 0x72, 0x12, 0x3e, 0x0a, 0x04, 0x6e, 0x75, 0x6d, + 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x2e, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x4c, 0x69, 0x73, + 0x74, 0x48, 0x00, 0x52, 0x04, 0x6e, 0x75, 0x6d, 0x73, 0x12, 0x3e, 0x0a, 0x04, 0x73, 0x74, 0x72, + 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, + 0x74, 0x48, 0x00, 0x52, 0x04, 0x73, 0x74, 0x72, 0x73, 0x1a, 0x20, 0x0a, 0x0a, 0x4e, 0x75, 0x6d, + 0x62, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x75, 0x6d, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x04, 0x52, 0x04, 0x6e, 0x75, 0x6d, 0x73, 0x1a, 0x20, 0x0a, 0x0a, 0x53, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x74, 0x72, + 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x73, 0x74, 0x72, 0x73, 0x22, 0x7f, 0x0a, + 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, + 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x42, 0x4f, 0x4f, 0x4c, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, + 0x49, 0x4e, 0x54, 0x36, 0x34, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x46, 0x4c, 0x4f, 0x41, 0x54, + 0x36, 0x34, 0x10, 0x03, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x04, + 0x12, 0x0c, 0x0a, 0x08, 0x42, 0x4f, 0x4f, 0x4c, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x05, 0x12, 0x0d, + 0x0a, 0x09, 0x49, 0x4e, 0x54, 0x36, 0x34, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x06, 0x12, 0x0f, 0x0a, + 0x0b, 0x46, 0x4c, 0x4f, 0x41, 0x54, 0x36, 0x34, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x07, 0x12, 0x0e, + 0x0a, 0x0a, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x08, 0x42, 0x07, + 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0xab, 0x01, 0x0a, 0x04, 0x4c, 0x69, 0x6e, 0x6b, + 0x12, 0x19, 0x0a, 0x08, 0x74, 0x72, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x07, 0x74, 0x72, 0x61, 0x63, 0x65, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x73, + 0x70, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x73, 0x70, + 0x61, 0x6e, 0x49, 0x64, 0x12, 0x37, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x36, 0x0a, + 0x17, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, + 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x1a, 0xad, 0x01, 0x0a, 0x05, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, + 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6d, 0x69, 0x63, 0x72, + 0x6f, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x10, 0x52, 0x0a, 0x74, 0x69, 0x6d, 0x65, 0x4d, 0x69, + 0x63, 0x72, 0x6f, 0x73, 0x12, 0x37, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x36, 0x0a, + 0x17, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, + 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x1a, 0x73, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, + 0x2d, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, + 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x2e, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x2e, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x14, + 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x22, 0x24, 0x0a, 0x04, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x09, 0x0a, 0x05, + 0x55, 0x4e, 0x53, 0x45, 0x54, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52, + 0x10, 0x01, 0x12, 0x06, 0x0a, 0x02, 0x4f, 0x4b, 0x10, 0x02, 0x1a, 0x54, 0x0a, 0x05, 0x53, 0x63, + 0x6f, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x75, 0x72, 0x6c, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x55, 0x72, 0x6c, + 0x1a, 0x56, 0x0a, 0x07, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, + 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x63, 0x68, + 0x65, 0x6d, 0x61, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x55, 0x72, 0x6c, 0x1a, 0x62, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x75, + 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, + 0x55, 0x72, 0x6c, 0x12, 0x37, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x22, 0x59, 0x0a, 0x04, + 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x0f, 0x0a, 0x0b, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, + 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x4e, 0x41, + 0x4c, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x10, 0x02, 0x12, + 0x0a, 0x0a, 0x06, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x10, 0x03, 0x12, 0x0c, 0x0a, 0x08, 0x50, + 0x52, 0x4f, 0x44, 0x55, 0x43, 0x45, 0x52, 0x10, 0x04, 0x12, 0x0c, 0x0a, 0x08, 0x43, 0x4f, 0x4e, + 0x53, 0x55, 0x4d, 0x45, 0x52, 0x10, 0x05, 0x2a, 0x47, 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x6c, 0x74, + 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, + 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x59, 0x10, + 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x55, 0x4e, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x59, 0x10, 0x02, + 0x12, 0x0e, 0x0a, 0x0a, 0x54, 0x45, 0x52, 0x4d, 0x49, 0x4e, 0x41, 0x54, 0x45, 0x44, 0x10, 0x03, + 0x2a, 0x40, 0x0a, 0x0a, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, + 0x0a, 0x07, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x43, + 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x47, 0x41, 0x55, 0x47, + 0x45, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x48, 0x49, 0x53, 0x54, 0x4f, 0x47, 0x52, 0x41, 0x4d, + 0x10, 0x03, 0x2a, 0x31, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x54, 0x79, 0x70, + 0x65, 0x12, 0x0f, 0x0a, 0x0b, 0x55, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, + 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x65, 0x61, 0x70, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, + 0x43, 0x50, 0x55, 0x10, 0x02, 0x42, 0x30, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x57, 0x65, 0x61, 0x76, 0x65, + 0x72, 0x2f, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x2f, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, + 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/runtime/protos/runtime.proto b/runtime/protos/runtime.proto index 4b720b8ab..2cfe141d9 100644 --- a/runtime/protos/runtime.proto +++ b/runtime/protos/runtime.proto @@ -169,6 +169,10 @@ message EnvelopeInfo { // should be propagated from the deployer. string internal_address = 10; + // Unix domain socket path where weavelet should serve Control component + // method calls. + string control_socket = 13; + // A redirect entry instructs the weavelet to direct calls made to component // to be instead sent to the component named target at the specified address. message Redirect { diff --git a/runtime/protos/version_test.go b/runtime/protos/version_test.go index a80780ec4..42fc0baef 100644 --- a/runtime/protos/version_test.go +++ b/runtime/protos/version_test.go @@ -45,7 +45,7 @@ func TestDeployerVersion(t *testing.T) { got := fmt.Sprintf("%x", h.Sum(nil)) // If runtime.proto has changed, the deployer API version may need updating. - const want = "0aeca2daccf70c392639a8c407a030cfe5e4f38b169d54cd5cf24cdd2dc93016" + const want = "3581f94362e6818a7c0ca62d3a1de384ecdc1792275f10a387cb43e2e10a79b2" if got != want { t.Fatalf(`Unexpected SHA-256 hash of runtime.proto: got %s, want %s. If this change is meaningful, REMEMBER TO UPDATE THE DEPLOYER API VERSION in runtime/version/version.go.`, got, want) } diff --git a/runtime/weavelet.go b/runtime/weavelet.go index 7486542d2..97a34d425 100644 --- a/runtime/weavelet.go +++ b/runtime/weavelet.go @@ -37,5 +37,8 @@ func CheckEnvelopeInfo(w *protos.EnvelopeInfo) error { if w.Id == "" { return fmt.Errorf("EnvelopeInfo: missing weavelet id") } + if w.ControlSocket == "" { + return fmt.Errorf("EnvelopeInfo: missing control socket") + } return nil } diff --git a/weaver_gen.go b/weaver_gen.go index 32529b4b1..2787a0951 100644 --- a/weaver_gen.go +++ b/weaver_gen.go @@ -32,13 +32,33 @@ func init() { }, RefData: "", }) + codegen.Register(codegen.Registration{ + Name: "github.com/ServiceWeaver/weaver/controller", + Iface: reflect.TypeOf((*controller)(nil)).Elem(), + Impl: reflect.TypeOf(noopController{}), + LocalStubFn: func(impl any, caller string, tracer trace.Tracer) any { + return controller_local_stub{impl: impl.(controller), tracer: tracer, getHealthMetrics: codegen.MethodMetricsFor(codegen.MethodLabels{Caller: caller, Component: "github.com/ServiceWeaver/weaver/controller", Method: "GetHealth", Remote: false}), updateComponentsMetrics: codegen.MethodMetricsFor(codegen.MethodLabels{Caller: caller, Component: "github.com/ServiceWeaver/weaver/controller", Method: "UpdateComponents", Remote: false})} + }, + ClientStubFn: func(stub codegen.Stub, caller string) any { + return controller_client_stub{stub: stub, getHealthMetrics: codegen.MethodMetricsFor(codegen.MethodLabels{Caller: caller, Component: "github.com/ServiceWeaver/weaver/controller", Method: "GetHealth", Remote: true}), updateComponentsMetrics: codegen.MethodMetricsFor(codegen.MethodLabels{Caller: caller, Component: "github.com/ServiceWeaver/weaver/controller", Method: "UpdateComponents", Remote: true})} + }, + ServerStubFn: func(impl any, addLoad func(uint64, float64)) codegen.Server { + return controller_server_stub{impl: impl.(controller), addLoad: addLoad} + }, + ReflectStubFn: func(caller func(string, context.Context, []any, []any) error) any { + return controller_reflect_stub{caller: caller} + }, + RefData: "", + }) } // weaver.InstanceOf checks. var _ InstanceOf[Logger] = (*stderrLogger)(nil) +var _ InstanceOf[controller] = (*noopController)(nil) // weaver.Router checks. var _ Unrouted = (*stderrLogger)(nil) +var _ Unrouted = (*noopController)(nil) // Local stub implementations. @@ -71,6 +91,56 @@ func (s logger_local_stub) LogBatch(ctx context.Context, a0 *protos.LogEntryBatc return s.impl.LogBatch(ctx, a0) } +type controller_local_stub struct { + impl controller + tracer trace.Tracer + getHealthMetrics *codegen.MethodMetrics + updateComponentsMetrics *codegen.MethodMetrics +} + +// Check that controller_local_stub implements the controller interface. +var _ controller = (*controller_local_stub)(nil) + +func (s controller_local_stub) GetHealth(ctx context.Context, a0 *protos.GetHealthRequest) (r0 *protos.GetHealthReply, err error) { + // Update metrics. + begin := s.getHealthMetrics.Begin() + defer func() { s.getHealthMetrics.End(begin, err != nil, 0, 0) }() + span := trace.SpanFromContext(ctx) + if span.SpanContext().IsValid() { + // Create a child span for this method. + ctx, span = s.tracer.Start(ctx, "weaver.controller.GetHealth", trace.WithSpanKind(trace.SpanKindInternal)) + defer func() { + if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, err.Error()) + } + span.End() + }() + } + + return s.impl.GetHealth(ctx, a0) +} + +func (s controller_local_stub) UpdateComponents(ctx context.Context, a0 *protos.UpdateComponentsRequest) (r0 *protos.UpdateComponentsReply, err error) { + // Update metrics. + begin := s.updateComponentsMetrics.Begin() + defer func() { s.updateComponentsMetrics.End(begin, err != nil, 0, 0) }() + span := trace.SpanFromContext(ctx) + if span.SpanContext().IsValid() { + // Create a child span for this method. + ctx, span = s.tracer.Start(ctx, "weaver.controller.UpdateComponents", trace.WithSpanKind(trace.SpanKindInternal)) + defer func() { + if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, err.Error()) + } + span.End() + }() + } + + return s.impl.UpdateComponents(ctx, a0) +} + // Client stub implementations. type logger_client_stub struct { @@ -131,6 +201,117 @@ func (s logger_client_stub) LogBatch(ctx context.Context, a0 *protos.LogEntryBat return } +type controller_client_stub struct { + stub codegen.Stub + getHealthMetrics *codegen.MethodMetrics + updateComponentsMetrics *codegen.MethodMetrics +} + +// Check that controller_client_stub implements the controller interface. +var _ controller = (*controller_client_stub)(nil) + +func (s controller_client_stub) GetHealth(ctx context.Context, a0 *protos.GetHealthRequest) (r0 *protos.GetHealthReply, err error) { + // Update metrics. + var requestBytes, replyBytes int + begin := s.getHealthMetrics.Begin() + defer func() { s.getHealthMetrics.End(begin, err != nil, requestBytes, replyBytes) }() + + span := trace.SpanFromContext(ctx) + if span.SpanContext().IsValid() { + // Create a child span for this method. + ctx, span = s.stub.Tracer().Start(ctx, "weaver.controller.GetHealth", trace.WithSpanKind(trace.SpanKindClient)) + } + + defer func() { + // Catch and return any panics detected during encoding/decoding/rpc. + if err == nil { + err = codegen.CatchPanics(recover()) + if err != nil { + err = errors.Join(RemoteCallError, err) + } + } + + if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, err.Error()) + } + span.End() + + }() + + // Encode arguments. + enc := codegen.NewEncoder() + serviceweaver_enc_ptr_GetHealthRequest_fd6083fb(enc, a0) + var shardKey uint64 + + // Call the remote method. + requestBytes = len(enc.Data()) + var results []byte + results, err = s.stub.Run(ctx, 0, enc.Data(), shardKey) + replyBytes = len(results) + if err != nil { + err = errors.Join(RemoteCallError, err) + return + } + + // Decode the results. + dec := codegen.NewDecoder(results) + r0 = serviceweaver_dec_ptr_GetHealthReply_b2d11423(dec) + err = dec.Error() + return +} + +func (s controller_client_stub) UpdateComponents(ctx context.Context, a0 *protos.UpdateComponentsRequest) (r0 *protos.UpdateComponentsReply, err error) { + // Update metrics. + var requestBytes, replyBytes int + begin := s.updateComponentsMetrics.Begin() + defer func() { s.updateComponentsMetrics.End(begin, err != nil, requestBytes, replyBytes) }() + + span := trace.SpanFromContext(ctx) + if span.SpanContext().IsValid() { + // Create a child span for this method. + ctx, span = s.stub.Tracer().Start(ctx, "weaver.controller.UpdateComponents", trace.WithSpanKind(trace.SpanKindClient)) + } + + defer func() { + // Catch and return any panics detected during encoding/decoding/rpc. + if err == nil { + err = codegen.CatchPanics(recover()) + if err != nil { + err = errors.Join(RemoteCallError, err) + } + } + + if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, err.Error()) + } + span.End() + + }() + + // Encode arguments. + enc := codegen.NewEncoder() + serviceweaver_enc_ptr_UpdateComponentsRequest_d1b56e1f(enc, a0) + var shardKey uint64 + + // Call the remote method. + requestBytes = len(enc.Data()) + var results []byte + results, err = s.stub.Run(ctx, 1, enc.Data(), shardKey) + replyBytes = len(results) + if err != nil { + err = errors.Join(RemoteCallError, err) + return + } + + // Decode the results. + dec := codegen.NewDecoder(results) + r0 = serviceweaver_dec_ptr_UpdateComponentsReply_93bebb77(dec) + err = dec.Error() + return +} + // Note that "weaver generate" will always generate the error message below. // Everything is okay. The error message is only relevant if you see it when // you run "go build" or "go run". @@ -198,6 +379,76 @@ func (s logger_server_stub) logBatch(ctx context.Context, args []byte) (res []by return enc.Data(), nil } +type controller_server_stub struct { + impl controller + addLoad func(key uint64, load float64) +} + +// Check that controller_server_stub implements the codegen.Server interface. +var _ codegen.Server = (*controller_server_stub)(nil) + +// GetStubFn implements the codegen.Server interface. +func (s controller_server_stub) GetStubFn(method string) func(ctx context.Context, args []byte) ([]byte, error) { + switch method { + case "GetHealth": + return s.getHealth + case "UpdateComponents": + return s.updateComponents + default: + return nil + } +} + +func (s controller_server_stub) getHealth(ctx context.Context, args []byte) (res []byte, err error) { + // Catch and return any panics detected during encoding/decoding/rpc. + defer func() { + if err == nil { + err = codegen.CatchPanics(recover()) + } + }() + + // Decode arguments. + dec := codegen.NewDecoder(args) + var a0 *protos.GetHealthRequest + a0 = serviceweaver_dec_ptr_GetHealthRequest_fd6083fb(dec) + + // TODO(rgrandl): The deferred function above will recover from panics in the + // user code: fix this. + // Call the local method. + r0, appErr := s.impl.GetHealth(ctx, a0) + + // Encode the results. + enc := codegen.NewEncoder() + serviceweaver_enc_ptr_GetHealthReply_b2d11423(enc, r0) + enc.Error(appErr) + return enc.Data(), nil +} + +func (s controller_server_stub) updateComponents(ctx context.Context, args []byte) (res []byte, err error) { + // Catch and return any panics detected during encoding/decoding/rpc. + defer func() { + if err == nil { + err = codegen.CatchPanics(recover()) + } + }() + + // Decode arguments. + dec := codegen.NewDecoder(args) + var a0 *protos.UpdateComponentsRequest + a0 = serviceweaver_dec_ptr_UpdateComponentsRequest_d1b56e1f(dec) + + // TODO(rgrandl): The deferred function above will recover from panics in the + // user code: fix this. + // Call the local method. + r0, appErr := s.impl.UpdateComponents(ctx, a0) + + // Encode the results. + enc := codegen.NewEncoder() + serviceweaver_enc_ptr_UpdateComponentsReply_93bebb77(enc, r0) + enc.Error(appErr) + return enc.Data(), nil +} + // Reflect stub implementations. type logger_reflect_stub struct { @@ -212,6 +463,23 @@ func (s logger_reflect_stub) LogBatch(ctx context.Context, a0 *protos.LogEntryBa return } +type controller_reflect_stub struct { + caller func(string, context.Context, []any, []any) error +} + +// Check that controller_reflect_stub implements the controller interface. +var _ controller = (*controller_reflect_stub)(nil) + +func (s controller_reflect_stub) GetHealth(ctx context.Context, a0 *protos.GetHealthRequest) (r0 *protos.GetHealthReply, err error) { + err = s.caller("GetHealth", ctx, []any{a0}, []any{&r0}) + return +} + +func (s controller_reflect_stub) UpdateComponents(ctx context.Context, a0 *protos.UpdateComponentsRequest) (r0 *protos.UpdateComponentsReply, err error) { + err = s.caller("UpdateComponents", ctx, []any{a0}, []any{&r0}) + return +} + // Encoding/decoding implementations. func serviceweaver_enc_ptr_LogEntryBatch_fec9a5d4(enc *codegen.Encoder, arg *protos.LogEntryBatch) { @@ -231,3 +499,75 @@ func serviceweaver_dec_ptr_LogEntryBatch_fec9a5d4(dec *codegen.Decoder) *protos. dec.DecodeProto(&res) return &res } + +func serviceweaver_enc_ptr_GetHealthRequest_fd6083fb(enc *codegen.Encoder, arg *protos.GetHealthRequest) { + if arg == nil { + enc.Bool(false) + } else { + enc.Bool(true) + enc.EncodeProto(arg) + } +} + +func serviceweaver_dec_ptr_GetHealthRequest_fd6083fb(dec *codegen.Decoder) *protos.GetHealthRequest { + if !dec.Bool() { + return nil + } + var res protos.GetHealthRequest + dec.DecodeProto(&res) + return &res +} + +func serviceweaver_enc_ptr_GetHealthReply_b2d11423(enc *codegen.Encoder, arg *protos.GetHealthReply) { + if arg == nil { + enc.Bool(false) + } else { + enc.Bool(true) + enc.EncodeProto(arg) + } +} + +func serviceweaver_dec_ptr_GetHealthReply_b2d11423(dec *codegen.Decoder) *protos.GetHealthReply { + if !dec.Bool() { + return nil + } + var res protos.GetHealthReply + dec.DecodeProto(&res) + return &res +} + +func serviceweaver_enc_ptr_UpdateComponentsRequest_d1b56e1f(enc *codegen.Encoder, arg *protos.UpdateComponentsRequest) { + if arg == nil { + enc.Bool(false) + } else { + enc.Bool(true) + enc.EncodeProto(arg) + } +} + +func serviceweaver_dec_ptr_UpdateComponentsRequest_d1b56e1f(dec *codegen.Decoder) *protos.UpdateComponentsRequest { + if !dec.Bool() { + return nil + } + var res protos.UpdateComponentsRequest + dec.DecodeProto(&res) + return &res +} + +func serviceweaver_enc_ptr_UpdateComponentsReply_93bebb77(enc *codegen.Encoder, arg *protos.UpdateComponentsReply) { + if arg == nil { + enc.Bool(false) + } else { + enc.Bool(true) + enc.EncodeProto(arg) + } +} + +func serviceweaver_dec_ptr_UpdateComponentsReply_93bebb77(dec *codegen.Decoder) *protos.UpdateComponentsReply { + if !dec.Bool() { + return nil + } + var res protos.UpdateComponentsReply + dec.DecodeProto(&res) + return &res +} diff --git a/weavertest/deployer.go b/weavertest/deployer.go index df8ad6197..2c110105e 100644 --- a/weavertest/deployer.go +++ b/weavertest/deployer.go @@ -18,13 +18,16 @@ import ( "context" "errors" "fmt" + "log/slog" "os" "reflect" "sync" "github.com/ServiceWeaver/weaver/internal/envelope/conn" "github.com/ServiceWeaver/weaver/runtime" + "github.com/ServiceWeaver/weaver/runtime/deployers" "github.com/ServiceWeaver/weaver/runtime/envelope" + "github.com/ServiceWeaver/weaver/runtime/logging" "github.com/ServiceWeaver/weaver/runtime/protos" "github.com/google/uuid" "golang.org/x/exp/maps" @@ -52,6 +55,7 @@ const DefaultReplication = 2 type deployer struct { ctx context.Context ctxCancel context.CancelFunc + tmpDir string runner Runner // holds runner-specific info like config wlet *protos.EnvelopeInfo // info for subprocesses config *protos.AppConfig // application config @@ -104,7 +108,7 @@ var _ envelope.EnvelopeHandler = &handler{} // newDeployer returns a new weavertest multiprocess deployer. locals contains // components that should be co-located with the main component and not // replicated. -func newDeployer(ctx context.Context, wlet *protos.EnvelopeInfo, config *protos.AppConfig, runner Runner, locals []reflect.Type, logWriter func(*protos.LogEntry)) *deployer { +func newDeployer(ctx context.Context, wlet *protos.EnvelopeInfo, config *protos.AppConfig, runner Runner, locals []reflect.Type, logWriter func(*protos.LogEntry), tmpDir string) *deployer { colocation := map[string]string{} for _, group := range config.Colocate { for _, c := range group.Components { @@ -115,6 +119,7 @@ func newDeployer(ctx context.Context, wlet *protos.EnvelopeInfo, config *protos. d := &deployer{ ctx: ctx, ctxCancel: cancel, + tmpDir: tmpDir, runner: runner, wlet: wlet, config: config, @@ -162,6 +167,9 @@ func (d *deployer) start() (runtime.Bootstrap, error) { Id: uuid.New().String(), Sections: d.wlet.Sections, InternalAddress: "localhost:0", + + // Create ControlSocket ourselves since we are not using envelope.NewEnvelope(). + ControlSocket: deployers.NewUnixSocketPath(d.tmpDir), } bootstrap := runtime.Bootstrap{ ToWeaveletFile: toWeaveletReader, @@ -364,7 +372,13 @@ func (d *deployer) startGroup(g *group) error { group: g, subscribed: map[string]bool{}, } - e, err := envelope.NewEnvelope(d.ctx, wlet, d.config) + logger := slog.New(&logging.LogHandler{ + Opts: logging.Options{Component: "envelope", Weavelet: wlet.Id}, + Write: d.log, + }) + e, err := envelope.NewEnvelope(d.ctx, wlet, d.config, envelope.Options{ + Logger: logger, + }) if err != nil { return err } diff --git a/weavertest/multi.go b/weavertest/multi.go index d9dd28b1e..f8cd60872 100644 --- a/weavertest/multi.go +++ b/weavertest/multi.go @@ -98,7 +98,7 @@ func initMultiProcess(ctx context.Context, t testing.TB, isBench bool, runner Ru } // Launch the deployer. - d := newDeployer(ctx, wlet, appConfig, runner, locals, logWriter) + d := newDeployer(ctx, wlet, appConfig, runner, locals, logWriter, t.TempDir()) bootstrap, err = d.start() if err != nil { return runtime.Bootstrap{}, nil, err diff --git a/website/blog/deployers.md b/website/blog/deployers.md index 0b57feca7..bedb4b81d 100644 --- a/website/blog/deployers.md +++ b/website/blog/deployers.md @@ -447,6 +447,9 @@ and [`weaver gke`][weaver_gke_github] deployers for reference. ## Appendix: Envelope-Weavelet Protocol +TODO(sanjay,mwhittaker): Drop this section and replace it with the component +method call based protocol once we have fully transitioned to it. + In this appendix, we describe the low-level communication protocol between an envelope and a weavelet. Most deployers should use the high-level [`Envelope`][Envelope] API described earlier, but understanding the low-level diff --git a/website/blog/deployers/deployers_test.go b/website/blog/deployers/deployers_test.go index 56d94b672..4e7765dfe 100644 --- a/website/blog/deployers/deployers_test.go +++ b/website/blog/deployers/deployers_test.go @@ -21,6 +21,8 @@ import ( "net/http" "os/exec" "strings" + "sync" + "syscall" "testing" ) @@ -65,16 +67,30 @@ func deployCollatz(t *testing.T, deployer string) { if err != nil { t.Fatal(err) } + errpipe, err := cmd.StderrPipe() + if err != nil { + t.Fatal(err) + } if err := cmd.Start(); err != nil { t.Fatal(err) } - defer cmd.Process.Kill() + defer cmd.Process.Signal(syscall.SIGTERM) // Give child a chance to cleanup + + // Log stderr messages if any + log := asyncLogger(t) + go func() { + scanner := bufio.NewScanner(errpipe) + for scanner.Scan() { + log(scanner.Text()) + } + }() // Parse the listener address from the logs (yes, this is janky). addr := "" scanner := bufio.NewScanner(out) for scanner.Scan() { line := scanner.Text() + log(line) if strings.HasPrefix(line, "Weavelet listening on ") { addr, _ = strings.CutPrefix(line, "Weavelet listening on ") break @@ -83,6 +99,9 @@ func deployCollatz(t *testing.T, deployer string) { if err := scanner.Err(); err != nil { t.Fatal(err) } + if addr == "" { + t.Fatal("did not find weavelet port") + } // Curl the listener. url := fmt.Sprintf("http://%s?x=10", addr) @@ -101,3 +120,22 @@ func deployCollatz(t *testing.T, deployer string) { t.Fatalf("curl %s: got %q, want %q", url, got, want) } } + +// asyncLogger returns a function that logs a line to t until t is done, after which +// it discards log entries. +func asyncLogger(t *testing.T) func(string) { + var mu sync.Mutex + done := false + t.Cleanup(func() { + mu.Lock() + defer mu.Unlock() + done = true + }) + return func(line string) { + mu.Lock() + defer mu.Unlock() + if !done { + t.Log(line) + } + } +} diff --git a/website/blog/deployers/multi/main.go b/website/blog/deployers/multi/main.go index 84b355077..616edf08d 100644 --- a/website/blog/deployers/multi/main.go +++ b/website/blog/deployers/multi/main.go @@ -20,6 +20,7 @@ import ( "context" "flag" "fmt" + "os" "sync" "github.com/ServiceWeaver/weaver/runtime" @@ -56,7 +57,10 @@ var deploymentId = uuid.New().String() func main() { flag.Parse() d := &deployer{handlers: map[string]*handler{}} - d.spawn(runtime.Main) + if _, err := d.spawn(runtime.Main); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } select {} // block forever } @@ -85,7 +89,7 @@ func (d *deployer) spawn(component string) (*handler, error) { Name: "app", // the application name Binary: flag.Arg(0), // the application binary } - envelope, err := envelope.NewEnvelope(context.Background(), info, config) + envelope, err := envelope.NewEnvelope(context.Background(), info, config, envelope.Options{}) if err != nil { return nil, err } diff --git a/website/blog/deployers/pipes/main.go b/website/blog/deployers/pipes/main.go index 0a037acb3..6376ecc8a 100644 --- a/website/blog/deployers/pipes/main.go +++ b/website/blog/deployers/pipes/main.go @@ -24,6 +24,8 @@ import ( "os" "os/exec" + "github.com/ServiceWeaver/weaver/runtime" + "github.com/ServiceWeaver/weaver/runtime/deployers" "github.com/ServiceWeaver/weaver/runtime/protomsg" "github.com/ServiceWeaver/weaver/runtime/protos" "github.com/google/uuid" @@ -40,6 +42,16 @@ func main() { } func run(ctx context.Context, binary string) error { + // Step 0. Create a unix domain socket where the weavelet will listen for + // control messages. + tmpDir, err := os.MkdirTemp("", "pipedep") + if err != nil { + return err + } + defer os.RemoveAll(tmpDir) + runtime.OnExitSignal(func() { os.RemoveAll(tmpDir) }) + socket := deployers.NewUnixSocketPath(tmpDir) + // Step 1. Run the binary and establish the pipes between the envelope and // the weavelet. // @@ -75,6 +87,7 @@ func run(ctx context.Context, binary string) error { Id: uuid.New().String(), // the weavelet id RunMain: true, // should the weavelet run main? InternalAddress: "localhost:0", // internal address of the weavelet + ControlSocket: socket, // socket where weavelet will listen for control calls }, } if err := protomsg.Write(envelopeWriter, info); err != nil { diff --git a/website/blog/deployers/single/main.go b/website/blog/deployers/single/main.go index 12f5a209b..abd842ace 100644 --- a/website/blog/deployers/single/main.go +++ b/website/blog/deployers/single/main.go @@ -61,7 +61,7 @@ func deploy(binary string) error { Name: "app", // the application name Binary: binary, // the application binary } - envelope, err := envelope.NewEnvelope(context.Background(), info, config) + envelope, err := envelope.NewEnvelope(context.Background(), info, config, envelope.Options{}) if err != nil { return err }