diff --git a/pkg/gateway/gateway.go b/pkg/gateway/gateway.go index 661f93e99..cf520bfe0 100644 --- a/pkg/gateway/gateway.go +++ b/pkg/gateway/gateway.go @@ -58,6 +58,7 @@ type Gateway struct { EventRepo repository.EventRepository Tailscale *network.Tailscale metricsRepo repository.MetricsRepository + workerRepo repository.WorkerRepository Storage storage.Storage Scheduler *scheduler.Scheduler ctx context.Context @@ -127,6 +128,7 @@ func NewGateway() (*Gateway, error) { containerRepo := repository.NewContainerRedisRepository(redisClient) providerRepo := repository.NewProviderRedisRepository(redisClient) + workerRepo := repository.NewWorkerRedisRepository(redisClient, config.Worker) taskRepo := repository.NewTaskRedisRepository(redisClient) taskDispatcher, err := task.NewDispatcher(ctx, taskRepo) if err != nil { @@ -144,6 +146,7 @@ func NewGateway() (*Gateway, error) { gateway.TaskDispatcher = taskDispatcher gateway.metricsRepo = metricsRepo gateway.EventRepo = eventRepo + gateway.workerRepo = workerRepo return gateway, nil } @@ -367,6 +370,7 @@ func (g *Gateway) registerServices() error { TaskDispatcher: g.TaskDispatcher, RedisClient: g.RedisClient, EventRepo: g.EventRepo, + WorkerRepo: g.workerRepo, }) if err != nil { return err diff --git a/pkg/gateway/gateway.proto b/pkg/gateway/gateway.proto index 8af10a971..c24bd7f34 100644 --- a/pkg/gateway/gateway.proto +++ b/pkg/gateway/gateway.proto @@ -51,6 +51,12 @@ service GatewayService { rpc CreateToken(CreateTokenRequest) returns (CreateTokenResponse); rpc ToggleToken(ToggleTokenRequest) returns (ToggleTokenResponse); rpc DeleteToken(DeleteTokenRequest) returns (DeleteTokenResponse); + + // Workers + rpc ListWorkers(ListWorkersRequest) returns (ListWorkersResponse); + rpc CordonWorker(CordonWorkerRequest) returns (CordonWorkerResponse); + rpc UncordonWorker(UncordonWorkerRequest) returns (UncordonWorkerResponse); + rpc DrainWorker(DrainWorkerRequest) returns (DrainWorkerResponse); } message AuthorizeRequest {} @@ -445,3 +451,54 @@ message GetURLResponse { string err_msg = 2; string url = 3; } + +message Worker { + string id = 1; + string status = 2; + string gpu = 3; + string pool_name = 4; + string machine_id = 5; + int32 priority = 6; + int64 total_cpu = 7; + int64 total_memory = 8; + uint32 total_gpu_count = 9; + int64 free_cpu = 10; + int64 free_memory = 11; + uint32 free_gpu_count = 12; + repeated Container active_containers = 13; +} + +message ListWorkersRequest {} + +message ListWorkersResponse { + bool ok = 1; + string err_msg = 2; + repeated Worker workers = 3; +} + +message CordonWorkerRequest { + string worker_id = 1; +} + +message CordonWorkerResponse { + bool ok = 1; + string err_msg = 2; +} + +message UncordonWorkerRequest { + string worker_id = 1; +} + +message UncordonWorkerResponse { + bool ok = 1; + string err_msg = 2; +} + +message DrainWorkerRequest { + string worker_id = 1; +} + +message DrainWorkerResponse { + bool ok = 1; + string err_msg = 2; +} diff --git a/pkg/gateway/services/service.go b/pkg/gateway/services/service.go index 37b53de9a..7f00cb93f 100644 --- a/pkg/gateway/services/service.go +++ b/pkg/gateway/services/service.go @@ -18,6 +18,7 @@ type GatewayService struct { taskDispatcher *task.Dispatcher redisClient *common.RedisClient eventRepo repository.EventRepository + workerRepo repository.WorkerRepository pb.UnimplementedGatewayServiceServer } @@ -30,6 +31,7 @@ type GatewayServiceOpts struct { TaskDispatcher *task.Dispatcher RedisClient *common.RedisClient EventRepo repository.EventRepository + WorkerRepo repository.WorkerRepository } func NewGatewayService(opts *GatewayServiceOpts) (*GatewayService, error) { @@ -42,5 +44,6 @@ func NewGatewayService(opts *GatewayServiceOpts) (*GatewayService, error) { taskDispatcher: opts.TaskDispatcher, redisClient: opts.RedisClient, eventRepo: opts.EventRepo, + workerRepo: opts.WorkerRepo, }, nil } diff --git a/pkg/gateway/services/worker.go b/pkg/gateway/services/worker.go new file mode 100644 index 000000000..83afe468c --- /dev/null +++ b/pkg/gateway/services/worker.go @@ -0,0 +1,199 @@ +package gatewayservices + +import ( + "context" + "errors" + "time" + + "github.com/beam-cloud/beta9/pkg/auth" + "github.com/beam-cloud/beta9/pkg/types" + pb "github.com/beam-cloud/beta9/proto" + "golang.org/x/exp/slices" + "golang.org/x/sync/errgroup" + "google.golang.org/protobuf/types/known/timestamppb" +) + +func (gws *GatewayService) ListWorkers(ctx context.Context, in *pb.ListWorkersRequest) (*pb.ListWorkersResponse, error) { + if _, err := isClusterAdmin(ctx); err != nil { + return &pb.ListWorkersResponse{ + Ok: false, + ErrMsg: err.Error(), + }, nil + } + + workers, err := gws.workerRepo.GetAllWorkers() + if err != nil { + return &pb.ListWorkersResponse{ + Ok: false, + ErrMsg: err.Error(), + }, nil + } + + sortWorkers(workers) + + pbWorkers := make([]*pb.Worker, len(workers)) + for i, w := range workers { + pbWorkers[i] = &pb.Worker{ + Id: w.Id, + Status: string(w.Status), + Gpu: w.Gpu, + PoolName: w.PoolName, + MachineId: w.MachineId, + Priority: w.Priority, + TotalCpu: w.TotalCpu, + TotalMemory: w.TotalMemory, + TotalGpuCount: w.TotalGpuCount, + FreeCpu: w.FreeCpu, + FreeMemory: w.FreeMemory, + FreeGpuCount: w.FreeGpuCount, + } + + containers, err := gws.containerRepo.GetActiveContainersByWorkerId(w.Id) + if err != nil { + continue + } + + pbWorkers[i].ActiveContainers = make([]*pb.Container, len(containers)) + for j, c := range containers { + pbWorkers[i].ActiveContainers[j] = &pb.Container{ + ContainerId: c.ContainerId, + WorkspaceId: string(c.WorkspaceId), + Status: string(c.Status), + ScheduledAt: timestamppb.New(time.Unix(c.ScheduledAt, 0)), + } + } + } + + return &pb.ListWorkersResponse{ + Ok: true, + Workers: pbWorkers, + }, nil +} + +func sortWorkers(w []*types.Worker) { + slices.SortFunc(w, func(i, j *types.Worker) int { + if i.PoolName < j.PoolName { + return -1 + } + if i.PoolName > j.PoolName { + return 1 + } + if i.Status < j.Status { + return -1 + } + if i.Status > j.Status { + return 1 + } + if i.Id < j.Id { + return -1 + } + if i.Id > j.Id { + return 1 + } + return 0 + }) +} + +func (gws *GatewayService) CordonWorker(ctx context.Context, in *pb.CordonWorkerRequest) (*pb.CordonWorkerResponse, error) { + if _, err := isClusterAdmin(ctx); err != nil { + return &pb.CordonWorkerResponse{ + Ok: false, + ErrMsg: err.Error(), + }, nil + } + + worker, err := gws.workerRepo.GetWorkerById(in.WorkerId) + if err != nil { + return &pb.CordonWorkerResponse{ + Ok: false, + ErrMsg: err.Error(), + }, nil + } + + if err := gws.workerRepo.UpdateWorkerStatus(worker.Id, types.WorkerStatusDisabled); err != nil { + return &pb.CordonWorkerResponse{ + Ok: false, + ErrMsg: err.Error(), + }, nil + } + + return &pb.CordonWorkerResponse{ + Ok: true, + }, nil +} + +func (gws *GatewayService) UncordonWorker(ctx context.Context, in *pb.UncordonWorkerRequest) (*pb.UncordonWorkerResponse, error) { + if _, err := isClusterAdmin(ctx); err != nil { + return &pb.UncordonWorkerResponse{ + Ok: false, + ErrMsg: err.Error(), + }, nil + } + + worker, err := gws.workerRepo.GetWorkerById(in.WorkerId) + if err != nil { + return &pb.UncordonWorkerResponse{ + Ok: false, + ErrMsg: err.Error(), + }, nil + } + + err = gws.workerRepo.UpdateWorkerStatus(worker.Id, types.WorkerStatusAvailable) + if err != nil { + return &pb.UncordonWorkerResponse{ + Ok: false, + ErrMsg: err.Error(), + }, nil + } + + return &pb.UncordonWorkerResponse{ + Ok: true, + }, nil +} + +func (gws *GatewayService) DrainWorker(ctx context.Context, in *pb.DrainWorkerRequest) (*pb.DrainWorkerResponse, error) { + if _, err := isClusterAdmin(ctx); err != nil { + return &pb.DrainWorkerResponse{ + Ok: false, + ErrMsg: err.Error(), + }, nil + } + + worker, err := gws.workerRepo.GetWorkerById(in.WorkerId) + if err != nil { + return &pb.DrainWorkerResponse{ + Ok: false, + ErrMsg: err.Error(), + }, nil + } + + containers, err := gws.containerRepo.GetActiveContainersByWorkerId(worker.Id) + if err != nil { + return &pb.DrainWorkerResponse{ + Ok: false, + ErrMsg: err.Error(), + }, err + } + + var group errgroup.Group + for _, container := range containers { + group.Go(func() error { + return gws.scheduler.Stop(container.ContainerId) + }) + } + if err := group.Wait(); err != nil { + return &pb.DrainWorkerResponse{ + Ok: false, + ErrMsg: err.Error(), + }, nil + } + + return &pb.DrainWorkerResponse{ + Ok: true, + }, nil +} + +func isClusterAdmin(ctx context.Context) (bool, error) { + authInfo, _ := auth.AuthInfoFromContext(ctx) + return authInfo.Token.TokenType == types.TokenTypeClusterAdmin, errors.New("This action is not permitted") +} diff --git a/pkg/repository/base.go b/pkg/repository/base.go index ba650e181..041f5b2d0 100755 --- a/pkg/repository/base.go +++ b/pkg/repository/base.go @@ -18,6 +18,7 @@ type WorkerRepository interface { GetAllWorkersOnMachine(machineId string) ([]*types.Worker, error) AddWorker(w *types.Worker) error ToggleWorkerAvailable(workerId string) error + UpdateWorkerStatus(workerId string, status types.WorkerStatus) error RemoveWorker(w *types.Worker) error SetWorkerKeepAlive(workerId string) error UpdateWorkerCapacity(w *types.Worker, cr *types.ContainerRequest, ut types.CapacityUpdateType) error diff --git a/pkg/repository/worker_redis.go b/pkg/repository/worker_redis.go index 58103e1ee..eebd388c0 100644 --- a/pkg/repository/worker_redis.go +++ b/pkg/repository/worker_redis.go @@ -96,19 +96,7 @@ func (r *WorkerRedisRepository) RemoveWorker(worker *types.Worker) error { return nil } -func (r *WorkerRedisRepository) SetWorkerKeepAlive(workerId string) error { - stateKey := common.RedisKeys.SchedulerWorkerState(workerId) - - // Set TTL on state key - err := r.rdb.Expire(context.TODO(), stateKey, time.Duration(types.WorkerStateTtlS)*time.Second).Err() - if err != nil { - return fmt.Errorf("failed to set worker state ttl <%v>: %w", stateKey, err) - } - - return nil -} - -func (r *WorkerRedisRepository) ToggleWorkerAvailable(workerId string) error { +func (r *WorkerRedisRepository) UpdateWorkerStatus(workerId string, status types.WorkerStatus) error { err := r.lock.Acquire(context.TODO(), common.RedisKeys.SchedulerWorkerLock(workerId), common.RedisLockOptions{TtlS: 10, Retries: 3}) if err != nil { return err @@ -121,12 +109,12 @@ func (r *WorkerRedisRepository) ToggleWorkerAvailable(workerId string) error { return err } - // Make worker available by setting status + // Update worker status + worker.Status = status worker.ResourceVersion++ - worker.Status = types.WorkerStatusAvailable err = r.rdb.HSet(context.TODO(), stateKey, common.ToSlice(worker)).Err() if err != nil { - return fmt.Errorf("failed to toggle worker state <%s>: %v", stateKey, err) + return fmt.Errorf("failed to update worker status <%s>: %v", stateKey, err) } // Set TTL on state key @@ -138,6 +126,22 @@ func (r *WorkerRedisRepository) ToggleWorkerAvailable(workerId string) error { return nil } +func (r *WorkerRedisRepository) SetWorkerKeepAlive(workerId string) error { + stateKey := common.RedisKeys.SchedulerWorkerState(workerId) + + // Set TTL on state key + err := r.rdb.Expire(context.TODO(), stateKey, time.Duration(types.WorkerStateTtlS)*time.Second).Err() + if err != nil { + return fmt.Errorf("failed to set worker state ttl <%v>: %w", stateKey, err) + } + + return nil +} + +func (r *WorkerRedisRepository) ToggleWorkerAvailable(workerId string) error { + return r.UpdateWorkerStatus(workerId, types.WorkerStatusAvailable) +} + // getWorkers retrieves a list of worker objects from the Redis store that match a given pattern. // If useLock is set to true, a lock will be acquired for each worker and released after retrieval. // If you can afford to not have the most up-to-date worker information, you can set useLock to false. diff --git a/pkg/scheduler/pool.go b/pkg/scheduler/pool.go index b95d1615b..8208deff7 100644 --- a/pkg/scheduler/pool.go +++ b/pkg/scheduler/pool.go @@ -78,6 +78,11 @@ func freePoolCapacity(workerRepo repository.WorkerRepository, wpc WorkerPoolCont } for _, worker := range workers { + // Exclude disabled workers from the capacity calculation + if worker.Status == types.WorkerStatusDisabled { + continue + } + capacity.FreeCpu += worker.FreeCpu capacity.FreeMemory += worker.FreeMemory diff --git a/pkg/scheduler/scheduler.go b/pkg/scheduler/scheduler.go index cf2e0f2bb..f5cca4bdd 100644 --- a/pkg/scheduler/scheduler.go +++ b/pkg/scheduler/scheduler.go @@ -255,7 +255,7 @@ func filterWorkersByResources(workers []*types.Worker, request *types.ContainerR filteredWorkers := []*types.Worker{} for _, worker := range workers { if worker.FreeCpu >= int64(request.Cpu) && worker.FreeMemory >= int64(request.Memory) && - worker.Gpu == request.Gpu && worker.FreeGpuCount >= request.GpuCount { + worker.Gpu == request.Gpu && worker.FreeGpuCount >= request.GpuCount && worker.Status != types.WorkerStatusDisabled { filteredWorkers = append(filteredWorkers, worker) } } diff --git a/pkg/types/scheduler.go b/pkg/types/scheduler.go index 90e4be527..0294f8939 100644 --- a/pkg/types/scheduler.go +++ b/pkg/types/scheduler.go @@ -10,6 +10,7 @@ type WorkerStatus string const ( WorkerStatusAvailable WorkerStatus = "available" WorkerStatusPending WorkerStatus = "pending" + WorkerStatusDisabled WorkerStatus = "disabled" WorkerStateTtlS int = 60 ) diff --git a/proto/gateway.pb.go b/proto/gateway.pb.go index b20ecb4e1..17a0696cb 100644 --- a/proto/gateway.pb.go +++ b/proto/gateway.pb.go @@ -4355,6 +4355,556 @@ func (x *GetURLResponse) GetUrl() string { return "" } +type Worker struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Status string `protobuf:"bytes,2,opt,name=status,proto3" json:"status,omitempty"` + Gpu string `protobuf:"bytes,3,opt,name=gpu,proto3" json:"gpu,omitempty"` + PoolName string `protobuf:"bytes,4,opt,name=pool_name,json=poolName,proto3" json:"pool_name,omitempty"` + MachineId string `protobuf:"bytes,5,opt,name=machine_id,json=machineId,proto3" json:"machine_id,omitempty"` + Priority int32 `protobuf:"varint,6,opt,name=priority,proto3" json:"priority,omitempty"` + TotalCpu int64 `protobuf:"varint,7,opt,name=total_cpu,json=totalCpu,proto3" json:"total_cpu,omitempty"` + TotalMemory int64 `protobuf:"varint,8,opt,name=total_memory,json=totalMemory,proto3" json:"total_memory,omitempty"` + TotalGpuCount uint32 `protobuf:"varint,9,opt,name=total_gpu_count,json=totalGpuCount,proto3" json:"total_gpu_count,omitempty"` + FreeCpu int64 `protobuf:"varint,10,opt,name=free_cpu,json=freeCpu,proto3" json:"free_cpu,omitempty"` + FreeMemory int64 `protobuf:"varint,11,opt,name=free_memory,json=freeMemory,proto3" json:"free_memory,omitempty"` + FreeGpuCount uint32 `protobuf:"varint,12,opt,name=free_gpu_count,json=freeGpuCount,proto3" json:"free_gpu_count,omitempty"` + ActiveContainers []*Container `protobuf:"bytes,13,rep,name=active_containers,json=activeContainers,proto3" json:"active_containers,omitempty"` +} + +func (x *Worker) Reset() { + *x = Worker{} + if protoimpl.UnsafeEnabled { + mi := &file_gateway_proto_msgTypes[64] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Worker) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Worker) ProtoMessage() {} + +func (x *Worker) ProtoReflect() protoreflect.Message { + mi := &file_gateway_proto_msgTypes[64] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Worker.ProtoReflect.Descriptor instead. +func (*Worker) Descriptor() ([]byte, []int) { + return file_gateway_proto_rawDescGZIP(), []int{64} +} + +func (x *Worker) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Worker) GetStatus() string { + if x != nil { + return x.Status + } + return "" +} + +func (x *Worker) GetGpu() string { + if x != nil { + return x.Gpu + } + return "" +} + +func (x *Worker) GetPoolName() string { + if x != nil { + return x.PoolName + } + return "" +} + +func (x *Worker) GetMachineId() string { + if x != nil { + return x.MachineId + } + return "" +} + +func (x *Worker) GetPriority() int32 { + if x != nil { + return x.Priority + } + return 0 +} + +func (x *Worker) GetTotalCpu() int64 { + if x != nil { + return x.TotalCpu + } + return 0 +} + +func (x *Worker) GetTotalMemory() int64 { + if x != nil { + return x.TotalMemory + } + return 0 +} + +func (x *Worker) GetTotalGpuCount() uint32 { + if x != nil { + return x.TotalGpuCount + } + return 0 +} + +func (x *Worker) GetFreeCpu() int64 { + if x != nil { + return x.FreeCpu + } + return 0 +} + +func (x *Worker) GetFreeMemory() int64 { + if x != nil { + return x.FreeMemory + } + return 0 +} + +func (x *Worker) GetFreeGpuCount() uint32 { + if x != nil { + return x.FreeGpuCount + } + return 0 +} + +func (x *Worker) GetActiveContainers() []*Container { + if x != nil { + return x.ActiveContainers + } + return nil +} + +type ListWorkersRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ListWorkersRequest) Reset() { + *x = ListWorkersRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_gateway_proto_msgTypes[65] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListWorkersRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListWorkersRequest) ProtoMessage() {} + +func (x *ListWorkersRequest) ProtoReflect() protoreflect.Message { + mi := &file_gateway_proto_msgTypes[65] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListWorkersRequest.ProtoReflect.Descriptor instead. +func (*ListWorkersRequest) Descriptor() ([]byte, []int) { + return file_gateway_proto_rawDescGZIP(), []int{65} +} + +type ListWorkersResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Ok bool `protobuf:"varint,1,opt,name=ok,proto3" json:"ok,omitempty"` + ErrMsg string `protobuf:"bytes,2,opt,name=err_msg,json=errMsg,proto3" json:"err_msg,omitempty"` + Workers []*Worker `protobuf:"bytes,3,rep,name=workers,proto3" json:"workers,omitempty"` +} + +func (x *ListWorkersResponse) Reset() { + *x = ListWorkersResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_gateway_proto_msgTypes[66] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListWorkersResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListWorkersResponse) ProtoMessage() {} + +func (x *ListWorkersResponse) ProtoReflect() protoreflect.Message { + mi := &file_gateway_proto_msgTypes[66] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListWorkersResponse.ProtoReflect.Descriptor instead. +func (*ListWorkersResponse) Descriptor() ([]byte, []int) { + return file_gateway_proto_rawDescGZIP(), []int{66} +} + +func (x *ListWorkersResponse) GetOk() bool { + if x != nil { + return x.Ok + } + return false +} + +func (x *ListWorkersResponse) GetErrMsg() string { + if x != nil { + return x.ErrMsg + } + return "" +} + +func (x *ListWorkersResponse) GetWorkers() []*Worker { + if x != nil { + return x.Workers + } + return nil +} + +type CordonWorkerRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + WorkerId string `protobuf:"bytes,1,opt,name=worker_id,json=workerId,proto3" json:"worker_id,omitempty"` +} + +func (x *CordonWorkerRequest) Reset() { + *x = CordonWorkerRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_gateway_proto_msgTypes[67] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CordonWorkerRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CordonWorkerRequest) ProtoMessage() {} + +func (x *CordonWorkerRequest) ProtoReflect() protoreflect.Message { + mi := &file_gateway_proto_msgTypes[67] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CordonWorkerRequest.ProtoReflect.Descriptor instead. +func (*CordonWorkerRequest) Descriptor() ([]byte, []int) { + return file_gateway_proto_rawDescGZIP(), []int{67} +} + +func (x *CordonWorkerRequest) GetWorkerId() string { + if x != nil { + return x.WorkerId + } + return "" +} + +type CordonWorkerResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Ok bool `protobuf:"varint,1,opt,name=ok,proto3" json:"ok,omitempty"` + ErrMsg string `protobuf:"bytes,2,opt,name=err_msg,json=errMsg,proto3" json:"err_msg,omitempty"` +} + +func (x *CordonWorkerResponse) Reset() { + *x = CordonWorkerResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_gateway_proto_msgTypes[68] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CordonWorkerResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CordonWorkerResponse) ProtoMessage() {} + +func (x *CordonWorkerResponse) ProtoReflect() protoreflect.Message { + mi := &file_gateway_proto_msgTypes[68] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CordonWorkerResponse.ProtoReflect.Descriptor instead. +func (*CordonWorkerResponse) Descriptor() ([]byte, []int) { + return file_gateway_proto_rawDescGZIP(), []int{68} +} + +func (x *CordonWorkerResponse) GetOk() bool { + if x != nil { + return x.Ok + } + return false +} + +func (x *CordonWorkerResponse) GetErrMsg() string { + if x != nil { + return x.ErrMsg + } + return "" +} + +type UncordonWorkerRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + WorkerId string `protobuf:"bytes,1,opt,name=worker_id,json=workerId,proto3" json:"worker_id,omitempty"` +} + +func (x *UncordonWorkerRequest) Reset() { + *x = UncordonWorkerRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_gateway_proto_msgTypes[69] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UncordonWorkerRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UncordonWorkerRequest) ProtoMessage() {} + +func (x *UncordonWorkerRequest) ProtoReflect() protoreflect.Message { + mi := &file_gateway_proto_msgTypes[69] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UncordonWorkerRequest.ProtoReflect.Descriptor instead. +func (*UncordonWorkerRequest) Descriptor() ([]byte, []int) { + return file_gateway_proto_rawDescGZIP(), []int{69} +} + +func (x *UncordonWorkerRequest) GetWorkerId() string { + if x != nil { + return x.WorkerId + } + return "" +} + +type UncordonWorkerResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Ok bool `protobuf:"varint,1,opt,name=ok,proto3" json:"ok,omitempty"` + ErrMsg string `protobuf:"bytes,2,opt,name=err_msg,json=errMsg,proto3" json:"err_msg,omitempty"` +} + +func (x *UncordonWorkerResponse) Reset() { + *x = UncordonWorkerResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_gateway_proto_msgTypes[70] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UncordonWorkerResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UncordonWorkerResponse) ProtoMessage() {} + +func (x *UncordonWorkerResponse) ProtoReflect() protoreflect.Message { + mi := &file_gateway_proto_msgTypes[70] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UncordonWorkerResponse.ProtoReflect.Descriptor instead. +func (*UncordonWorkerResponse) Descriptor() ([]byte, []int) { + return file_gateway_proto_rawDescGZIP(), []int{70} +} + +func (x *UncordonWorkerResponse) GetOk() bool { + if x != nil { + return x.Ok + } + return false +} + +func (x *UncordonWorkerResponse) GetErrMsg() string { + if x != nil { + return x.ErrMsg + } + return "" +} + +type DrainWorkerRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + WorkerId string `protobuf:"bytes,1,opt,name=worker_id,json=workerId,proto3" json:"worker_id,omitempty"` +} + +func (x *DrainWorkerRequest) Reset() { + *x = DrainWorkerRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_gateway_proto_msgTypes[71] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DrainWorkerRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DrainWorkerRequest) ProtoMessage() {} + +func (x *DrainWorkerRequest) ProtoReflect() protoreflect.Message { + mi := &file_gateway_proto_msgTypes[71] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DrainWorkerRequest.ProtoReflect.Descriptor instead. +func (*DrainWorkerRequest) Descriptor() ([]byte, []int) { + return file_gateway_proto_rawDescGZIP(), []int{71} +} + +func (x *DrainWorkerRequest) GetWorkerId() string { + if x != nil { + return x.WorkerId + } + return "" +} + +type DrainWorkerResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Ok bool `protobuf:"varint,1,opt,name=ok,proto3" json:"ok,omitempty"` + ErrMsg string `protobuf:"bytes,2,opt,name=err_msg,json=errMsg,proto3" json:"err_msg,omitempty"` +} + +func (x *DrainWorkerResponse) Reset() { + *x = DrainWorkerResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_gateway_proto_msgTypes[72] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DrainWorkerResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DrainWorkerResponse) ProtoMessage() {} + +func (x *DrainWorkerResponse) ProtoReflect() protoreflect.Message { + mi := &file_gateway_proto_msgTypes[72] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DrainWorkerResponse.ProtoReflect.Descriptor instead. +func (*DrainWorkerResponse) Descriptor() ([]byte, []int) { + return file_gateway_proto_rawDescGZIP(), []int{72} +} + +func (x *DrainWorkerResponse) GetOk() bool { + if x != nil { + return x.Ok + } + return false +} + +func (x *DrainWorkerResponse) GetErrMsg() string { + if x != nil { + return x.ErrMsg + } + return "" +} + var File_gateway_proto protoreflect.FileDescriptor var file_gateway_proto_rawDesc = []byte{ @@ -4905,139 +5455,214 @@ var file_gateway_proto_rawDesc = []byte{ 0x6f, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x02, 0x6f, 0x6b, 0x12, 0x17, 0x0a, 0x07, 0x65, 0x72, 0x72, 0x5f, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x65, 0x72, 0x72, 0x4d, 0x73, 0x67, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x2a, 0x41, 0x0a, 0x1d, 0x52, 0x65, 0x70, 0x6c, 0x61, - 0x63, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x4f, - 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x09, 0x0a, 0x05, 0x57, 0x52, 0x49, 0x54, - 0x45, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x01, 0x12, - 0x09, 0x0a, 0x05, 0x4d, 0x4f, 0x56, 0x45, 0x44, 0x10, 0x02, 0x32, 0xc7, 0x0f, 0x0a, 0x0e, 0x47, - 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x44, 0x0a, - 0x09, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x12, 0x19, 0x2e, 0x67, 0x61, 0x74, - 0x65, 0x77, 0x61, 0x79, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, - 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x00, 0x12, 0x4a, 0x0a, 0x0b, 0x53, 0x69, 0x67, 0x6e, 0x50, 0x61, 0x79, 0x6c, 0x6f, - 0x61, 0x64, 0x12, 0x1b, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x53, 0x69, 0x67, - 0x6e, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x1c, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x50, 0x61, - 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, - 0x47, 0x0a, 0x0a, 0x48, 0x65, 0x61, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x1a, 0x2e, - 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x4f, 0x62, 0x6a, 0x65, - 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x67, 0x61, 0x74, 0x65, - 0x77, 0x61, 0x79, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x44, 0x0a, 0x09, 0x50, 0x75, 0x74, 0x4f, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x19, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, - 0x50, 0x75, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x1a, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x50, 0x75, 0x74, 0x4f, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4c, - 0x0a, 0x0f, 0x50, 0x75, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x12, 0x19, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x50, 0x75, 0x74, 0x4f, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x67, - 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x50, 0x75, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x28, 0x01, 0x12, 0x65, 0x0a, 0x14, - 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, - 0x74, 0x65, 0x6e, 0x74, 0x12, 0x24, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x52, - 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x74, - 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x67, 0x61, 0x74, - 0x65, 0x77, 0x61, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x4f, 0x62, 0x6a, 0x65, - 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x00, 0x12, 0x53, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x1e, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, - 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, - 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x50, 0x0a, 0x0d, 0x53, 0x74, 0x6f, 0x70, - 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x1d, 0x2e, 0x67, 0x61, 0x74, 0x65, - 0x77, 0x61, 0x79, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, - 0x61, 0x79, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x42, 0x0a, 0x09, 0x53, 0x74, - 0x61, 0x72, 0x74, 0x54, 0x61, 0x73, 0x6b, 0x12, 0x19, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, - 0x79, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x53, 0x74, 0x61, - 0x72, 0x74, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3c, - 0x0a, 0x07, 0x45, 0x6e, 0x64, 0x54, 0x61, 0x73, 0x6b, 0x12, 0x17, 0x2e, 0x67, 0x61, 0x74, 0x65, - 0x77, 0x61, 0x79, 0x2e, 0x45, 0x6e, 0x64, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x45, 0x6e, 0x64, - 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x42, 0x0a, 0x09, - 0x53, 0x74, 0x6f, 0x70, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x12, 0x19, 0x2e, 0x67, 0x61, 0x74, 0x65, - 0x77, 0x61, 0x79, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x53, - 0x74, 0x6f, 0x70, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x42, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x12, 0x19, 0x2e, - 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, 0x73, 0x6b, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, - 0x61, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x54, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x4f, 0x72, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x53, 0x74, 0x75, 0x62, 0x12, 0x1f, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, - 0x79, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x75, - 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, - 0x61, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, - 0x75, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x45, 0x0a, 0x0a, 0x44, 0x65, - 0x70, 0x6c, 0x6f, 0x79, 0x53, 0x74, 0x75, 0x62, 0x12, 0x1a, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, - 0x61, 0x79, 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x53, 0x74, 0x75, 0x62, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x44, - 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x53, 0x74, 0x75, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x39, 0x0a, 0x06, 0x47, 0x65, 0x74, 0x55, 0x52, 0x4c, 0x12, 0x16, 0x2e, 0x67, 0x61, - 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x52, 0x4c, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x47, 0x65, - 0x74, 0x55, 0x52, 0x4c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x54, 0x0a, 0x0f, - 0x4c, 0x69, 0x73, 0x74, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, - 0x1f, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x65, - 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x20, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x44, - 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x51, 0x0a, 0x0e, 0x53, 0x74, 0x6f, 0x70, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, - 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x1e, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x53, - 0x74, 0x6f, 0x70, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x53, - 0x74, 0x6f, 0x70, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x57, 0x0a, 0x10, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x44, - 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x20, 0x2e, 0x67, 0x61, 0x74, 0x65, - 0x77, 0x61, 0x79, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, - 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x67, 0x61, - 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x44, 0x65, 0x70, 0x6c, - 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x42, - 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x6f, 0x6c, 0x73, 0x12, 0x19, 0x2e, 0x67, 0x61, - 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x6f, 0x6c, 0x73, 0x52, + 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x22, 0xa5, 0x03, 0x0a, 0x06, 0x57, 0x6f, 0x72, 0x6b, + 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, + 0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x67, 0x70, + 0x75, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x67, 0x70, 0x75, 0x12, 0x1b, 0x0a, 0x09, + 0x70, 0x6f, 0x6f, 0x6c, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x70, 0x6f, 0x6f, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x61, 0x63, + 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, + 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, + 0x72, 0x69, 0x74, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x72, 0x69, 0x6f, + 0x72, 0x69, 0x74, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x63, 0x70, + 0x75, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x43, 0x70, + 0x75, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x6d, 0x65, 0x6d, 0x6f, 0x72, + 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x4d, 0x65, + 0x6d, 0x6f, 0x72, 0x79, 0x12, 0x26, 0x0a, 0x0f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x67, 0x70, + 0x75, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x74, + 0x6f, 0x74, 0x61, 0x6c, 0x47, 0x70, 0x75, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x19, 0x0a, 0x08, + 0x66, 0x72, 0x65, 0x65, 0x5f, 0x63, 0x70, 0x75, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, + 0x66, 0x72, 0x65, 0x65, 0x43, 0x70, 0x75, 0x12, 0x1f, 0x0a, 0x0b, 0x66, 0x72, 0x65, 0x65, 0x5f, + 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x66, 0x72, + 0x65, 0x65, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x12, 0x24, 0x0a, 0x0e, 0x66, 0x72, 0x65, 0x65, + 0x5f, 0x67, 0x70, 0x75, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x0c, 0x66, 0x72, 0x65, 0x65, 0x47, 0x70, 0x75, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x3f, + 0x0a, 0x11, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x61, 0x74, 0x65, + 0x77, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x10, 0x61, + 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x22, + 0x14, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x69, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x6f, 0x72, + 0x6b, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, + 0x6f, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x02, 0x6f, 0x6b, 0x12, 0x17, 0x0a, 0x07, + 0x65, 0x72, 0x72, 0x5f, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x65, + 0x72, 0x72, 0x4d, 0x73, 0x67, 0x12, 0x29, 0x0a, 0x07, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x73, + 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, + 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x52, 0x07, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x73, + 0x22, 0x32, 0x0a, 0x13, 0x43, 0x6f, 0x72, 0x64, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x65, + 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, + 0x65, 0x72, 0x49, 0x64, 0x22, 0x3f, 0x0a, 0x14, 0x43, 0x6f, 0x72, 0x64, 0x6f, 0x6e, 0x57, 0x6f, + 0x72, 0x6b, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, + 0x6f, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x02, 0x6f, 0x6b, 0x12, 0x17, 0x0a, 0x07, + 0x65, 0x72, 0x72, 0x5f, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x65, + 0x72, 0x72, 0x4d, 0x73, 0x67, 0x22, 0x34, 0x0a, 0x15, 0x55, 0x6e, 0x63, 0x6f, 0x72, 0x64, 0x6f, + 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, + 0x0a, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x49, 0x64, 0x22, 0x41, 0x0a, 0x16, 0x55, + 0x6e, 0x63, 0x6f, 0x72, 0x64, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x02, 0x6f, 0x6b, 0x12, 0x17, 0x0a, 0x07, 0x65, 0x72, 0x72, 0x5f, 0x6d, 0x73, 0x67, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x65, 0x72, 0x72, 0x4d, 0x73, 0x67, 0x22, 0x31, + 0x0a, 0x12, 0x44, 0x72, 0x61, 0x69, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x5f, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x49, + 0x64, 0x22, 0x3e, 0x0a, 0x13, 0x44, 0x72, 0x61, 0x69, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x6b, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x02, 0x6f, 0x6b, 0x12, 0x17, 0x0a, 0x07, 0x65, 0x72, 0x72, 0x5f, + 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x65, 0x72, 0x72, 0x4d, 0x73, + 0x67, 0x2a, 0x41, 0x0a, 0x1d, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x4f, 0x62, 0x6a, 0x65, + 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x09, 0x0a, 0x05, 0x57, 0x52, 0x49, 0x54, 0x45, 0x10, 0x00, 0x12, 0x0a, 0x0a, + 0x06, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x4d, 0x4f, 0x56, + 0x45, 0x44, 0x10, 0x02, 0x32, 0xfb, 0x11, 0x0a, 0x0e, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x44, 0x0a, 0x09, 0x41, 0x75, 0x74, 0x68, 0x6f, + 0x72, 0x69, 0x7a, 0x65, 0x12, 0x19, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x41, + 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x1a, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, + 0x69, 0x7a, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4a, 0x0a, + 0x0b, 0x53, 0x69, 0x67, 0x6e, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x1b, 0x2e, 0x67, + 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x50, 0x61, 0x79, 0x6c, 0x6f, + 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x67, 0x61, 0x74, 0x65, + 0x77, 0x61, 0x79, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x47, 0x0a, 0x0a, 0x48, 0x65, 0x61, + 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x1a, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, + 0x79, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x48, 0x65, + 0x61, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x12, 0x44, 0x0a, 0x09, 0x50, 0x75, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, + 0x19, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x50, 0x75, 0x74, 0x4f, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x67, 0x61, 0x74, + 0x65, 0x77, 0x61, 0x79, 0x2e, 0x50, 0x75, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4c, 0x0a, 0x0f, 0x50, 0x75, 0x74, 0x4f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x19, 0x2e, 0x67, 0x61, + 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x50, 0x75, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, - 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x6f, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, - 0x65, 0x73, 0x12, 0x1c, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x1d, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, - 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x4e, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, - 0x12, 0x1d, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x1e, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x4e, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, - 0x12, 0x1d, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x1e, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x45, 0x0a, 0x0a, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x1a, 0x2e, - 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x6f, 0x6b, 0x65, - 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x67, 0x61, 0x74, 0x65, - 0x77, 0x61, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, 0x0a, 0x0b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1b, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x48, 0x0a, 0x0b, 0x54, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, - 0x1b, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x54, 0x6f, 0x67, 0x67, 0x6c, 0x65, + 0x2e, 0x50, 0x75, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x28, 0x01, 0x12, 0x65, 0x0a, 0x14, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, + 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x24, + 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, + 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x52, + 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x74, + 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x53, 0x0a, + 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x12, + 0x1e, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x1f, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x12, 0x50, 0x0a, 0x0d, 0x53, 0x74, 0x6f, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x65, 0x72, 0x12, 0x1d, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x53, 0x74, + 0x6f, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x53, 0x74, 0x6f, + 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x12, 0x42, 0x0a, 0x09, 0x53, 0x74, 0x61, 0x72, 0x74, 0x54, 0x61, 0x73, + 0x6b, 0x12, 0x19, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x53, 0x74, 0x61, 0x72, + 0x74, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x67, + 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x54, 0x61, 0x73, 0x6b, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3c, 0x0a, 0x07, 0x45, 0x6e, 0x64, 0x54, + 0x61, 0x73, 0x6b, 0x12, 0x17, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x45, 0x6e, + 0x64, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x67, + 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x45, 0x6e, 0x64, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x42, 0x0a, 0x09, 0x53, 0x74, 0x6f, 0x70, 0x54, 0x61, + 0x73, 0x6b, 0x73, 0x12, 0x19, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x53, 0x74, + 0x6f, 0x70, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, + 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x54, 0x61, 0x73, + 0x6b, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x42, 0x0a, 0x09, 0x4c, 0x69, + 0x73, 0x74, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x12, 0x19, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, + 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x54, + 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x4f, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x75, + 0x62, 0x12, 0x1f, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x4f, + 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x75, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x47, 0x65, 0x74, + 0x4f, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x75, 0x62, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x45, 0x0a, 0x0a, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x53, 0x74, + 0x75, 0x62, 0x12, 0x1a, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x44, 0x65, 0x70, + 0x6c, 0x6f, 0x79, 0x53, 0x74, 0x75, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, + 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x53, + 0x74, 0x75, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x06, 0x47, + 0x65, 0x74, 0x55, 0x52, 0x4c, 0x12, 0x16, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, + 0x47, 0x65, 0x74, 0x55, 0x52, 0x4c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, + 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x52, 0x4c, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x54, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x65, + 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x1f, 0x2e, 0x67, 0x61, 0x74, 0x65, + 0x77, 0x61, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x67, 0x61, 0x74, + 0x65, 0x77, 0x61, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x51, 0x0a, 0x0e, + 0x53, 0x74, 0x6f, 0x70, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x1e, + 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x44, 0x65, 0x70, + 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, + 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x44, 0x65, 0x70, + 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x57, 0x0a, 0x10, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, + 0x65, 0x6e, 0x74, 0x12, 0x20, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x42, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, + 0x50, 0x6f, 0x6f, 0x6c, 0x73, 0x12, 0x19, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, + 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x6f, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x1a, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, + 0x6f, 0x6f, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x0c, + 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x73, 0x12, 0x1c, 0x2e, 0x67, + 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, + 0x6e, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x67, 0x61, 0x74, + 0x65, 0x77, 0x61, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x0d, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x12, 0x1d, 0x2e, 0x67, 0x61, 0x74, + 0x65, 0x77, 0x61, 0x79, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, + 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x67, 0x61, 0x74, 0x65, + 0x77, 0x61, 0x79, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x0d, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x12, 0x1d, 0x2e, 0x67, 0x61, 0x74, + 0x65, 0x77, 0x61, 0x79, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, + 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x67, 0x61, 0x74, 0x65, + 0x77, 0x61, 0x79, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x45, 0x0a, 0x0a, 0x4c, 0x69, 0x73, + 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x1a, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, + 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x48, 0x0a, 0x0b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, + 0x1b, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x67, - 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x54, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x54, 0x6f, 0x6b, - 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, 0x0a, 0x0b, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1b, 0x2e, 0x67, 0x61, 0x74, 0x65, - 0x77, 0x61, 0x79, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, + 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x6f, 0x6b, + 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, 0x0a, 0x0b, 0x54, 0x6f, + 0x67, 0x67, 0x6c, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1b, 0x2e, 0x67, 0x61, 0x74, 0x65, + 0x77, 0x61, 0x79, 0x2e, 0x54, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, - 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x23, 0x5a, 0x21, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x62, 0x65, 0x61, 0x6d, 0x2d, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x62, 0x65, - 0x74, 0x61, 0x39, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x2e, 0x54, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, 0x0a, 0x0b, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x6f, + 0x6b, 0x65, 0x6e, 0x12, 0x1b, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x1c, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, + 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x73, 0x12, 0x1b, 0x2e, + 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x6f, 0x72, 0x6b, + 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x67, 0x61, 0x74, + 0x65, 0x77, 0x61, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x0c, 0x43, 0x6f, 0x72, 0x64, + 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x12, 0x1c, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, + 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x64, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, + 0x2e, 0x43, 0x6f, 0x72, 0x64, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x51, 0x0a, 0x0e, 0x55, 0x6e, 0x63, 0x6f, 0x72, 0x64, 0x6f, + 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x12, 0x1e, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, + 0x79, 0x2e, 0x55, 0x6e, 0x63, 0x6f, 0x72, 0x64, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, + 0x79, 0x2e, 0x55, 0x6e, 0x63, 0x6f, 0x72, 0x64, 0x6f, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, 0x0a, 0x0b, 0x44, 0x72, 0x61, 0x69, + 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x12, 0x1b, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, + 0x79, 0x2e, 0x44, 0x72, 0x61, 0x69, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x44, + 0x72, 0x61, 0x69, 0x6e, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x42, 0x23, 0x5a, 0x21, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x62, 0x65, 0x61, 0x6d, 0x2d, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x62, 0x65, 0x74, 0x61, + 0x39, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -5053,7 +5678,7 @@ func file_gateway_proto_rawDescGZIP() []byte { } var file_gateway_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_gateway_proto_msgTypes = make([]protoimpl.MessageInfo, 68) +var file_gateway_proto_msgTypes = make([]protoimpl.MessageInfo, 77) var file_gateway_proto_goTypes = []interface{}{ (ReplaceObjectContentOperation)(0), // 0: gateway.ReplaceObjectContentOperation (*AuthorizeRequest)(nil), // 1: gateway.AuthorizeRequest @@ -5120,104 +5745,123 @@ var file_gateway_proto_goTypes = []interface{}{ (*DeleteTokenResponse)(nil), // 62: gateway.DeleteTokenResponse (*GetURLRequest)(nil), // 63: gateway.GetURLRequest (*GetURLResponse)(nil), // 64: gateway.GetURLResponse - nil, // 65: gateway.ListTasksRequest.FiltersEntry - nil, // 66: gateway.ListDeploymentsRequest.FiltersEntry - nil, // 67: gateway.ListPoolsRequest.FiltersEntry - nil, // 68: gateway.ListMachinesResponse.GpusEntry - (*timestamppb.Timestamp)(nil), // 69: google.protobuf.Timestamp + (*Worker)(nil), // 65: gateway.Worker + (*ListWorkersRequest)(nil), // 66: gateway.ListWorkersRequest + (*ListWorkersResponse)(nil), // 67: gateway.ListWorkersResponse + (*CordonWorkerRequest)(nil), // 68: gateway.CordonWorkerRequest + (*CordonWorkerResponse)(nil), // 69: gateway.CordonWorkerResponse + (*UncordonWorkerRequest)(nil), // 70: gateway.UncordonWorkerRequest + (*UncordonWorkerResponse)(nil), // 71: gateway.UncordonWorkerResponse + (*DrainWorkerRequest)(nil), // 72: gateway.DrainWorkerRequest + (*DrainWorkerResponse)(nil), // 73: gateway.DrainWorkerResponse + nil, // 74: gateway.ListTasksRequest.FiltersEntry + nil, // 75: gateway.ListDeploymentsRequest.FiltersEntry + nil, // 76: gateway.ListPoolsRequest.FiltersEntry + nil, // 77: gateway.ListMachinesResponse.GpusEntry + (*timestamppb.Timestamp)(nil), // 78: google.protobuf.Timestamp } var file_gateway_proto_depIdxs = []int32{ 5, // 0: gateway.HeadObjectResponse.object_metadata:type_name -> gateway.ObjectMetadata 5, // 1: gateway.PutObjectRequest.object_metadata:type_name -> gateway.ObjectMetadata 0, // 2: gateway.ReplaceObjectContentRequest.op:type_name -> gateway.ReplaceObjectContentOperation - 69, // 3: gateway.Container.scheduled_at:type_name -> google.protobuf.Timestamp + 78, // 3: gateway.Container.scheduled_at:type_name -> google.protobuf.Timestamp 12, // 4: gateway.ListContainersResponse.containers:type_name -> gateway.Container - 65, // 5: gateway.ListTasksRequest.filters:type_name -> gateway.ListTasksRequest.FiltersEntry - 69, // 6: gateway.Task.started_at:type_name -> google.protobuf.Timestamp - 69, // 7: gateway.Task.ended_at:type_name -> google.protobuf.Timestamp - 69, // 8: gateway.Task.created_at:type_name -> google.protobuf.Timestamp - 69, // 9: gateway.Task.updated_at:type_name -> google.protobuf.Timestamp + 74, // 5: gateway.ListTasksRequest.filters:type_name -> gateway.ListTasksRequest.FiltersEntry + 78, // 6: gateway.Task.started_at:type_name -> google.protobuf.Timestamp + 78, // 7: gateway.Task.ended_at:type_name -> google.protobuf.Timestamp + 78, // 8: gateway.Task.created_at:type_name -> google.protobuf.Timestamp + 78, // 9: gateway.Task.updated_at:type_name -> google.protobuf.Timestamp 23, // 10: gateway.ListTasksResponse.tasks:type_name -> gateway.Task 28, // 11: gateway.Volume.config:type_name -> gateway.MountPointConfig 27, // 12: gateway.GetOrCreateStubRequest.volumes:type_name -> gateway.Volume 29, // 13: gateway.GetOrCreateStubRequest.secrets:type_name -> gateway.SecretVar 30, // 14: gateway.GetOrCreateStubRequest.autoscaler:type_name -> gateway.Autoscaler 31, // 15: gateway.GetOrCreateStubRequest.task_policy:type_name -> gateway.TaskPolicy - 69, // 16: gateway.Deployment.created_at:type_name -> google.protobuf.Timestamp - 69, // 17: gateway.Deployment.updated_at:type_name -> google.protobuf.Timestamp - 66, // 18: gateway.ListDeploymentsRequest.filters:type_name -> gateway.ListDeploymentsRequest.FiltersEntry + 78, // 16: gateway.Deployment.created_at:type_name -> google.protobuf.Timestamp + 78, // 17: gateway.Deployment.updated_at:type_name -> google.protobuf.Timestamp + 75, // 18: gateway.ListDeploymentsRequest.filters:type_name -> gateway.ListDeploymentsRequest.FiltersEntry 36, // 19: gateway.ListDeploymentsResponse.deployments:type_name -> gateway.Deployment - 67, // 20: gateway.ListPoolsRequest.filters:type_name -> gateway.ListPoolsRequest.FiltersEntry + 76, // 20: gateway.ListPoolsRequest.filters:type_name -> gateway.ListPoolsRequest.FiltersEntry 43, // 21: gateway.ListPoolsResponse.pools:type_name -> gateway.Pool 47, // 22: gateway.Machine.machine_metrics:type_name -> gateway.MachineMetrics 46, // 23: gateway.ListMachinesResponse.machines:type_name -> gateway.Machine - 68, // 24: gateway.ListMachinesResponse.gpus:type_name -> gateway.ListMachinesResponse.GpusEntry + 77, // 24: gateway.ListMachinesResponse.gpus:type_name -> gateway.ListMachinesResponse.GpusEntry 46, // 25: gateway.CreateMachineResponse.machine:type_name -> gateway.Machine - 69, // 26: gateway.Token.created_at:type_name -> google.protobuf.Timestamp - 69, // 27: gateway.Token.updated_at:type_name -> google.protobuf.Timestamp + 78, // 26: gateway.Token.created_at:type_name -> google.protobuf.Timestamp + 78, // 27: gateway.Token.updated_at:type_name -> google.protobuf.Timestamp 54, // 28: gateway.ListTokensResponse.tokens:type_name -> gateway.Token 54, // 29: gateway.CreateTokenResponse.token:type_name -> gateway.Token 54, // 30: gateway.ToggleTokenResponse.token:type_name -> gateway.Token - 21, // 31: gateway.ListTasksRequest.FiltersEntry.value:type_name -> gateway.StringList - 21, // 32: gateway.ListDeploymentsRequest.FiltersEntry.value:type_name -> gateway.StringList - 21, // 33: gateway.ListPoolsRequest.FiltersEntry.value:type_name -> gateway.StringList - 1, // 34: gateway.GatewayService.Authorize:input_type -> gateway.AuthorizeRequest - 3, // 35: gateway.GatewayService.SignPayload:input_type -> gateway.SignPayloadRequest - 6, // 36: gateway.GatewayService.HeadObject:input_type -> gateway.HeadObjectRequest - 8, // 37: gateway.GatewayService.PutObject:input_type -> gateway.PutObjectRequest - 8, // 38: gateway.GatewayService.PutObjectStream:input_type -> gateway.PutObjectRequest - 10, // 39: gateway.GatewayService.ReplaceObjectContent:input_type -> gateway.ReplaceObjectContentRequest - 13, // 40: gateway.GatewayService.ListContainers:input_type -> gateway.ListContainersRequest - 15, // 41: gateway.GatewayService.StopContainer:input_type -> gateway.StopContainerRequest - 17, // 42: gateway.GatewayService.StartTask:input_type -> gateway.StartTaskRequest - 19, // 43: gateway.GatewayService.EndTask:input_type -> gateway.EndTaskRequest - 25, // 44: gateway.GatewayService.StopTasks:input_type -> gateway.StopTasksRequest - 22, // 45: gateway.GatewayService.ListTasks:input_type -> gateway.ListTasksRequest - 32, // 46: gateway.GatewayService.GetOrCreateStub:input_type -> gateway.GetOrCreateStubRequest - 34, // 47: gateway.GatewayService.DeployStub:input_type -> gateway.DeployStubRequest - 63, // 48: gateway.GatewayService.GetURL:input_type -> gateway.GetURLRequest - 37, // 49: gateway.GatewayService.ListDeployments:input_type -> gateway.ListDeploymentsRequest - 39, // 50: gateway.GatewayService.StopDeployment:input_type -> gateway.StopDeploymentRequest - 41, // 51: gateway.GatewayService.DeleteDeployment:input_type -> gateway.DeleteDeploymentRequest - 44, // 52: gateway.GatewayService.ListPools:input_type -> gateway.ListPoolsRequest - 48, // 53: gateway.GatewayService.ListMachines:input_type -> gateway.ListMachinesRequest - 50, // 54: gateway.GatewayService.CreateMachine:input_type -> gateway.CreateMachineRequest - 52, // 55: gateway.GatewayService.DeleteMachine:input_type -> gateway.DeleteMachineRequest - 55, // 56: gateway.GatewayService.ListTokens:input_type -> gateway.ListTokensRequest - 57, // 57: gateway.GatewayService.CreateToken:input_type -> gateway.CreateTokenRequest - 59, // 58: gateway.GatewayService.ToggleToken:input_type -> gateway.ToggleTokenRequest - 61, // 59: gateway.GatewayService.DeleteToken:input_type -> gateway.DeleteTokenRequest - 2, // 60: gateway.GatewayService.Authorize:output_type -> gateway.AuthorizeResponse - 4, // 61: gateway.GatewayService.SignPayload:output_type -> gateway.SignPayloadResponse - 7, // 62: gateway.GatewayService.HeadObject:output_type -> gateway.HeadObjectResponse - 9, // 63: gateway.GatewayService.PutObject:output_type -> gateway.PutObjectResponse - 9, // 64: gateway.GatewayService.PutObjectStream:output_type -> gateway.PutObjectResponse - 11, // 65: gateway.GatewayService.ReplaceObjectContent:output_type -> gateway.ReplaceObjectContentResponse - 14, // 66: gateway.GatewayService.ListContainers:output_type -> gateway.ListContainersResponse - 16, // 67: gateway.GatewayService.StopContainer:output_type -> gateway.StopContainerResponse - 18, // 68: gateway.GatewayService.StartTask:output_type -> gateway.StartTaskResponse - 20, // 69: gateway.GatewayService.EndTask:output_type -> gateway.EndTaskResponse - 26, // 70: gateway.GatewayService.StopTasks:output_type -> gateway.StopTasksResponse - 24, // 71: gateway.GatewayService.ListTasks:output_type -> gateway.ListTasksResponse - 33, // 72: gateway.GatewayService.GetOrCreateStub:output_type -> gateway.GetOrCreateStubResponse - 35, // 73: gateway.GatewayService.DeployStub:output_type -> gateway.DeployStubResponse - 64, // 74: gateway.GatewayService.GetURL:output_type -> gateway.GetURLResponse - 38, // 75: gateway.GatewayService.ListDeployments:output_type -> gateway.ListDeploymentsResponse - 40, // 76: gateway.GatewayService.StopDeployment:output_type -> gateway.StopDeploymentResponse - 42, // 77: gateway.GatewayService.DeleteDeployment:output_type -> gateway.DeleteDeploymentResponse - 45, // 78: gateway.GatewayService.ListPools:output_type -> gateway.ListPoolsResponse - 49, // 79: gateway.GatewayService.ListMachines:output_type -> gateway.ListMachinesResponse - 51, // 80: gateway.GatewayService.CreateMachine:output_type -> gateway.CreateMachineResponse - 53, // 81: gateway.GatewayService.DeleteMachine:output_type -> gateway.DeleteMachineResponse - 56, // 82: gateway.GatewayService.ListTokens:output_type -> gateway.ListTokensResponse - 58, // 83: gateway.GatewayService.CreateToken:output_type -> gateway.CreateTokenResponse - 60, // 84: gateway.GatewayService.ToggleToken:output_type -> gateway.ToggleTokenResponse - 62, // 85: gateway.GatewayService.DeleteToken:output_type -> gateway.DeleteTokenResponse - 60, // [60:86] is the sub-list for method output_type - 34, // [34:60] is the sub-list for method input_type - 34, // [34:34] is the sub-list for extension type_name - 34, // [34:34] is the sub-list for extension extendee - 0, // [0:34] is the sub-list for field type_name + 12, // 31: gateway.Worker.active_containers:type_name -> gateway.Container + 65, // 32: gateway.ListWorkersResponse.workers:type_name -> gateway.Worker + 21, // 33: gateway.ListTasksRequest.FiltersEntry.value:type_name -> gateway.StringList + 21, // 34: gateway.ListDeploymentsRequest.FiltersEntry.value:type_name -> gateway.StringList + 21, // 35: gateway.ListPoolsRequest.FiltersEntry.value:type_name -> gateway.StringList + 1, // 36: gateway.GatewayService.Authorize:input_type -> gateway.AuthorizeRequest + 3, // 37: gateway.GatewayService.SignPayload:input_type -> gateway.SignPayloadRequest + 6, // 38: gateway.GatewayService.HeadObject:input_type -> gateway.HeadObjectRequest + 8, // 39: gateway.GatewayService.PutObject:input_type -> gateway.PutObjectRequest + 8, // 40: gateway.GatewayService.PutObjectStream:input_type -> gateway.PutObjectRequest + 10, // 41: gateway.GatewayService.ReplaceObjectContent:input_type -> gateway.ReplaceObjectContentRequest + 13, // 42: gateway.GatewayService.ListContainers:input_type -> gateway.ListContainersRequest + 15, // 43: gateway.GatewayService.StopContainer:input_type -> gateway.StopContainerRequest + 17, // 44: gateway.GatewayService.StartTask:input_type -> gateway.StartTaskRequest + 19, // 45: gateway.GatewayService.EndTask:input_type -> gateway.EndTaskRequest + 25, // 46: gateway.GatewayService.StopTasks:input_type -> gateway.StopTasksRequest + 22, // 47: gateway.GatewayService.ListTasks:input_type -> gateway.ListTasksRequest + 32, // 48: gateway.GatewayService.GetOrCreateStub:input_type -> gateway.GetOrCreateStubRequest + 34, // 49: gateway.GatewayService.DeployStub:input_type -> gateway.DeployStubRequest + 63, // 50: gateway.GatewayService.GetURL:input_type -> gateway.GetURLRequest + 37, // 51: gateway.GatewayService.ListDeployments:input_type -> gateway.ListDeploymentsRequest + 39, // 52: gateway.GatewayService.StopDeployment:input_type -> gateway.StopDeploymentRequest + 41, // 53: gateway.GatewayService.DeleteDeployment:input_type -> gateway.DeleteDeploymentRequest + 44, // 54: gateway.GatewayService.ListPools:input_type -> gateway.ListPoolsRequest + 48, // 55: gateway.GatewayService.ListMachines:input_type -> gateway.ListMachinesRequest + 50, // 56: gateway.GatewayService.CreateMachine:input_type -> gateway.CreateMachineRequest + 52, // 57: gateway.GatewayService.DeleteMachine:input_type -> gateway.DeleteMachineRequest + 55, // 58: gateway.GatewayService.ListTokens:input_type -> gateway.ListTokensRequest + 57, // 59: gateway.GatewayService.CreateToken:input_type -> gateway.CreateTokenRequest + 59, // 60: gateway.GatewayService.ToggleToken:input_type -> gateway.ToggleTokenRequest + 61, // 61: gateway.GatewayService.DeleteToken:input_type -> gateway.DeleteTokenRequest + 66, // 62: gateway.GatewayService.ListWorkers:input_type -> gateway.ListWorkersRequest + 68, // 63: gateway.GatewayService.CordonWorker:input_type -> gateway.CordonWorkerRequest + 70, // 64: gateway.GatewayService.UncordonWorker:input_type -> gateway.UncordonWorkerRequest + 72, // 65: gateway.GatewayService.DrainWorker:input_type -> gateway.DrainWorkerRequest + 2, // 66: gateway.GatewayService.Authorize:output_type -> gateway.AuthorizeResponse + 4, // 67: gateway.GatewayService.SignPayload:output_type -> gateway.SignPayloadResponse + 7, // 68: gateway.GatewayService.HeadObject:output_type -> gateway.HeadObjectResponse + 9, // 69: gateway.GatewayService.PutObject:output_type -> gateway.PutObjectResponse + 9, // 70: gateway.GatewayService.PutObjectStream:output_type -> gateway.PutObjectResponse + 11, // 71: gateway.GatewayService.ReplaceObjectContent:output_type -> gateway.ReplaceObjectContentResponse + 14, // 72: gateway.GatewayService.ListContainers:output_type -> gateway.ListContainersResponse + 16, // 73: gateway.GatewayService.StopContainer:output_type -> gateway.StopContainerResponse + 18, // 74: gateway.GatewayService.StartTask:output_type -> gateway.StartTaskResponse + 20, // 75: gateway.GatewayService.EndTask:output_type -> gateway.EndTaskResponse + 26, // 76: gateway.GatewayService.StopTasks:output_type -> gateway.StopTasksResponse + 24, // 77: gateway.GatewayService.ListTasks:output_type -> gateway.ListTasksResponse + 33, // 78: gateway.GatewayService.GetOrCreateStub:output_type -> gateway.GetOrCreateStubResponse + 35, // 79: gateway.GatewayService.DeployStub:output_type -> gateway.DeployStubResponse + 64, // 80: gateway.GatewayService.GetURL:output_type -> gateway.GetURLResponse + 38, // 81: gateway.GatewayService.ListDeployments:output_type -> gateway.ListDeploymentsResponse + 40, // 82: gateway.GatewayService.StopDeployment:output_type -> gateway.StopDeploymentResponse + 42, // 83: gateway.GatewayService.DeleteDeployment:output_type -> gateway.DeleteDeploymentResponse + 45, // 84: gateway.GatewayService.ListPools:output_type -> gateway.ListPoolsResponse + 49, // 85: gateway.GatewayService.ListMachines:output_type -> gateway.ListMachinesResponse + 51, // 86: gateway.GatewayService.CreateMachine:output_type -> gateway.CreateMachineResponse + 53, // 87: gateway.GatewayService.DeleteMachine:output_type -> gateway.DeleteMachineResponse + 56, // 88: gateway.GatewayService.ListTokens:output_type -> gateway.ListTokensResponse + 58, // 89: gateway.GatewayService.CreateToken:output_type -> gateway.CreateTokenResponse + 60, // 90: gateway.GatewayService.ToggleToken:output_type -> gateway.ToggleTokenResponse + 62, // 91: gateway.GatewayService.DeleteToken:output_type -> gateway.DeleteTokenResponse + 67, // 92: gateway.GatewayService.ListWorkers:output_type -> gateway.ListWorkersResponse + 69, // 93: gateway.GatewayService.CordonWorker:output_type -> gateway.CordonWorkerResponse + 71, // 94: gateway.GatewayService.UncordonWorker:output_type -> gateway.UncordonWorkerResponse + 73, // 95: gateway.GatewayService.DrainWorker:output_type -> gateway.DrainWorkerResponse + 66, // [66:96] is the sub-list for method output_type + 36, // [36:66] is the sub-list for method input_type + 36, // [36:36] is the sub-list for extension type_name + 36, // [36:36] is the sub-list for extension extendee + 0, // [0:36] is the sub-list for field type_name } func init() { file_gateway_proto_init() } @@ -5994,6 +6638,114 @@ func file_gateway_proto_init() { return nil } } + file_gateway_proto_msgTypes[64].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Worker); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gateway_proto_msgTypes[65].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListWorkersRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gateway_proto_msgTypes[66].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListWorkersResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gateway_proto_msgTypes[67].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CordonWorkerRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gateway_proto_msgTypes[68].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CordonWorkerResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gateway_proto_msgTypes[69].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UncordonWorkerRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gateway_proto_msgTypes[70].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UncordonWorkerResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gateway_proto_msgTypes[71].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DrainWorkerRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gateway_proto_msgTypes[72].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DrainWorkerResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } file_gateway_proto_msgTypes[26].OneofWrappers = []interface{}{} file_gateway_proto_msgTypes[53].OneofWrappers = []interface{}{} @@ -6003,7 +6755,7 @@ func file_gateway_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_gateway_proto_rawDesc, NumEnums: 1, - NumMessages: 68, + NumMessages: 77, NumExtensions: 0, NumServices: 1, }, diff --git a/proto/gateway_grpc.pb.go b/proto/gateway_grpc.pb.go index 5f0453b71..6d09a920b 100644 --- a/proto/gateway_grpc.pb.go +++ b/proto/gateway_grpc.pb.go @@ -45,6 +45,10 @@ const ( GatewayService_CreateToken_FullMethodName = "/gateway.GatewayService/CreateToken" GatewayService_ToggleToken_FullMethodName = "/gateway.GatewayService/ToggleToken" GatewayService_DeleteToken_FullMethodName = "/gateway.GatewayService/DeleteToken" + GatewayService_ListWorkers_FullMethodName = "/gateway.GatewayService/ListWorkers" + GatewayService_CordonWorker_FullMethodName = "/gateway.GatewayService/CordonWorker" + GatewayService_UncordonWorker_FullMethodName = "/gateway.GatewayService/UncordonWorker" + GatewayService_DrainWorker_FullMethodName = "/gateway.GatewayService/DrainWorker" ) // GatewayServiceClient is the client API for GatewayService service. @@ -86,6 +90,11 @@ type GatewayServiceClient interface { CreateToken(ctx context.Context, in *CreateTokenRequest, opts ...grpc.CallOption) (*CreateTokenResponse, error) ToggleToken(ctx context.Context, in *ToggleTokenRequest, opts ...grpc.CallOption) (*ToggleTokenResponse, error) DeleteToken(ctx context.Context, in *DeleteTokenRequest, opts ...grpc.CallOption) (*DeleteTokenResponse, error) + // Workers + ListWorkers(ctx context.Context, in *ListWorkersRequest, opts ...grpc.CallOption) (*ListWorkersResponse, error) + CordonWorker(ctx context.Context, in *CordonWorkerRequest, opts ...grpc.CallOption) (*CordonWorkerResponse, error) + UncordonWorker(ctx context.Context, in *UncordonWorkerRequest, opts ...grpc.CallOption) (*UncordonWorkerResponse, error) + DrainWorker(ctx context.Context, in *DrainWorkerRequest, opts ...grpc.CallOption) (*DrainWorkerResponse, error) } type gatewayServiceClient struct { @@ -355,6 +364,42 @@ func (c *gatewayServiceClient) DeleteToken(ctx context.Context, in *DeleteTokenR return out, nil } +func (c *gatewayServiceClient) ListWorkers(ctx context.Context, in *ListWorkersRequest, opts ...grpc.CallOption) (*ListWorkersResponse, error) { + out := new(ListWorkersResponse) + err := c.cc.Invoke(ctx, GatewayService_ListWorkers_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *gatewayServiceClient) CordonWorker(ctx context.Context, in *CordonWorkerRequest, opts ...grpc.CallOption) (*CordonWorkerResponse, error) { + out := new(CordonWorkerResponse) + err := c.cc.Invoke(ctx, GatewayService_CordonWorker_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *gatewayServiceClient) UncordonWorker(ctx context.Context, in *UncordonWorkerRequest, opts ...grpc.CallOption) (*UncordonWorkerResponse, error) { + out := new(UncordonWorkerResponse) + err := c.cc.Invoke(ctx, GatewayService_UncordonWorker_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *gatewayServiceClient) DrainWorker(ctx context.Context, in *DrainWorkerRequest, opts ...grpc.CallOption) (*DrainWorkerResponse, error) { + out := new(DrainWorkerResponse) + err := c.cc.Invoke(ctx, GatewayService_DrainWorker_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // GatewayServiceServer is the server API for GatewayService service. // All implementations must embed UnimplementedGatewayServiceServer // for forward compatibility @@ -394,6 +439,11 @@ type GatewayServiceServer interface { CreateToken(context.Context, *CreateTokenRequest) (*CreateTokenResponse, error) ToggleToken(context.Context, *ToggleTokenRequest) (*ToggleTokenResponse, error) DeleteToken(context.Context, *DeleteTokenRequest) (*DeleteTokenResponse, error) + // Workers + ListWorkers(context.Context, *ListWorkersRequest) (*ListWorkersResponse, error) + CordonWorker(context.Context, *CordonWorkerRequest) (*CordonWorkerResponse, error) + UncordonWorker(context.Context, *UncordonWorkerRequest) (*UncordonWorkerResponse, error) + DrainWorker(context.Context, *DrainWorkerRequest) (*DrainWorkerResponse, error) mustEmbedUnimplementedGatewayServiceServer() } @@ -479,6 +529,18 @@ func (UnimplementedGatewayServiceServer) ToggleToken(context.Context, *ToggleTok func (UnimplementedGatewayServiceServer) DeleteToken(context.Context, *DeleteTokenRequest) (*DeleteTokenResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method DeleteToken not implemented") } +func (UnimplementedGatewayServiceServer) ListWorkers(context.Context, *ListWorkersRequest) (*ListWorkersResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListWorkers not implemented") +} +func (UnimplementedGatewayServiceServer) CordonWorker(context.Context, *CordonWorkerRequest) (*CordonWorkerResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CordonWorker not implemented") +} +func (UnimplementedGatewayServiceServer) UncordonWorker(context.Context, *UncordonWorkerRequest) (*UncordonWorkerResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UncordonWorker not implemented") +} +func (UnimplementedGatewayServiceServer) DrainWorker(context.Context, *DrainWorkerRequest) (*DrainWorkerResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method DrainWorker not implemented") +} func (UnimplementedGatewayServiceServer) mustEmbedUnimplementedGatewayServiceServer() {} // UnsafeGatewayServiceServer may be embedded to opt out of forward compatibility for this service. @@ -968,6 +1030,78 @@ func _GatewayService_DeleteToken_Handler(srv interface{}, ctx context.Context, d return interceptor(ctx, in, info, handler) } +func _GatewayService_ListWorkers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListWorkersRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(GatewayServiceServer).ListWorkers(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: GatewayService_ListWorkers_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(GatewayServiceServer).ListWorkers(ctx, req.(*ListWorkersRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _GatewayService_CordonWorker_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CordonWorkerRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(GatewayServiceServer).CordonWorker(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: GatewayService_CordonWorker_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(GatewayServiceServer).CordonWorker(ctx, req.(*CordonWorkerRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _GatewayService_UncordonWorker_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UncordonWorkerRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(GatewayServiceServer).UncordonWorker(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: GatewayService_UncordonWorker_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(GatewayServiceServer).UncordonWorker(ctx, req.(*UncordonWorkerRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _GatewayService_DrainWorker_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DrainWorkerRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(GatewayServiceServer).DrainWorker(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: GatewayService_DrainWorker_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(GatewayServiceServer).DrainWorker(ctx, req.(*DrainWorkerRequest)) + } + return interceptor(ctx, in, info, handler) +} + // GatewayService_ServiceDesc is the grpc.ServiceDesc for GatewayService service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -1075,6 +1209,22 @@ var GatewayService_ServiceDesc = grpc.ServiceDesc{ MethodName: "DeleteToken", Handler: _GatewayService_DeleteToken_Handler, }, + { + MethodName: "ListWorkers", + Handler: _GatewayService_ListWorkers_Handler, + }, + { + MethodName: "CordonWorker", + Handler: _GatewayService_CordonWorker_Handler, + }, + { + MethodName: "UncordonWorker", + Handler: _GatewayService_UncordonWorker_Handler, + }, + { + MethodName: "DrainWorker", + Handler: _GatewayService_DrainWorker_Handler, + }, }, Streams: []grpc.StreamDesc{ { diff --git a/sdk/src/beta9/cli/main.py b/sdk/src/beta9/cli/main.py index d2ece3520..8a7168825 100644 --- a/sdk/src/beta9/cli/main.py +++ b/sdk/src/beta9/cli/main.py @@ -8,7 +8,19 @@ from ..channel import handle_grpc_error, prompt_first_auth from ..config import SDKSettings, is_config_empty, set_settings -from . import config, container, deployment, machine, pool, secret, serve, task, token, volume +from . import ( + config, + container, + deployment, + machine, + pool, + secret, + serve, + task, + token, + volume, + worker, +) from .extraclick import CLICK_CONTEXT_SETTINGS, ClickCommonGroup, CommandGroupCollection click.formatting.FORCED_WIDTH = shutil.get_terminal_size().columns @@ -87,6 +99,7 @@ def load_cli(check_config=True, **kwargs: Any) -> CLI: cli.register(machine) cli.register(secret) cli.register(token) + cli.register(worker) if check_config: cli.check_config() diff --git a/sdk/src/beta9/cli/worker.py b/sdk/src/beta9/cli/worker.py new file mode 100644 index 000000000..2b9d17797 --- /dev/null +++ b/sdk/src/beta9/cli/worker.py @@ -0,0 +1,194 @@ +import click +from betterproto import Casing +from rich.table import Column, Table, box + +from .. import terminal +from ..channel import ServiceClient +from ..cli import extraclick +from ..clients.gateway import ( + CordonWorkerRequest, + DrainWorkerRequest, + ListWorkersRequest, + ListWorkersResponse, + UncordonWorkerRequest, +) +from .extraclick import ClickCommonGroup, ClickManagementGroup + + +@click.group(cls=ClickCommonGroup) +def common(**_): + pass + + +@click.group( + name="worker", + help="Manage workers.", + cls=ClickManagementGroup, +) +def management(): + pass + + +@management.command( + name="list", + help="List all workers.", + epilog=""" + Examples: + + # List workers and output in JSON format + {cli_name} worker list --format json + \b + """, +) +@click.option( + "--format", + type=click.Choice(("table", "json")), + default="table", + show_default=True, + help="Change the format of the output.", +) +@extraclick.pass_service_client +def list_workers( + service: ServiceClient, + format: str, +): + res: ListWorkersResponse + res = service.gateway.list_workers(ListWorkersRequest()) + + if not res.ok: + terminal.error(res.err_msg) + + if format == "json": + workers = [d.to_dict(casing=Casing.SNAKE) for d in res.workers] # type:ignore + terminal.print_json(workers) + return + + table = Table( + Column("ID"), + Column("Pool"), + Column("Status"), + Column("Machine ID"), + Column("Priority"), + Column("CPU"), + Column("Memory"), + Column("GPUs"), + Column("CPU Available"), + Column("Memory Available"), + Column("GPUs Available"), + Column("Containers"), + box=box.SIMPLE, + ) + + for worker in res.workers: + table.add_row( + worker.id, + worker.pool_name, + { + "available": f"[green]{worker.status}[/green]", + "pending": f"[yellow]{worker.status}[/yellow]", + "disabled": f"[red]{worker.status}[/red]", + }.get(worker.status, worker.status), + worker.machine_id if worker.machine_id else "-", + str(worker.priority), + f"{worker.total_cpu:,}m" if worker.total_cpu > 0 else "-", + terminal.humanize_memory(worker.total_memory * 1024 * 1024), + str(worker.total_gpu_count), + f"{worker.free_cpu:,}m", + terminal.humanize_memory(worker.free_memory * 1024 * 1024), + str(worker.free_gpu_count), + str(len(worker.active_containers)), + ) + + table.add_section() + table.add_row(f"[bold]{len(res.workers)} items") + + terminal.print(table) + + +@management.command( + name="cordon", + help=""" + Cordon a worker. When a worker is cordoned, it will not accept new container requests. + It will only be used to run existing containers. This is useful when you want to + gracefully remove a worker from the pool. + """, + epilog=""" + Examples: + + {cli_name} worker cordon 675a65c3 + \b + """, +) +@click.argument( + "worker_id", + nargs=1, + required=True, +) +@extraclick.pass_service_client +def cordon_worker(service: ServiceClient, worker_id: str): + res = service.gateway.cordon_worker(CordonWorkerRequest(worker_id=worker_id)) + if not res.ok: + return terminal.error(f"Failed to cordon worker: {res.err_msg}") + + terminal.success(f"Worker {worker_id} has been cordoned.") + + +@management.command( + name="uncordon", + help="Uncordon a worker.", + epilog=""" + Examples: + + {cli_name} worker uncordon 675a65c3 + \b + """, +) +@click.argument( + "worker_id", + nargs=1, + required=True, +) +@extraclick.pass_service_client +def uncordon_worker(service: ServiceClient, worker_id: str): + res = service.gateway.uncordon_worker(UncordonWorkerRequest(worker_id=worker_id)) + if not res.ok: + return terminal.error(f"Failed to uncordon worker: {res.err_msg}") + + terminal.success(f"Worker {worker_id} has been uncordoned.") + + +@management.command( + name="drain", + help=""" + Drain a worker. When a worker is drained, all running containers on it will be stopped. + """, + epilog=""" + Examples: + + {cli_name} worker drain 675a65c3 + \b + """, +) +@click.argument( + "worker_id", + nargs=1, + required=True, +) +@extraclick.pass_service_client +def drain_worker(service: ServiceClient, worker_id: str): + terminal.warn("Draining a worker will stop all running containers on it.") + + while True: + answer = terminal.prompt(text="Are you sure you want to continue? (y/n)") + if not answer: + continue + if answer.lower() in ("yes", "y"): + break + if answer.lower() in ("no", "n"): + return terminal.print("Aborted.") + + res = service.gateway.drain_worker(DrainWorkerRequest(worker_id=worker_id)) + if not res.ok: + return terminal.error(res.err_msg) + + terminal.success(f"Worker {worker_id} has been drained.") diff --git a/sdk/src/beta9/clients/gateway/__init__.py b/sdk/src/beta9/clients/gateway/__init__.py index 139c8a673..9e6b54f67 100644 --- a/sdk/src/beta9/clients/gateway/__init__.py +++ b/sdk/src/beta9/clients/gateway/__init__.py @@ -529,6 +529,68 @@ class GetUrlResponse(betterproto.Message): url: str = betterproto.string_field(3) +@dataclass(eq=False, repr=False) +class Worker(betterproto.Message): + id: str = betterproto.string_field(1) + status: str = betterproto.string_field(2) + gpu: str = betterproto.string_field(3) + pool_name: str = betterproto.string_field(4) + machine_id: str = betterproto.string_field(5) + priority: int = betterproto.int32_field(6) + total_cpu: int = betterproto.int64_field(7) + total_memory: int = betterproto.int64_field(8) + total_gpu_count: int = betterproto.uint32_field(9) + free_cpu: int = betterproto.int64_field(10) + free_memory: int = betterproto.int64_field(11) + free_gpu_count: int = betterproto.uint32_field(12) + active_containers: List["Container"] = betterproto.message_field(13) + + +@dataclass(eq=False, repr=False) +class ListWorkersRequest(betterproto.Message): + pass + + +@dataclass(eq=False, repr=False) +class ListWorkersResponse(betterproto.Message): + ok: bool = betterproto.bool_field(1) + err_msg: str = betterproto.string_field(2) + workers: List["Worker"] = betterproto.message_field(3) + + +@dataclass(eq=False, repr=False) +class CordonWorkerRequest(betterproto.Message): + worker_id: str = betterproto.string_field(1) + + +@dataclass(eq=False, repr=False) +class CordonWorkerResponse(betterproto.Message): + ok: bool = betterproto.bool_field(1) + err_msg: str = betterproto.string_field(2) + + +@dataclass(eq=False, repr=False) +class UncordonWorkerRequest(betterproto.Message): + worker_id: str = betterproto.string_field(1) + + +@dataclass(eq=False, repr=False) +class UncordonWorkerResponse(betterproto.Message): + ok: bool = betterproto.bool_field(1) + err_msg: str = betterproto.string_field(2) + + +@dataclass(eq=False, repr=False) +class DrainWorkerRequest(betterproto.Message): + worker_id: str = betterproto.string_field(1) + + +@dataclass(eq=False, repr=False) +class DrainWorkerResponse(betterproto.Message): + ok: bool = betterproto.bool_field(1) + err_msg: str = betterproto.string_field(2) + + class GatewayServiceStub(SyncServiceStub): def authorize(self, authorize_request: "AuthorizeRequest") -> "AuthorizeResponse": return self._unary_unary( @@ -751,3 +813,39 @@ def delete_token( DeleteTokenRequest, DeleteTokenResponse, )(delete_token_request) + + def list_workers( + self, list_workers_request: "ListWorkersRequest" + ) -> "ListWorkersResponse": + return self._unary_unary( + "/gateway.GatewayService/ListWorkers", + ListWorkersRequest, + ListWorkersResponse, + )(list_workers_request) + + def cordon_worker( + self, cordon_worker_request: "CordonWorkerRequest" + ) -> "CordonWorkerResponse": + return self._unary_unary( + "/gateway.GatewayService/CordonWorker", + CordonWorkerRequest, + CordonWorkerResponse, + )(cordon_worker_request) + + def uncordon_worker( + self, uncordon_worker_request: "UncordonWorkerRequest" + ) -> "UncordonWorkerResponse": + return self._unary_unary( + "/gateway.GatewayService/UncordonWorker", + UncordonWorkerRequest, + UncordonWorkerResponse, + )(uncordon_worker_request) + + def drain_worker( + self, drain_worker_request: "DrainWorkerRequest" + ) -> "DrainWorkerResponse": + return self._unary_unary( + "/gateway.GatewayService/DrainWorker", + DrainWorkerRequest, + DrainWorkerResponse, + )(drain_worker_request)