From b7c075b8a5a78d6641e557b86904e203f27a85c8 Mon Sep 17 00:00:00 2001 From: Samuel N Cui Date: Fri, 6 Oct 2023 07:53:14 +0800 Subject: [PATCH] perf: optimize job update refresh performance --- apis/converts.go | 12 +- apis/job_get_log.go | 2 +- apis/job_list.go | 6 + entity/job.go | 4 + entity/job.pb.go | 291 +++++++++++++-------- entity/job.proto | 14 +- entity/service.pb.go | 459 ++++++++++++++++++--------------- entity/service.proto | 2 + entity/utils.go | 67 ++++- executor/job.go | 39 ++- frontend/src/api.ts | 11 +- frontend/src/entity/job.ts | 109 ++++++-- frontend/src/entity/service.ts | 34 ++- frontend/src/pages/jobs.tsx | 128 ++++++--- go.mod | 3 +- go.sum | 3 +- tools/pool.go | 25 ++ 17 files changed, 811 insertions(+), 398 deletions(-) create mode 100644 tools/pool.go diff --git a/apis/converts.go b/apis/converts.go index 05c6728..00e6f6c 100644 --- a/apis/converts.go +++ b/apis/converts.go @@ -69,12 +69,12 @@ func convertJobs(jobs ...*executor.Job) []*entity.Job { converted := make([]*entity.Job, 0, len(jobs)) for _, job := range jobs { converted = append(converted, &entity.Job{ - Id: job.ID, - Status: job.Status, - Priority: job.Priority, - CreateTime: job.CreateTime.Unix(), - UpdateTime: job.UpdateTime.Unix(), - State: job.State, + Id: job.ID, + Status: job.Status, + Priority: job.Priority, + CreateTimeNs: job.CreateTime.UnixNano(), + UpdateTimeNs: job.UpdateTime.UnixNano(), + State: job.State, }) } return converted diff --git a/apis/job_get_log.go b/apis/job_get_log.go index d2c1f51..daf69c4 100644 --- a/apis/job_get_log.go +++ b/apis/job_get_log.go @@ -28,5 +28,5 @@ func (api *API) JobGetLog(ctx context.Context, req *entity.JobGetLogRequest) (*e return nil, fmt.Errorf("read log fail, %w", err) } - return &entity.JobGetLogReply{Logs: buf}, nil + return &entity.JobGetLogReply{Logs: buf, Offset: req.GetOffset() + int64(len(buf))}, nil } diff --git a/apis/job_list.go b/apis/job_list.go index 6b92adf..f028a79 100644 --- a/apis/job_list.go +++ b/apis/job_list.go @@ -21,6 +21,12 @@ func (api *API) JobList(ctx context.Context, req *entity.JobListRequest) (*entit return nil, err } return &entity.JobListReply{Jobs: convertJobs(jobs...)}, nil + case *entity.JobListRequest_RecentlyUpdate: + jobs, err := api.exe.ListRecentlyUpdateJob(ctx, param.RecentlyUpdate) + if err != nil { + return nil, err + } + return &entity.JobListReply{Jobs: convertJobs(jobs...)}, nil default: return nil, fmt.Errorf("unexpected param, %T", req.Param) } diff --git a/entity/job.go b/entity/job.go index 8724cb5..22821aa 100644 --- a/entity/job.go +++ b/entity/job.go @@ -5,6 +5,10 @@ import ( "database/sql/driver" ) +const ( + JobStatusVisible = 128 +) + var ( _ = sql.Scanner(&JobParam{}) _ = driver.Valuer(&JobParam{}) diff --git a/entity/job.pb.go b/entity/job.pb.go index 74be39a..422d0f8 100644 --- a/entity/job.pb.go +++ b/entity/job.pb.go @@ -28,7 +28,8 @@ const ( JobStatus_PENDING JobStatus = 2 // waiting in queue JobStatus_PROCESSING JobStatus = 3 JobStatus_COMPLETED JobStatus = 4 - JobStatus_FAILED JobStatus = 255 + JobStatus_FAILED JobStatus = 127 + JobStatus_DELETED JobStatus = 255 ) // Enum value maps for JobStatus. @@ -39,7 +40,8 @@ var ( 2: "PENDING", 3: "PROCESSING", 4: "COMPLETED", - 255: "FAILED", + 127: "FAILED", + 255: "DELETED", } JobStatus_value = map[string]int32{ "DRAFT": 0, @@ -47,7 +49,8 @@ var ( "PENDING": 2, "PROCESSING": 3, "COMPLETED": 4, - "FAILED": 255, + "FAILED": 127, + "DELETED": 255, } ) @@ -83,12 +86,12 @@ type Job struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` - Status JobStatus `protobuf:"varint,2,opt,name=status,proto3,enum=job.JobStatus" json:"status,omitempty"` - Priority int64 `protobuf:"varint,3,opt,name=priority,proto3" json:"priority,omitempty"` - CreateTime int64 `protobuf:"varint,4,opt,name=create_time,json=createTime,proto3" json:"create_time,omitempty"` - UpdateTime int64 `protobuf:"varint,5,opt,name=update_time,json=updateTime,proto3" json:"update_time,omitempty"` - State *JobState `protobuf:"bytes,17,opt,name=state,proto3" json:"state,omitempty"` + Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + Status JobStatus `protobuf:"varint,2,opt,name=status,proto3,enum=job.JobStatus" json:"status,omitempty"` + Priority int64 `protobuf:"varint,3,opt,name=priority,proto3" json:"priority,omitempty"` + CreateTimeNs int64 `protobuf:"varint,4,opt,name=create_time_ns,json=createTimeNs,proto3" json:"create_time_ns,omitempty"` + UpdateTimeNs int64 `protobuf:"varint,5,opt,name=update_time_ns,json=updateTimeNs,proto3" json:"update_time_ns,omitempty"` + State *JobState `protobuf:"bytes,17,opt,name=state,proto3" json:"state,omitempty"` } func (x *Job) Reset() { @@ -144,16 +147,16 @@ func (x *Job) GetPriority() int64 { return 0 } -func (x *Job) GetCreateTime() int64 { +func (x *Job) GetCreateTimeNs() int64 { if x != nil { - return x.CreateTime + return x.CreateTimeNs } return 0 } -func (x *Job) GetUpdateTime() int64 { +func (x *Job) GetUpdateTimeNs() int64 { if x != nil { - return x.UpdateTime + return x.UpdateTimeNs } return 0 } @@ -523,6 +526,61 @@ func (x *JobFilter) GetOffset() int64 { return 0 } +type JobRecentlyUpdateFilter struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + UpdateSinceNs *int64 `protobuf:"varint,1,opt,name=update_since_ns,json=updateSinceNs,proto3,oneof" json:"update_since_ns,omitempty"` + Limit *int64 `protobuf:"varint,33,opt,name=limit,proto3,oneof" json:"limit,omitempty"` +} + +func (x *JobRecentlyUpdateFilter) Reset() { + *x = JobRecentlyUpdateFilter{} + if protoimpl.UnsafeEnabled { + mi := &file_job_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *JobRecentlyUpdateFilter) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*JobRecentlyUpdateFilter) ProtoMessage() {} + +func (x *JobRecentlyUpdateFilter) ProtoReflect() protoreflect.Message { + mi := &file_job_proto_msgTypes[6] + 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 JobRecentlyUpdateFilter.ProtoReflect.Descriptor instead. +func (*JobRecentlyUpdateFilter) Descriptor() ([]byte, []int) { + return file_job_proto_rawDescGZIP(), []int{6} +} + +func (x *JobRecentlyUpdateFilter) GetUpdateSinceNs() int64 { + if x != nil && x.UpdateSinceNs != nil { + return *x.UpdateSinceNs + } + return 0 +} + +func (x *JobRecentlyUpdateFilter) GetLimit() int64 { + if x != nil && x.Limit != nil { + return *x.Limit + } + return 0 +} + type JobDisplay struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -537,7 +595,7 @@ type JobDisplay struct { func (x *JobDisplay) Reset() { *x = JobDisplay{} if protoimpl.UnsafeEnabled { - mi := &file_job_proto_msgTypes[6] + mi := &file_job_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -550,7 +608,7 @@ func (x *JobDisplay) String() string { func (*JobDisplay) ProtoMessage() {} func (x *JobDisplay) ProtoReflect() protoreflect.Message { - mi := &file_job_proto_msgTypes[6] + mi := &file_job_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -563,7 +621,7 @@ func (x *JobDisplay) ProtoReflect() protoreflect.Message { // Deprecated: Use JobDisplay.ProtoReflect.Descriptor instead. func (*JobDisplay) Descriptor() ([]byte, []int) { - return file_job_proto_rawDescGZIP(), []int{6} + return file_job_proto_rawDescGZIP(), []int{7} } func (m *JobDisplay) GetDisplay() isJobDisplay_Display { @@ -609,78 +667,87 @@ var file_job_proto_rawDesc = []byte{ 0x0a, 0x09, 0x6a, 0x6f, 0x62, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x03, 0x6a, 0x6f, 0x62, 0x1a, 0x11, 0x6a, 0x6f, 0x62, 0x5f, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x11, 0x6a, 0x6f, 0x62, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xc0, 0x01, 0x0a, 0x03, 0x4a, 0x6f, 0x62, 0x12, 0x0e, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xca, 0x01, 0x0a, 0x03, 0x4a, 0x6f, 0x62, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x26, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0e, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x4a, 0x6f, 0x62, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, - 0x74, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, - 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, - 0x69, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, - 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x54, 0x69, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x11, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x4a, 0x6f, 0x62, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x87, 0x01, 0x0a, 0x08, 0x4a, 0x6f, - 0x62, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x12, 0x38, 0x0a, 0x07, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x6a, 0x6f, 0x62, 0x5f, 0x61, 0x72, - 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x4a, 0x6f, 0x62, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, - 0x50, 0x61, 0x72, 0x61, 0x6d, 0x48, 0x00, 0x52, 0x07, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, - 0x12, 0x38, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1c, 0x2e, 0x6a, 0x6f, 0x62, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, - 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x48, - 0x00, 0x52, 0x07, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x42, 0x07, 0x0a, 0x05, 0x70, 0x61, - 0x72, 0x61, 0x6d, 0x22, 0x87, 0x01, 0x0a, 0x08, 0x4a, 0x6f, 0x62, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x74, 0x79, 0x12, 0x24, 0x0a, 0x0e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, + 0x65, 0x5f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x63, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x4e, 0x73, 0x12, 0x24, 0x0a, 0x0e, 0x75, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x0c, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x4e, 0x73, 0x12, 0x23, + 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, + 0x6a, 0x6f, 0x62, 0x2e, 0x4a, 0x6f, 0x62, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, + 0x61, 0x74, 0x65, 0x22, 0x87, 0x01, 0x0a, 0x08, 0x4a, 0x6f, 0x62, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x12, 0x38, 0x0a, 0x07, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x6a, 0x6f, 0x62, 0x5f, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, - 0x4a, 0x6f, 0x62, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x48, + 0x4a, 0x6f, 0x62, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x48, 0x00, 0x52, 0x07, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x12, 0x38, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x6a, 0x6f, 0x62, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, - 0x74, 0x6f, 0x72, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x48, 0x00, 0x52, 0x07, 0x72, 0x65, 0x73, - 0x74, 0x6f, 0x72, 0x65, 0x42, 0x07, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x93, 0x01, - 0x0a, 0x0c, 0x4a, 0x6f, 0x62, 0x4e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x12, 0x3c, - 0x0a, 0x07, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x20, 0x2e, 0x6a, 0x6f, 0x62, 0x5f, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x4a, 0x6f, - 0x62, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x4e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x72, 0x61, - 0x6d, 0x48, 0x00, 0x52, 0x07, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x12, 0x3c, 0x0a, 0x07, - 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, - 0x6a, 0x6f, 0x62, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x4a, 0x6f, 0x62, 0x52, - 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x4e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x48, - 0x00, 0x52, 0x07, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x42, 0x07, 0x0a, 0x05, 0x70, 0x61, - 0x72, 0x61, 0x6d, 0x22, 0x4f, 0x0a, 0x0c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x4a, 0x6f, 0x62, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, - 0x23, 0x0a, 0x05, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, - 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x4a, 0x6f, 0x62, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x52, 0x05, 0x70, - 0x61, 0x72, 0x61, 0x6d, 0x22, 0x90, 0x01, 0x0a, 0x09, 0x4a, 0x6f, 0x62, 0x46, 0x69, 0x6c, 0x74, - 0x65, 0x72, 0x12, 0x2b, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x0e, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x4a, 0x6f, 0x62, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x48, 0x00, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x88, 0x01, 0x01, 0x12, - 0x19, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x21, 0x20, 0x01, 0x28, 0x03, 0x48, 0x01, - 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x88, 0x01, 0x01, 0x12, 0x1b, 0x0a, 0x06, 0x6f, 0x66, - 0x66, 0x73, 0x65, 0x74, 0x18, 0x22, 0x20, 0x01, 0x28, 0x03, 0x48, 0x02, 0x52, 0x06, 0x6f, 0x66, - 0x66, 0x73, 0x65, 0x74, 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x73, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x42, 0x09, 0x0a, 0x07, - 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x22, 0x8f, 0x01, 0x0a, 0x0a, 0x4a, 0x6f, 0x62, 0x44, - 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x12, 0x3a, 0x0a, 0x07, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x6a, 0x6f, 0x62, 0x5f, 0x61, 0x72, - 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x4a, 0x6f, 0x62, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, - 0x44, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x48, 0x00, 0x52, 0x07, 0x61, 0x72, 0x63, 0x68, 0x69, - 0x76, 0x65, 0x12, 0x3a, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x6a, 0x6f, 0x62, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, - 0x65, 0x2e, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x44, 0x69, 0x73, 0x70, - 0x6c, 0x61, 0x79, 0x48, 0x00, 0x52, 0x07, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x42, 0x09, - 0x0a, 0x07, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x2a, 0x5e, 0x0a, 0x09, 0x4a, 0x6f, 0x62, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x09, 0x0a, 0x05, 0x44, 0x52, 0x41, 0x46, 0x54, 0x10, - 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x4e, 0x4f, 0x54, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x59, 0x10, 0x01, - 0x12, 0x0b, 0x0a, 0x07, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x0e, 0x0a, - 0x0a, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x49, 0x4e, 0x47, 0x10, 0x03, 0x12, 0x0d, 0x0a, - 0x09, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x04, 0x12, 0x0b, 0x0a, 0x06, - 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0xff, 0x01, 0x42, 0x23, 0x5a, 0x21, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x61, 0x6d, 0x75, 0x65, 0x6c, 0x6e, 0x63, - 0x75, 0x69, 0x2f, 0x79, 0x61, 0x74, 0x6d, 0x2f, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x74, 0x6f, 0x72, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x48, 0x00, 0x52, 0x07, 0x72, 0x65, 0x73, + 0x74, 0x6f, 0x72, 0x65, 0x42, 0x07, 0x0a, 0x05, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x22, 0x87, 0x01, + 0x0a, 0x08, 0x4a, 0x6f, 0x62, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x38, 0x0a, 0x07, 0x61, 0x72, + 0x63, 0x68, 0x69, 0x76, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x6a, 0x6f, + 0x62, 0x5f, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x4a, 0x6f, 0x62, 0x41, 0x72, 0x63, + 0x68, 0x69, 0x76, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x48, 0x00, 0x52, 0x07, 0x61, 0x72, 0x63, + 0x68, 0x69, 0x76, 0x65, 0x12, 0x38, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x6a, 0x6f, 0x62, 0x5f, 0x72, 0x65, 0x73, 0x74, + 0x6f, 0x72, 0x65, 0x2e, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x48, 0x00, 0x52, 0x07, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x42, 0x07, + 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x93, 0x01, 0x0a, 0x0c, 0x4a, 0x6f, 0x62, 0x4e, + 0x65, 0x78, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x12, 0x3c, 0x0a, 0x07, 0x61, 0x72, 0x63, 0x68, + 0x69, 0x76, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x6a, 0x6f, 0x62, 0x5f, + 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x4a, 0x6f, 0x62, 0x41, 0x72, 0x63, 0x68, 0x69, + 0x76, 0x65, 0x4e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x48, 0x00, 0x52, 0x07, 0x61, + 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x12, 0x3c, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x6a, 0x6f, 0x62, 0x5f, 0x72, 0x65, + 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, + 0x4e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x48, 0x00, 0x52, 0x07, 0x72, 0x65, 0x73, + 0x74, 0x6f, 0x72, 0x65, 0x42, 0x07, 0x0a, 0x05, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x22, 0x4f, 0x0a, + 0x0c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4a, 0x6f, 0x62, 0x12, 0x1a, 0x0a, + 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x23, 0x0a, 0x05, 0x70, 0x61, 0x72, + 0x61, 0x6d, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x4a, + 0x6f, 0x62, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x52, 0x05, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x22, 0x90, + 0x01, 0x0a, 0x09, 0x4a, 0x6f, 0x62, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x2b, 0x0a, 0x06, + 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0e, 0x2e, 0x6a, + 0x6f, 0x62, 0x2e, 0x4a, 0x6f, 0x62, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x48, 0x00, 0x52, 0x06, + 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x88, 0x01, 0x01, 0x12, 0x19, 0x0a, 0x05, 0x6c, 0x69, 0x6d, + 0x69, 0x74, 0x18, 0x21, 0x20, 0x01, 0x28, 0x03, 0x48, 0x01, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, + 0x74, 0x88, 0x01, 0x01, 0x12, 0x1b, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x22, + 0x20, 0x01, 0x28, 0x03, 0x48, 0x02, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x88, 0x01, + 0x01, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x08, 0x0a, 0x06, + 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, + 0x74, 0x22, 0x7f, 0x0a, 0x17, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x6c, 0x79, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x2b, 0x0a, 0x0f, + 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x5f, 0x6e, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x0d, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, + 0x69, 0x6e, 0x63, 0x65, 0x4e, 0x73, 0x88, 0x01, 0x01, 0x12, 0x19, 0x0a, 0x05, 0x6c, 0x69, 0x6d, + 0x69, 0x74, 0x18, 0x21, 0x20, 0x01, 0x28, 0x03, 0x48, 0x01, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, + 0x74, 0x88, 0x01, 0x01, 0x42, 0x12, 0x0a, 0x10, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, + 0x73, 0x69, 0x6e, 0x63, 0x65, 0x5f, 0x6e, 0x73, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x6c, 0x69, 0x6d, + 0x69, 0x74, 0x22, 0x8f, 0x01, 0x0a, 0x0a, 0x4a, 0x6f, 0x62, 0x44, 0x69, 0x73, 0x70, 0x6c, 0x61, + 0x79, 0x12, 0x3a, 0x0a, 0x07, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x6a, 0x6f, 0x62, 0x5f, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, + 0x2e, 0x4a, 0x6f, 0x62, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x44, 0x69, 0x73, 0x70, 0x6c, + 0x61, 0x79, 0x48, 0x00, 0x52, 0x07, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x12, 0x3a, 0x0a, + 0x07, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, + 0x2e, 0x6a, 0x6f, 0x62, 0x5f, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x4a, 0x6f, 0x62, + 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x44, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x48, 0x00, + 0x52, 0x07, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x42, 0x09, 0x0a, 0x07, 0x64, 0x69, 0x73, + 0x70, 0x6c, 0x61, 0x79, 0x2a, 0x6b, 0x0a, 0x09, 0x4a, 0x6f, 0x62, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x12, 0x09, 0x0a, 0x05, 0x44, 0x52, 0x41, 0x46, 0x54, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, + 0x4e, 0x4f, 0x54, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x59, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x50, + 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x50, 0x52, 0x4f, 0x43, + 0x45, 0x53, 0x53, 0x49, 0x4e, 0x47, 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x4f, 0x4d, 0x50, + 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x04, 0x12, 0x0a, 0x0a, 0x06, 0x46, 0x41, 0x49, 0x4c, 0x45, + 0x44, 0x10, 0x7f, 0x12, 0x0c, 0x0a, 0x07, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0xff, + 0x01, 0x42, 0x23, 0x5a, 0x21, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x73, 0x61, 0x6d, 0x75, 0x65, 0x6c, 0x6e, 0x63, 0x75, 0x69, 0x2f, 0x79, 0x61, 0x74, 0x6d, 0x2f, + 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -696,38 +763,39 @@ func file_job_proto_rawDescGZIP() []byte { } var file_job_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_job_proto_msgTypes = make([]protoimpl.MessageInfo, 7) +var file_job_proto_msgTypes = make([]protoimpl.MessageInfo, 8) var file_job_proto_goTypes = []interface{}{ - (JobStatus)(0), // 0: job.JobStatus - (*Job)(nil), // 1: job.Job - (*JobParam)(nil), // 2: job.JobParam - (*JobState)(nil), // 3: job.JobState - (*JobNextParam)(nil), // 4: job.JobNextParam - (*CreatableJob)(nil), // 5: job.CreatableJob - (*JobFilter)(nil), // 6: job.JobFilter - (*JobDisplay)(nil), // 7: job.JobDisplay - (*JobArchiveParam)(nil), // 8: job_archive.JobArchiveParam - (*JobRestoreParam)(nil), // 9: job_restore.JobRestoreParam - (*JobArchiveState)(nil), // 10: job_archive.JobArchiveState - (*JobRestoreState)(nil), // 11: job_restore.JobRestoreState - (*JobArchiveNextParam)(nil), // 12: job_archive.JobArchiveNextParam - (*JobRestoreNextParam)(nil), // 13: job_restore.JobRestoreNextParam - (*JobArchiveDisplay)(nil), // 14: job_archive.JobArchiveDisplay - (*JobRestoreDisplay)(nil), // 15: job_restore.JobRestoreDisplay + (JobStatus)(0), // 0: job.JobStatus + (*Job)(nil), // 1: job.Job + (*JobParam)(nil), // 2: job.JobParam + (*JobState)(nil), // 3: job.JobState + (*JobNextParam)(nil), // 4: job.JobNextParam + (*CreatableJob)(nil), // 5: job.CreatableJob + (*JobFilter)(nil), // 6: job.JobFilter + (*JobRecentlyUpdateFilter)(nil), // 7: job.JobRecentlyUpdateFilter + (*JobDisplay)(nil), // 8: job.JobDisplay + (*JobArchiveParam)(nil), // 9: job_archive.JobArchiveParam + (*JobRestoreParam)(nil), // 10: job_restore.JobRestoreParam + (*JobArchiveState)(nil), // 11: job_archive.JobArchiveState + (*JobRestoreState)(nil), // 12: job_restore.JobRestoreState + (*JobArchiveNextParam)(nil), // 13: job_archive.JobArchiveNextParam + (*JobRestoreNextParam)(nil), // 14: job_restore.JobRestoreNextParam + (*JobArchiveDisplay)(nil), // 15: job_archive.JobArchiveDisplay + (*JobRestoreDisplay)(nil), // 16: job_restore.JobRestoreDisplay } var file_job_proto_depIdxs = []int32{ 0, // 0: job.Job.status:type_name -> job.JobStatus 3, // 1: job.Job.state:type_name -> job.JobState - 8, // 2: job.JobParam.archive:type_name -> job_archive.JobArchiveParam - 9, // 3: job.JobParam.restore:type_name -> job_restore.JobRestoreParam - 10, // 4: job.JobState.archive:type_name -> job_archive.JobArchiveState - 11, // 5: job.JobState.restore:type_name -> job_restore.JobRestoreState - 12, // 6: job.JobNextParam.archive:type_name -> job_archive.JobArchiveNextParam - 13, // 7: job.JobNextParam.restore:type_name -> job_restore.JobRestoreNextParam + 9, // 2: job.JobParam.archive:type_name -> job_archive.JobArchiveParam + 10, // 3: job.JobParam.restore:type_name -> job_restore.JobRestoreParam + 11, // 4: job.JobState.archive:type_name -> job_archive.JobArchiveState + 12, // 5: job.JobState.restore:type_name -> job_restore.JobRestoreState + 13, // 6: job.JobNextParam.archive:type_name -> job_archive.JobArchiveNextParam + 14, // 7: job.JobNextParam.restore:type_name -> job_restore.JobRestoreNextParam 2, // 8: job.CreatableJob.param:type_name -> job.JobParam 0, // 9: job.JobFilter.status:type_name -> job.JobStatus - 14, // 10: job.JobDisplay.archive:type_name -> job_archive.JobArchiveDisplay - 15, // 11: job.JobDisplay.restore:type_name -> job_restore.JobRestoreDisplay + 15, // 10: job.JobDisplay.archive:type_name -> job_archive.JobArchiveDisplay + 16, // 11: job.JobDisplay.restore:type_name -> job_restore.JobRestoreDisplay 12, // [12:12] is the sub-list for method output_type 12, // [12:12] is the sub-list for method input_type 12, // [12:12] is the sub-list for extension type_name @@ -816,6 +884,18 @@ func file_job_proto_init() { } } file_job_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*JobRecentlyUpdateFilter); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_job_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*JobDisplay); i { case 0: return &v.state @@ -841,7 +921,8 @@ func file_job_proto_init() { (*JobNextParam_Restore)(nil), } file_job_proto_msgTypes[5].OneofWrappers = []interface{}{} - file_job_proto_msgTypes[6].OneofWrappers = []interface{}{ + file_job_proto_msgTypes[6].OneofWrappers = []interface{}{} + file_job_proto_msgTypes[7].OneofWrappers = []interface{}{ (*JobDisplay_Archive)(nil), (*JobDisplay_Restore)(nil), } @@ -851,7 +932,7 @@ func file_job_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_job_proto_rawDesc, NumEnums: 1, - NumMessages: 7, + NumMessages: 8, NumExtensions: 0, NumServices: 0, }, diff --git a/entity/job.proto b/entity/job.proto index 90aa4d5..01192de 100644 --- a/entity/job.proto +++ b/entity/job.proto @@ -12,15 +12,17 @@ enum JobStatus { PROCESSING = 3; COMPLETED = 4; - FAILED = 255; + FAILED = 127; + + DELETED = 255; } message Job { int64 id = 1; JobStatus status = 2; int64 priority = 3; - int64 create_time = 4; - int64 update_time = 5; + int64 create_time_ns = 4; + int64 update_time_ns = 5; JobState state = 17; } @@ -58,6 +60,12 @@ message JobFilter { optional int64 offset = 34; } +message JobRecentlyUpdateFilter { + optional int64 update_since_ns = 1; + + optional int64 limit = 33; +} + message JobDisplay { oneof display { job_archive.JobArchiveDisplay archive = 1; diff --git a/entity/service.pb.go b/entity/service.pb.go index 751d85d..7818e20 100644 --- a/entity/service.pb.go +++ b/entity/service.pb.go @@ -882,6 +882,7 @@ type JobListRequest struct { // Types that are assignable to Param: // *JobListRequest_Mget // *JobListRequest_List + // *JobListRequest_RecentlyUpdate Param isJobListRequest_Param `protobuf_oneof:"param"` } @@ -938,6 +939,13 @@ func (x *JobListRequest) GetList() *JobFilter { return nil } +func (x *JobListRequest) GetRecentlyUpdate() *JobRecentlyUpdateFilter { + if x, ok := x.GetParam().(*JobListRequest_RecentlyUpdate); ok { + return x.RecentlyUpdate + } + return nil +} + type isJobListRequest_Param interface { isJobListRequest_Param() } @@ -950,10 +958,16 @@ type JobListRequest_List struct { List *JobFilter `protobuf:"bytes,2,opt,name=list,proto3,oneof"` } +type JobListRequest_RecentlyUpdate struct { + RecentlyUpdate *JobRecentlyUpdateFilter `protobuf:"bytes,3,opt,name=recently_update,json=recentlyUpdate,proto3,oneof"` +} + func (*JobListRequest_Mget) isJobListRequest_Param() {} func (*JobListRequest_List) isJobListRequest_Param() {} +func (*JobListRequest_RecentlyUpdate) isJobListRequest_Param() {} + type JobMGetRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1483,7 +1497,8 @@ type JobGetLogReply struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Logs []byte `protobuf:"bytes,1,opt,name=logs,proto3" json:"logs,omitempty"` + Logs []byte `protobuf:"bytes,1,opt,name=logs,proto3" json:"logs,omitempty"` + Offset int64 `protobuf:"varint,2,opt,name=offset,proto3" json:"offset,omitempty"` } func (x *JobGetLogReply) Reset() { @@ -1525,6 +1540,13 @@ func (x *JobGetLogReply) GetLogs() []byte { return nil } +func (x *JobGetLogReply) GetOffset() int64 { + if x != nil { + return x.Offset + } + return 0 +} + type SourceListRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1979,163 +2001,169 @@ var file_service_proto_rawDesc = []byte{ 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x30, 0x0a, 0x09, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, - 0x6e, 0x52, 0x09, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x6e, 0x0a, 0x0e, - 0x4a, 0x6f, 0x62, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2d, - 0x0a, 0x04, 0x6d, 0x67, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4a, 0x6f, 0x62, 0x4d, 0x47, 0x65, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x04, 0x6d, 0x67, 0x65, 0x74, 0x12, 0x24, 0x0a, - 0x04, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6a, 0x6f, - 0x62, 0x2e, 0x4a, 0x6f, 0x62, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x48, 0x00, 0x52, 0x04, 0x6c, - 0x69, 0x73, 0x74, 0x42, 0x07, 0x0a, 0x05, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x22, 0x22, 0x0a, 0x0e, - 0x4a, 0x6f, 0x62, 0x4d, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, - 0x0a, 0x03, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x03, 0x52, 0x03, 0x69, 0x64, 0x73, - 0x22, 0x2c, 0x0a, 0x0c, 0x4a, 0x6f, 0x62, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, - 0x12, 0x1c, 0x0a, 0x04, 0x6a, 0x6f, 0x62, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x08, - 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x4a, 0x6f, 0x62, 0x52, 0x04, 0x6a, 0x6f, 0x62, 0x73, 0x22, 0x37, - 0x0a, 0x10, 0x4a, 0x6f, 0x62, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x23, 0x0a, 0x03, 0x6a, 0x6f, 0x62, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x11, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4a, - 0x6f, 0x62, 0x52, 0x03, 0x6a, 0x6f, 0x62, 0x22, 0x2c, 0x0a, 0x0e, 0x4a, 0x6f, 0x62, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x1a, 0x0a, 0x03, 0x6a, 0x6f, 0x62, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x4a, 0x6f, 0x62, - 0x52, 0x03, 0x6a, 0x6f, 0x62, 0x22, 0x24, 0x0a, 0x10, 0x4a, 0x6f, 0x62, 0x44, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x69, 0x64, 0x73, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x03, 0x52, 0x03, 0x69, 0x64, 0x73, 0x22, 0x10, 0x0a, 0x0e, 0x4a, - 0x6f, 0x62, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x49, 0x0a, - 0x0e, 0x4a, 0x6f, 0x62, 0x4e, 0x65, 0x78, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, - 0x27, 0x0a, 0x05, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, - 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x4a, 0x6f, 0x62, 0x4e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x72, 0x61, - 0x6d, 0x52, 0x05, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x22, 0x2a, 0x0a, 0x0c, 0x4a, 0x6f, 0x62, 0x4e, - 0x65, 0x78, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x1a, 0x0a, 0x03, 0x6a, 0x6f, 0x62, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x4a, 0x6f, 0x62, 0x52, - 0x03, 0x6a, 0x6f, 0x62, 0x22, 0x23, 0x0a, 0x11, 0x4a, 0x6f, 0x62, 0x44, 0x69, 0x73, 0x70, 0x6c, - 0x61, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x22, 0x3c, 0x0a, 0x0f, 0x4a, 0x6f, 0x62, - 0x44, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x29, 0x0a, 0x07, - 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, - 0x6a, 0x6f, 0x62, 0x2e, 0x4a, 0x6f, 0x62, 0x44, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x52, 0x07, - 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x22, 0x51, 0x0a, 0x10, 0x4a, 0x6f, 0x62, 0x47, 0x65, - 0x74, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x15, 0x0a, 0x06, 0x6a, - 0x6f, 0x62, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x6a, 0x6f, 0x62, - 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x03, 0x48, 0x00, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x88, 0x01, 0x01, 0x42, - 0x09, 0x0a, 0x07, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x22, 0x24, 0x0a, 0x0e, 0x4a, 0x6f, - 0x62, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x12, 0x0a, 0x04, - 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x6c, 0x6f, 0x67, 0x73, - 0x22, 0x27, 0x0a, 0x11, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x22, 0x93, 0x01, 0x0a, 0x0f, 0x53, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x26, 0x0a, - 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x2e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x52, - 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x28, 0x0a, 0x05, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x18, 0x02, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x53, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x05, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x12, - 0x2e, 0x0a, 0x08, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x18, 0x11, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x12, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x53, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x08, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x22, - 0x13, 0x0a, 0x11, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x22, 0x2b, 0x0a, 0x0f, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, - 0x73, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x76, 0x69, 0x63, - 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, - 0x73, 0x22, 0x54, 0x0a, 0x14, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x45, 0x78, 0x70, 0x6f, - 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3c, 0x0a, 0x05, 0x74, 0x79, 0x70, - 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x6c, 0x69, 0x62, 0x72, 0x61, - 0x72, 0x79, 0x5f, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x4c, - 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x54, 0x79, 0x70, 0x65, - 0x52, 0x05, 0x74, 0x79, 0x70, 0x65, 0x73, 0x22, 0x28, 0x0a, 0x12, 0x4c, 0x69, 0x62, 0x72, 0x61, - 0x72, 0x79, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x12, 0x0a, - 0x04, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x6a, 0x73, 0x6f, - 0x6e, 0x22, 0x56, 0x0a, 0x12, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x54, 0x72, 0x69, 0x6d, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x74, 0x72, 0x69, 0x6d, 0x5f, - 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, - 0x74, 0x72, 0x69, 0x6d, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x09, - 0x74, 0x72, 0x69, 0x6d, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x08, 0x74, 0x72, 0x69, 0x6d, 0x46, 0x69, 0x6c, 0x65, 0x22, 0x12, 0x0a, 0x10, 0x4c, 0x69, 0x62, - 0x72, 0x61, 0x72, 0x79, 0x54, 0x72, 0x69, 0x6d, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x32, 0xef, 0x09, - 0x0a, 0x07, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x3b, 0x0a, 0x07, 0x46, 0x69, 0x6c, - 0x65, 0x47, 0x65, 0x74, 0x12, 0x17, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x46, - 0x69, 0x6c, 0x65, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, - 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x47, 0x65, 0x74, 0x52, - 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x3e, 0x0a, 0x08, 0x46, 0x69, 0x6c, 0x65, 0x45, 0x64, - 0x69, 0x74, 0x12, 0x18, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x46, 0x69, 0x6c, - 0x65, 0x45, 0x64, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x73, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x45, 0x64, 0x69, 0x74, 0x52, - 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x41, 0x0a, 0x09, 0x46, 0x69, 0x6c, 0x65, 0x4d, 0x6b, - 0x64, 0x69, 0x72, 0x12, 0x19, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x46, 0x69, - 0x6c, 0x65, 0x4d, 0x6b, 0x64, 0x69, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, - 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4d, 0x6b, 0x64, - 0x69, 0x72, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x44, 0x0a, 0x0a, 0x46, 0x69, 0x6c, - 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x1a, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x46, 0x69, - 0x6c, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, - 0x53, 0x0a, 0x0f, 0x46, 0x69, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x72, 0x65, 0x6e, - 0x74, 0x73, 0x12, 0x1f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x46, 0x69, 0x6c, - 0x65, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x46, 0x69, - 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x70, - 0x6c, 0x79, 0x22, 0x00, 0x12, 0x3e, 0x0a, 0x08, 0x54, 0x61, 0x70, 0x65, 0x4c, 0x69, 0x73, 0x74, - 0x12, 0x18, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x54, 0x61, 0x70, 0x65, 0x4c, - 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x2e, 0x54, 0x61, 0x70, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x70, - 0x6c, 0x79, 0x22, 0x00, 0x12, 0x44, 0x0a, 0x0a, 0x54, 0x61, 0x70, 0x65, 0x44, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x12, 0x1a, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x54, 0x61, 0x70, - 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, - 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x54, 0x61, 0x70, 0x65, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x56, 0x0a, 0x10, 0x54, 0x61, - 0x70, 0x65, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x20, - 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x54, 0x61, 0x70, 0x65, 0x47, 0x65, 0x74, - 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x1e, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x54, 0x61, 0x70, 0x65, 0x47, - 0x65, 0x74, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, - 0x22, 0x00, 0x12, 0x3b, 0x0a, 0x07, 0x4a, 0x6f, 0x62, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x17, 0x2e, - 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4a, 0x6f, 0x62, 0x4c, 0x69, 0x73, 0x74, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x2e, 0x4a, 0x6f, 0x62, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, - 0x41, 0x0a, 0x09, 0x4a, 0x6f, 0x62, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x19, 0x2e, 0x73, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4a, 0x6f, 0x62, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x2e, 0x4a, 0x6f, 0x62, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, - 0x22, 0x00, 0x12, 0x41, 0x0a, 0x09, 0x4a, 0x6f, 0x62, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, - 0x19, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4a, 0x6f, 0x62, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4a, 0x6f, 0x62, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, - 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x3b, 0x0a, 0x07, 0x4a, 0x6f, 0x62, 0x4e, 0x65, 0x78, 0x74, - 0x12, 0x17, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4a, 0x6f, 0x62, 0x4e, 0x65, - 0x78, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x73, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x2e, 0x4a, 0x6f, 0x62, 0x4e, 0x65, 0x78, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, - 0x22, 0x00, 0x12, 0x44, 0x0a, 0x0a, 0x4a, 0x6f, 0x62, 0x44, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, - 0x12, 0x1a, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4a, 0x6f, 0x62, 0x44, 0x69, - 0x73, 0x70, 0x6c, 0x61, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x73, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4a, 0x6f, 0x62, 0x44, 0x69, 0x73, 0x70, 0x6c, 0x61, - 0x79, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x41, 0x0a, 0x09, 0x4a, 0x6f, 0x62, 0x47, - 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x12, 0x19, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, - 0x4a, 0x6f, 0x62, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x17, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4a, 0x6f, 0x62, 0x47, 0x65, - 0x74, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x44, 0x0a, 0x0a, 0x53, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x1a, 0x2e, 0x73, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x2e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, + 0x6e, 0x52, 0x09, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xb7, 0x01, 0x0a, + 0x0e, 0x4a, 0x6f, 0x62, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x2d, 0x0a, 0x04, 0x6d, 0x67, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4a, 0x6f, 0x62, 0x4d, 0x47, 0x65, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x04, 0x6d, 0x67, 0x65, 0x74, 0x12, 0x24, + 0x0a, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6a, + 0x6f, 0x62, 0x2e, 0x4a, 0x6f, 0x62, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x48, 0x00, 0x52, 0x04, + 0x6c, 0x69, 0x73, 0x74, 0x12, 0x47, 0x0a, 0x0f, 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x6c, 0x79, + 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, + 0x6a, 0x6f, 0x62, 0x2e, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x48, 0x00, 0x52, 0x0e, 0x72, + 0x65, 0x63, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x07, 0x0a, + 0x05, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x22, 0x22, 0x0a, 0x0e, 0x4a, 0x6f, 0x62, 0x4d, 0x47, 0x65, + 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x69, 0x64, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x03, 0x52, 0x03, 0x69, 0x64, 0x73, 0x22, 0x2c, 0x0a, 0x0c, 0x4a, 0x6f, + 0x62, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x1c, 0x0a, 0x04, 0x6a, 0x6f, + 0x62, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x4a, + 0x6f, 0x62, 0x52, 0x04, 0x6a, 0x6f, 0x62, 0x73, 0x22, 0x37, 0x0a, 0x10, 0x4a, 0x6f, 0x62, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x23, 0x0a, 0x03, + 0x6a, 0x6f, 0x62, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x03, 0x6a, 0x6f, + 0x62, 0x22, 0x2c, 0x0a, 0x0e, 0x4a, 0x6f, 0x62, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, + 0x70, 0x6c, 0x79, 0x12, 0x1a, 0x0a, 0x03, 0x6a, 0x6f, 0x62, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x08, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x4a, 0x6f, 0x62, 0x52, 0x03, 0x6a, 0x6f, 0x62, 0x22, + 0x24, 0x0a, 0x10, 0x4a, 0x6f, 0x62, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x03, + 0x52, 0x03, 0x69, 0x64, 0x73, 0x22, 0x10, 0x0a, 0x0e, 0x4a, 0x6f, 0x62, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x49, 0x0a, 0x0e, 0x4a, 0x6f, 0x62, 0x4e, 0x65, + 0x78, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x27, 0x0a, 0x05, 0x70, 0x61, 0x72, + 0x61, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x4a, + 0x6f, 0x62, 0x4e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x52, 0x05, 0x70, 0x61, 0x72, + 0x61, 0x6d, 0x22, 0x2a, 0x0a, 0x0c, 0x4a, 0x6f, 0x62, 0x4e, 0x65, 0x78, 0x74, 0x52, 0x65, 0x70, + 0x6c, 0x79, 0x12, 0x1a, 0x0a, 0x03, 0x6a, 0x6f, 0x62, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x08, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x4a, 0x6f, 0x62, 0x52, 0x03, 0x6a, 0x6f, 0x62, 0x22, 0x23, + 0x0a, 0x11, 0x4a, 0x6f, 0x62, 0x44, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x02, 0x69, 0x64, 0x22, 0x3c, 0x0a, 0x0f, 0x4a, 0x6f, 0x62, 0x44, 0x69, 0x73, 0x70, 0x6c, 0x61, + 0x79, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x29, 0x0a, 0x07, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6a, 0x6f, 0x62, 0x2e, 0x4a, 0x6f, + 0x62, 0x44, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x52, 0x07, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, + 0x79, 0x22, 0x51, 0x0a, 0x10, 0x4a, 0x6f, 0x62, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x15, 0x0a, 0x06, 0x6a, 0x6f, 0x62, 0x5f, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x6a, 0x6f, 0x62, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x06, + 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x06, + 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x6f, 0x66, + 0x66, 0x73, 0x65, 0x74, 0x22, 0x3c, 0x0a, 0x0e, 0x4a, 0x6f, 0x62, 0x47, 0x65, 0x74, 0x4c, 0x6f, + 0x67, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, + 0x66, 0x73, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, + 0x65, 0x74, 0x22, 0x27, 0x0a, 0x11, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x22, 0x93, 0x01, 0x0a, 0x0f, + 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, + 0x26, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x46, 0x69, 0x6c, + 0x65, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x28, 0x0a, 0x05, 0x63, 0x68, 0x61, 0x69, 0x6e, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, + 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x05, 0x63, 0x68, 0x61, 0x69, + 0x6e, 0x12, 0x2e, 0x0a, 0x08, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x18, 0x11, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x53, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x08, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, + 0x6e, 0x22, 0x13, 0x0a, 0x11, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x2b, 0x0a, 0x0f, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x64, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x73, 0x22, 0x54, 0x0a, 0x14, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x45, 0x78, + 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3c, 0x0a, 0x05, 0x74, + 0x79, 0x70, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x6c, 0x69, 0x62, + 0x72, 0x61, 0x72, 0x79, 0x5f, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x2e, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x54, 0x79, + 0x70, 0x65, 0x52, 0x05, 0x74, 0x79, 0x70, 0x65, 0x73, 0x22, 0x28, 0x0a, 0x12, 0x4c, 0x69, 0x62, + 0x72, 0x61, 0x72, 0x79, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, + 0x12, 0x0a, 0x04, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x6a, + 0x73, 0x6f, 0x6e, 0x22, 0x56, 0x0a, 0x12, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x54, 0x72, + 0x69, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x74, 0x72, 0x69, + 0x6d, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0c, 0x74, 0x72, 0x69, 0x6d, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1b, + 0x0a, 0x09, 0x74, 0x72, 0x69, 0x6d, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x08, 0x74, 0x72, 0x69, 0x6d, 0x46, 0x69, 0x6c, 0x65, 0x22, 0x12, 0x0a, 0x10, 0x4c, + 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x54, 0x72, 0x69, 0x6d, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x32, + 0xef, 0x09, 0x0a, 0x07, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x3b, 0x0a, 0x07, 0x46, + 0x69, 0x6c, 0x65, 0x47, 0x65, 0x74, 0x12, 0x17, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x15, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x47, 0x65, + 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x3e, 0x0a, 0x08, 0x46, 0x69, 0x6c, 0x65, + 0x45, 0x64, 0x69, 0x74, 0x12, 0x18, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x46, + 0x69, 0x6c, 0x65, 0x45, 0x64, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, + 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x45, 0x64, 0x69, + 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x41, 0x0a, 0x09, 0x46, 0x69, 0x6c, 0x65, + 0x4d, 0x6b, 0x64, 0x69, 0x72, 0x12, 0x19, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, + 0x46, 0x69, 0x6c, 0x65, 0x4d, 0x6b, 0x64, 0x69, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x17, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4d, + 0x6b, 0x64, 0x69, 0x72, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x44, 0x0a, 0x0a, 0x46, + 0x69, 0x6c, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x1a, 0x2e, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, - 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, - 0x00, 0x12, 0x44, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, - 0x1a, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, - 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x73, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, - 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x4d, 0x0a, 0x0d, 0x4c, 0x69, 0x62, 0x72, 0x61, - 0x72, 0x79, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x1d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x2e, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x2e, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x52, - 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x47, 0x0a, 0x0b, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, - 0x79, 0x54, 0x72, 0x69, 0x6d, 0x12, 0x1b, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, - 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x54, 0x72, 0x69, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4c, 0x69, 0x62, - 0x72, 0x61, 0x72, 0x79, 0x54, 0x72, 0x69, 0x6d, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x42, - 0x23, 0x5a, 0x21, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x61, - 0x6d, 0x75, 0x65, 0x6c, 0x6e, 0x63, 0x75, 0x69, 0x2f, 0x79, 0x61, 0x74, 0x6d, 0x2f, 0x65, 0x6e, - 0x74, 0x69, 0x74, 0x79, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x46, 0x69, 0x6c, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, + 0x00, 0x12, 0x53, 0x0a, 0x0f, 0x46, 0x69, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x72, + 0x65, 0x6e, 0x74, 0x73, 0x12, 0x1f, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x46, + 0x69, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, + 0x46, 0x69, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x52, + 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x3e, 0x0a, 0x08, 0x54, 0x61, 0x70, 0x65, 0x4c, 0x69, + 0x73, 0x74, 0x12, 0x18, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x54, 0x61, 0x70, + 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x73, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x54, 0x61, 0x70, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, + 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x44, 0x0a, 0x0a, 0x54, 0x61, 0x70, 0x65, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x12, 0x1a, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x54, + 0x61, 0x70, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x18, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x54, 0x61, 0x70, 0x65, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x56, 0x0a, 0x10, + 0x54, 0x61, 0x70, 0x65, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x12, 0x20, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x54, 0x61, 0x70, 0x65, 0x47, + 0x65, 0x74, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x54, 0x61, 0x70, + 0x65, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x70, + 0x6c, 0x79, 0x22, 0x00, 0x12, 0x3b, 0x0a, 0x07, 0x4a, 0x6f, 0x62, 0x4c, 0x69, 0x73, 0x74, 0x12, + 0x17, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4a, 0x6f, 0x62, 0x4c, 0x69, 0x73, + 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x2e, 0x4a, 0x6f, 0x62, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, + 0x00, 0x12, 0x41, 0x0a, 0x09, 0x4a, 0x6f, 0x62, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x19, + 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4a, 0x6f, 0x62, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x2e, 0x4a, 0x6f, 0x62, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x70, + 0x6c, 0x79, 0x22, 0x00, 0x12, 0x41, 0x0a, 0x09, 0x4a, 0x6f, 0x62, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x12, 0x19, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4a, 0x6f, 0x62, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x73, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4a, 0x6f, 0x62, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x3b, 0x0a, 0x07, 0x4a, 0x6f, 0x62, 0x4e, 0x65, + 0x78, 0x74, 0x12, 0x17, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4a, 0x6f, 0x62, + 0x4e, 0x65, 0x78, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x73, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4a, 0x6f, 0x62, 0x4e, 0x65, 0x78, 0x74, 0x52, 0x65, 0x70, + 0x6c, 0x79, 0x22, 0x00, 0x12, 0x44, 0x0a, 0x0a, 0x4a, 0x6f, 0x62, 0x44, 0x69, 0x73, 0x70, 0x6c, + 0x61, 0x79, 0x12, 0x1a, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4a, 0x6f, 0x62, + 0x44, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, + 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4a, 0x6f, 0x62, 0x44, 0x69, 0x73, 0x70, + 0x6c, 0x61, 0x79, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x41, 0x0a, 0x09, 0x4a, 0x6f, + 0x62, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x12, 0x19, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x2e, 0x4a, 0x6f, 0x62, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4a, 0x6f, 0x62, + 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x44, 0x0a, + 0x0a, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x1a, 0x2e, 0x73, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x2e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6c, + 0x79, 0x22, 0x00, 0x12, 0x44, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, + 0x74, 0x12, 0x1a, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x44, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, + 0x73, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x4d, 0x0a, 0x0d, 0x4c, 0x69, 0x62, + 0x72, 0x61, 0x72, 0x79, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x1d, 0x2e, 0x73, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x45, 0x78, 0x70, 0x6f, + 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x2e, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x45, 0x78, 0x70, 0x6f, 0x72, + 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x47, 0x0a, 0x0b, 0x4c, 0x69, 0x62, 0x72, + 0x61, 0x72, 0x79, 0x54, 0x72, 0x69, 0x6d, 0x12, 0x1b, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x2e, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x54, 0x72, 0x69, 0x6d, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4c, + 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x54, 0x72, 0x69, 0x6d, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, + 0x00, 0x42, 0x23, 0x5a, 0x21, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x73, 0x61, 0x6d, 0x75, 0x65, 0x6c, 0x6e, 0x63, 0x75, 0x69, 0x2f, 0x79, 0x61, 0x74, 0x6d, 0x2f, + 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -2196,12 +2224,13 @@ var file_service_proto_goTypes = []interface{}{ (*TapeFilter)(nil), // 41: tape.TapeFilter (*Tape)(nil), // 42: tape.Tape (*JobFilter)(nil), // 43: job.JobFilter - (*Job)(nil), // 44: job.Job - (*CreatableJob)(nil), // 45: job.CreatableJob - (*JobNextParam)(nil), // 46: job.JobNextParam - (*JobDisplay)(nil), // 47: job.JobDisplay - (*SourceFile)(nil), // 48: source.SourceFile - (LibraryEntityType)(0), // 49: library_entity_type.LibraryEntityType + (*JobRecentlyUpdateFilter)(nil), // 44: job.JobRecentlyUpdateFilter + (*Job)(nil), // 45: job.Job + (*CreatableJob)(nil), // 46: job.CreatableJob + (*JobNextParam)(nil), // 47: job.JobNextParam + (*JobDisplay)(nil), // 48: job.JobDisplay + (*SourceFile)(nil), // 49: source.SourceFile + (LibraryEntityType)(0), // 50: library_entity_type.LibraryEntityType } var file_service_proto_depIdxs = []int32{ 38, // 0: service.FileGetReply.file:type_name -> file.File @@ -2217,57 +2246,58 @@ var file_service_proto_depIdxs = []int32{ 39, // 10: service.TapeGetPositionsReply.positions:type_name -> position.Position 18, // 11: service.JobListRequest.mget:type_name -> service.JobMGetRequest 43, // 12: service.JobListRequest.list:type_name -> job.JobFilter - 44, // 13: service.JobListReply.jobs:type_name -> job.Job - 45, // 14: service.JobCreateRequest.job:type_name -> job.CreatableJob - 44, // 15: service.JobCreateReply.job:type_name -> job.Job - 46, // 16: service.JobNextRequest.param:type_name -> job.JobNextParam - 44, // 17: service.JobNextReply.job:type_name -> job.Job - 47, // 18: service.JobDisplayReply.display:type_name -> job.JobDisplay - 48, // 19: service.SourceListReply.file:type_name -> source.SourceFile - 48, // 20: service.SourceListReply.chain:type_name -> source.SourceFile - 48, // 21: service.SourceListReply.children:type_name -> source.SourceFile - 49, // 22: service.LibraryExportRequest.types:type_name -> library_entity_type.LibraryEntityType - 0, // 23: service.Service.FileGet:input_type -> service.FileGetRequest - 2, // 24: service.Service.FileEdit:input_type -> service.FileEditRequest - 4, // 25: service.Service.FileMkdir:input_type -> service.FileMkdirRequest - 6, // 26: service.Service.FileDelete:input_type -> service.FileDeleteRequest - 8, // 27: service.Service.FileListParents:input_type -> service.FileListParentsRequest - 10, // 28: service.Service.TapeList:input_type -> service.TapeListRequest - 13, // 29: service.Service.TapeDelete:input_type -> service.TapeDeleteRequest - 15, // 30: service.Service.TapeGetPositions:input_type -> service.TapeGetPositionsRequest - 17, // 31: service.Service.JobList:input_type -> service.JobListRequest - 20, // 32: service.Service.JobCreate:input_type -> service.JobCreateRequest - 22, // 33: service.Service.JobDelete:input_type -> service.JobDeleteRequest - 24, // 34: service.Service.JobNext:input_type -> service.JobNextRequest - 26, // 35: service.Service.JobDisplay:input_type -> service.JobDisplayRequest - 28, // 36: service.Service.JobGetLog:input_type -> service.JobGetLogRequest - 30, // 37: service.Service.SourceList:input_type -> service.SourceListRequest - 32, // 38: service.Service.DeviceList:input_type -> service.DeviceListRequest - 34, // 39: service.Service.LibraryExport:input_type -> service.LibraryExportRequest - 36, // 40: service.Service.LibraryTrim:input_type -> service.LibraryTrimRequest - 1, // 41: service.Service.FileGet:output_type -> service.FileGetReply - 3, // 42: service.Service.FileEdit:output_type -> service.FileEditReply - 5, // 43: service.Service.FileMkdir:output_type -> service.FileMkdirReply - 7, // 44: service.Service.FileDelete:output_type -> service.FileDeleteReply - 9, // 45: service.Service.FileListParents:output_type -> service.FileListParentsReply - 12, // 46: service.Service.TapeList:output_type -> service.TapeListReply - 14, // 47: service.Service.TapeDelete:output_type -> service.TapeDeleteReply - 16, // 48: service.Service.TapeGetPositions:output_type -> service.TapeGetPositionsReply - 19, // 49: service.Service.JobList:output_type -> service.JobListReply - 21, // 50: service.Service.JobCreate:output_type -> service.JobCreateReply - 23, // 51: service.Service.JobDelete:output_type -> service.JobDeleteReply - 25, // 52: service.Service.JobNext:output_type -> service.JobNextReply - 27, // 53: service.Service.JobDisplay:output_type -> service.JobDisplayReply - 29, // 54: service.Service.JobGetLog:output_type -> service.JobGetLogReply - 31, // 55: service.Service.SourceList:output_type -> service.SourceListReply - 33, // 56: service.Service.DeviceList:output_type -> service.DeviceListReply - 35, // 57: service.Service.LibraryExport:output_type -> service.LibraryExportReply - 37, // 58: service.Service.LibraryTrim:output_type -> service.LibraryTrimReply - 41, // [41:59] is the sub-list for method output_type - 23, // [23:41] is the sub-list for method input_type - 23, // [23:23] is the sub-list for extension type_name - 23, // [23:23] is the sub-list for extension extendee - 0, // [0:23] is the sub-list for field type_name + 44, // 13: service.JobListRequest.recently_update:type_name -> job.JobRecentlyUpdateFilter + 45, // 14: service.JobListReply.jobs:type_name -> job.Job + 46, // 15: service.JobCreateRequest.job:type_name -> job.CreatableJob + 45, // 16: service.JobCreateReply.job:type_name -> job.Job + 47, // 17: service.JobNextRequest.param:type_name -> job.JobNextParam + 45, // 18: service.JobNextReply.job:type_name -> job.Job + 48, // 19: service.JobDisplayReply.display:type_name -> job.JobDisplay + 49, // 20: service.SourceListReply.file:type_name -> source.SourceFile + 49, // 21: service.SourceListReply.chain:type_name -> source.SourceFile + 49, // 22: service.SourceListReply.children:type_name -> source.SourceFile + 50, // 23: service.LibraryExportRequest.types:type_name -> library_entity_type.LibraryEntityType + 0, // 24: service.Service.FileGet:input_type -> service.FileGetRequest + 2, // 25: service.Service.FileEdit:input_type -> service.FileEditRequest + 4, // 26: service.Service.FileMkdir:input_type -> service.FileMkdirRequest + 6, // 27: service.Service.FileDelete:input_type -> service.FileDeleteRequest + 8, // 28: service.Service.FileListParents:input_type -> service.FileListParentsRequest + 10, // 29: service.Service.TapeList:input_type -> service.TapeListRequest + 13, // 30: service.Service.TapeDelete:input_type -> service.TapeDeleteRequest + 15, // 31: service.Service.TapeGetPositions:input_type -> service.TapeGetPositionsRequest + 17, // 32: service.Service.JobList:input_type -> service.JobListRequest + 20, // 33: service.Service.JobCreate:input_type -> service.JobCreateRequest + 22, // 34: service.Service.JobDelete:input_type -> service.JobDeleteRequest + 24, // 35: service.Service.JobNext:input_type -> service.JobNextRequest + 26, // 36: service.Service.JobDisplay:input_type -> service.JobDisplayRequest + 28, // 37: service.Service.JobGetLog:input_type -> service.JobGetLogRequest + 30, // 38: service.Service.SourceList:input_type -> service.SourceListRequest + 32, // 39: service.Service.DeviceList:input_type -> service.DeviceListRequest + 34, // 40: service.Service.LibraryExport:input_type -> service.LibraryExportRequest + 36, // 41: service.Service.LibraryTrim:input_type -> service.LibraryTrimRequest + 1, // 42: service.Service.FileGet:output_type -> service.FileGetReply + 3, // 43: service.Service.FileEdit:output_type -> service.FileEditReply + 5, // 44: service.Service.FileMkdir:output_type -> service.FileMkdirReply + 7, // 45: service.Service.FileDelete:output_type -> service.FileDeleteReply + 9, // 46: service.Service.FileListParents:output_type -> service.FileListParentsReply + 12, // 47: service.Service.TapeList:output_type -> service.TapeListReply + 14, // 48: service.Service.TapeDelete:output_type -> service.TapeDeleteReply + 16, // 49: service.Service.TapeGetPositions:output_type -> service.TapeGetPositionsReply + 19, // 50: service.Service.JobList:output_type -> service.JobListReply + 21, // 51: service.Service.JobCreate:output_type -> service.JobCreateReply + 23, // 52: service.Service.JobDelete:output_type -> service.JobDeleteReply + 25, // 53: service.Service.JobNext:output_type -> service.JobNextReply + 27, // 54: service.Service.JobDisplay:output_type -> service.JobDisplayReply + 29, // 55: service.Service.JobGetLog:output_type -> service.JobGetLogReply + 31, // 56: service.Service.SourceList:output_type -> service.SourceListReply + 33, // 57: service.Service.DeviceList:output_type -> service.DeviceListReply + 35, // 58: service.Service.LibraryExport:output_type -> service.LibraryExportReply + 37, // 59: service.Service.LibraryTrim:output_type -> service.LibraryTrimReply + 42, // [42:60] is the sub-list for method output_type + 24, // [24:42] is the sub-list for method input_type + 24, // [24:24] is the sub-list for extension type_name + 24, // [24:24] is the sub-list for extension extendee + 0, // [0:24] is the sub-list for field type_name } func init() { file_service_proto_init() } @@ -2747,6 +2777,7 @@ func file_service_proto_init() { file_service_proto_msgTypes[17].OneofWrappers = []interface{}{ (*JobListRequest_Mget)(nil), (*JobListRequest_List)(nil), + (*JobListRequest_RecentlyUpdate)(nil), } file_service_proto_msgTypes[28].OneofWrappers = []interface{}{} type x struct{} diff --git a/entity/service.proto b/entity/service.proto index 4248491..0f5b6d4 100644 --- a/entity/service.proto +++ b/entity/service.proto @@ -113,6 +113,7 @@ message JobListRequest { oneof param { JobMGetRequest mget = 1; job.JobFilter list = 2; + job.JobRecentlyUpdateFilter recently_update = 3; } } @@ -163,6 +164,7 @@ message JobGetLogRequest { message JobGetLogReply { bytes logs = 1; + int64 offset = 2; } message SourceListRequest { diff --git a/entity/utils.go b/entity/utils.go index c8d7c69..5a0724c 100644 --- a/entity/utils.go +++ b/entity/utils.go @@ -1,13 +1,34 @@ package entity import ( + "bytes" "database/sql/driver" "fmt" + "io" + "github.com/klauspost/compress/zstd" "github.com/modern-go/reflect2" + "github.com/samuelncui/yatm/tools" "google.golang.org/protobuf/proto" ) +const ( + compressThreshold = 1024 +) + +var ( + magicHeaderV2 = []byte{0xff, 'y', 'm', '\x02'} + + zstdEncoderPool = tools.NewPool(func() *zstd.Encoder { + encoder, _ := zstd.NewWriter(nil) // there will be no error without options + return encoder + }) + zstdDecoderPool = tools.NewPool(func() *zstd.Decoder { + decoder, _ := zstd.NewReader(nil) // there will be no error without options + return decoder + }) +) + // Scan implement database/sql.Scanner func Scan(dst proto.Message, src interface{}) error { typ := reflect2.TypeOf(dst).(reflect2.PtrType).Elem() @@ -24,14 +45,31 @@ func Scan(dst proto.Message, src interface{}) error { default: return fmt.Errorf("process define extra scanner, unexpected type for i18n, %T", v) } - if len(buf) == 0 { return nil } + if bytes.HasPrefix(buf, magicHeaderV2) { + decoder := zstdDecoderPool.Get() + + err := decoder.Reset(bytes.NewBuffer(buf[len(magicHeaderV2):])) + if err != nil { + return fmt.Errorf("zstd reset decoder fail, %w", err) + } + + buf, err = io.ReadAll(decoder) + if err != nil { + return fmt.Errorf("zstd read decoder fail, %w", err) + } + + decoder.Reset(nil) + zstdDecoderPool.Put(decoder) + } + if err := proto.Unmarshal(buf, dst); err != nil { - return fmt.Errorf("process define extra scanner, json unmarshal fail, %w", err) + return fmt.Errorf("process define extra scanner, protobuf unmarshal fail, %w", err) } + return nil } @@ -39,7 +77,30 @@ func Scan(dst proto.Message, src interface{}) error { func Value(src proto.Message) (driver.Value, error) { buf, err := proto.Marshal(src) if err != nil { - return nil, fmt.Errorf("process define extra valuer, json marshal fail, %w", err) + return nil, fmt.Errorf("process define extra valuer, protobuf marshal fail, %w", err) + } + + if len(buf) <= compressThreshold { + return buf, nil } + + buffer := bytes.NewBuffer(make([]byte, 0, len(buf))) + buffer.Write(magicHeaderV2) + + encoder := zstdEncoderPool.Get() + encoder.Reset(buffer) + _, err = encoder.Write(buf) + if err != nil { + return nil, fmt.Errorf("zstd write to encoder fail, %w", err) + } + err = encoder.Close() + if err != nil { + return nil, fmt.Errorf("zstd close encoder fail, %w", err) + } + + buf = buffer.Bytes() + encoder.Reset(nil) + zstdEncoderPool.Put(encoder) + return buf, nil } diff --git a/executor/job.go b/executor/job.go index 19923ee..86ffa0f 100644 --- a/executor/job.go +++ b/executor/job.go @@ -22,7 +22,7 @@ type Job struct { State *entity.JobState CreateTime time.Time - UpdateTime time.Time + UpdateTime time.Time `gorm:"index:idx_update_time"` } func (j *Job) BeforeUpdate(tx *gorm.DB) error { @@ -56,9 +56,18 @@ func (e *Executor) CreateJob(ctx context.Context, job *Job, param *entity.JobPar } func (e *Executor) DeleteJobs(ctx context.Context, ids ...int64) error { - if r := e.db.WithContext(ctx).Delete(ModelJob, ids); r.Error != nil { - return fmt.Errorf("delete job fail, err= %w", r.Error) + jobs, err := e.MGetJob(ctx, ids...) + if err != nil { + return fmt.Errorf("mget jobs fail") + } + + for _, job := range jobs { + job.Status = entity.JobStatus_DELETED + if r := e.db.WithContext(ctx).Save(job); r.Error != nil { + return fmt.Errorf("delete job write db fail, id= %d err= %w", job.ID, r.Error) + } } + return nil } @@ -120,6 +129,8 @@ func (e *Executor) ListJob(ctx context.Context, filter *entity.JobFilter) ([]*Jo db := e.db.WithContext(ctx) if filter.Status != nil { db = db.Where("status = ?", *filter.Status) + } else { + db = db.Where("status < ?", entity.JobStatusVisible) } if filter.Limit != nil { @@ -140,3 +151,25 @@ func (e *Executor) ListJob(ctx context.Context, filter *entity.JobFilter) ([]*Jo return jobs, nil } + +func (e *Executor) ListRecentlyUpdateJob(ctx context.Context, filter *entity.JobRecentlyUpdateFilter) ([]*Job, error) { + db := e.db.WithContext(ctx) + if filter.UpdateSinceNs != nil { + db = db.Where("update_time > ?", time.Unix(0, *filter.UpdateSinceNs)) + } + + if filter.Limit != nil { + db = db.Limit(int(*filter.Limit)) + } else { + db = db.Limit(20) + } + + db = db.Order("update_time ASC") + + jobs := make([]*Job, 0, 20) + if r := db.Find(&jobs); r.Error != nil { + return nil, fmt.Errorf("list jobs fail, err= %w", r.Error) + } + + return jobs, nil +} diff --git a/frontend/src/api.ts b/frontend/src/api.ts index a90bb4c..929d98c 100644 --- a/frontend/src/api.ts +++ b/frontend/src/api.ts @@ -4,6 +4,9 @@ import { ServiceClient, File, SourceFile, Tape, Position } from "./entity"; import moment from "moment"; +export const MODE_DIR = 2147483648n; // d: is a directory +export const JOB_STATUS_VISIBLE = 128; + const apiBase: string = (() => { const base = (window as any).apiBase as string; if (!base || base === "%%API_BASE%%") { @@ -16,8 +19,6 @@ export const fileBase: string = (() => { return apiBase.replace("/services", "/files"); })(); -export const ModeDir = 2147483648n; // d: is a directory - export const Root: FileData = { id: "0", name: "Root", @@ -38,7 +39,7 @@ export const cli = new ServiceClient(transport); export function convertFiles(files: Array): FileData[] { return files.map((file) => { - const isDir = (file.mode & ModeDir) > 0; + const isDir = (file.mode & MODE_DIR) > 0; return { id: getID(file), @@ -58,7 +59,7 @@ export function convertFiles(files: Array): FileData[] { export function convertSourceFiles(files: Array): FileData[] { return files.map((file) => { - const isDir = (file.mode & ModeDir) > 0; + const isDir = (file.mode & MODE_DIR) > 0; return { id: getID(file), @@ -99,7 +100,7 @@ export function convertTapes(tapes: Array): FileData[] { export function convertPositions(positions: Array): FileData[] { return positions.map((posi) => { - const isDir = (posi.mode & ModeDir) > 0; + const isDir = (posi.mode & MODE_DIR) > 0; const name = isDir ? splitPath(posi.path.slice(0, -1)) : splitPath(posi.path); return { diff --git a/frontend/src/entity/job.ts b/frontend/src/entity/job.ts index aa61579..7c0d9ea 100644 --- a/frontend/src/entity/job.ts +++ b/frontend/src/entity/job.ts @@ -36,13 +36,13 @@ export interface Job { */ priority: bigint; /** - * @generated from protobuf field: int64 create_time = 4; + * @generated from protobuf field: int64 create_time_ns = 4; */ - createTime: bigint; + createTimeNs: bigint; /** - * @generated from protobuf field: int64 update_time = 5; + * @generated from protobuf field: int64 update_time_ns = 5; */ - updateTime: bigint; + updateTimeNs: bigint; /** * @generated from protobuf field: job.JobState state = 17; */ @@ -147,6 +147,19 @@ export interface JobFilter { */ offset?: bigint; } +/** + * @generated from protobuf message job.JobRecentlyUpdateFilter + */ +export interface JobRecentlyUpdateFilter { + /** + * @generated from protobuf field: optional int64 update_since_ns = 1; + */ + updateSinceNs?: bigint; + /** + * @generated from protobuf field: optional int64 limit = 33; + */ + limit?: bigint; +} /** * @generated from protobuf message job.JobDisplay */ @@ -199,9 +212,13 @@ export enum JobStatus { */ COMPLETED = 4, /** - * @generated from protobuf enum value: FAILED = 255; + * @generated from protobuf enum value: FAILED = 127; + */ + FAILED = 127, + /** + * @generated from protobuf enum value: DELETED = 255; */ - FAILED = 255 + DELETED = 255 } // @generated message type with reflection information, may provide speed optimized methods class Job$Type extends MessageType { @@ -210,13 +227,13 @@ class Job$Type extends MessageType { { no: 1, name: "id", kind: "scalar", T: 3 /*ScalarType.INT64*/, L: 0 /*LongType.BIGINT*/ }, { no: 2, name: "status", kind: "enum", T: () => ["job.JobStatus", JobStatus] }, { no: 3, name: "priority", kind: "scalar", T: 3 /*ScalarType.INT64*/, L: 0 /*LongType.BIGINT*/ }, - { no: 4, name: "create_time", kind: "scalar", T: 3 /*ScalarType.INT64*/, L: 0 /*LongType.BIGINT*/ }, - { no: 5, name: "update_time", kind: "scalar", T: 3 /*ScalarType.INT64*/, L: 0 /*LongType.BIGINT*/ }, + { no: 4, name: "create_time_ns", kind: "scalar", T: 3 /*ScalarType.INT64*/, L: 0 /*LongType.BIGINT*/ }, + { no: 5, name: "update_time_ns", kind: "scalar", T: 3 /*ScalarType.INT64*/, L: 0 /*LongType.BIGINT*/ }, { no: 17, name: "state", kind: "message", T: () => JobState } ]); } create(value?: PartialMessage): Job { - const message = { id: 0n, status: 0, priority: 0n, createTime: 0n, updateTime: 0n }; + const message = { id: 0n, status: 0, priority: 0n, createTimeNs: 0n, updateTimeNs: 0n }; globalThis.Object.defineProperty(message, MESSAGE_TYPE, { enumerable: false, value: this }); if (value !== undefined) reflectionMergePartial(this, message, value); @@ -236,11 +253,11 @@ class Job$Type extends MessageType { case /* int64 priority */ 3: message.priority = reader.int64().toBigInt(); break; - case /* int64 create_time */ 4: - message.createTime = reader.int64().toBigInt(); + case /* int64 create_time_ns */ 4: + message.createTimeNs = reader.int64().toBigInt(); break; - case /* int64 update_time */ 5: - message.updateTime = reader.int64().toBigInt(); + case /* int64 update_time_ns */ 5: + message.updateTimeNs = reader.int64().toBigInt(); break; case /* job.JobState state */ 17: message.state = JobState.internalBinaryRead(reader, reader.uint32(), options, message.state); @@ -266,12 +283,12 @@ class Job$Type extends MessageType { /* int64 priority = 3; */ if (message.priority !== 0n) writer.tag(3, WireType.Varint).int64(message.priority); - /* int64 create_time = 4; */ - if (message.createTime !== 0n) - writer.tag(4, WireType.Varint).int64(message.createTime); - /* int64 update_time = 5; */ - if (message.updateTime !== 0n) - writer.tag(5, WireType.Varint).int64(message.updateTime); + /* int64 create_time_ns = 4; */ + if (message.createTimeNs !== 0n) + writer.tag(4, WireType.Varint).int64(message.createTimeNs); + /* int64 update_time_ns = 5; */ + if (message.updateTimeNs !== 0n) + writer.tag(5, WireType.Varint).int64(message.updateTimeNs); /* job.JobState state = 17; */ if (message.state) JobState.internalBinaryWrite(message.state, writer.tag(17, WireType.LengthDelimited).fork(), options).join(); @@ -581,6 +598,60 @@ class JobFilter$Type extends MessageType { */ export const JobFilter = new JobFilter$Type(); // @generated message type with reflection information, may provide speed optimized methods +class JobRecentlyUpdateFilter$Type extends MessageType { + constructor() { + super("job.JobRecentlyUpdateFilter", [ + { no: 1, name: "update_since_ns", kind: "scalar", opt: true, T: 3 /*ScalarType.INT64*/, L: 0 /*LongType.BIGINT*/ }, + { no: 33, name: "limit", kind: "scalar", opt: true, T: 3 /*ScalarType.INT64*/, L: 0 /*LongType.BIGINT*/ } + ]); + } + create(value?: PartialMessage): JobRecentlyUpdateFilter { + const message = {}; + globalThis.Object.defineProperty(message, MESSAGE_TYPE, { enumerable: false, value: this }); + if (value !== undefined) + reflectionMergePartial(this, message, value); + return message; + } + internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: JobRecentlyUpdateFilter): JobRecentlyUpdateFilter { + let message = target ?? this.create(), end = reader.pos + length; + while (reader.pos < end) { + let [fieldNo, wireType] = reader.tag(); + switch (fieldNo) { + case /* optional int64 update_since_ns */ 1: + message.updateSinceNs = reader.int64().toBigInt(); + break; + case /* optional int64 limit */ 33: + message.limit = reader.int64().toBigInt(); + break; + default: + let u = options.readUnknownField; + if (u === "throw") + throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`); + let d = reader.skip(wireType); + if (u !== false) + (u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d); + } + } + return message; + } + internalBinaryWrite(message: JobRecentlyUpdateFilter, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter { + /* optional int64 update_since_ns = 1; */ + if (message.updateSinceNs !== undefined) + writer.tag(1, WireType.Varint).int64(message.updateSinceNs); + /* optional int64 limit = 33; */ + if (message.limit !== undefined) + writer.tag(33, WireType.Varint).int64(message.limit); + let u = options.writeUnknownFields; + if (u !== false) + (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); + return writer; + } +} +/** + * @generated MessageType for protobuf message job.JobRecentlyUpdateFilter + */ +export const JobRecentlyUpdateFilter = new JobRecentlyUpdateFilter$Type(); +// @generated message type with reflection information, may provide speed optimized methods class JobDisplay$Type extends MessageType { constructor() { super("job.JobDisplay", [ diff --git a/frontend/src/entity/service.ts b/frontend/src/entity/service.ts index 1046b5a..11abbed 100644 --- a/frontend/src/entity/service.ts +++ b/frontend/src/entity/service.ts @@ -18,6 +18,7 @@ import { JobDisplay } from "./job"; import { JobNextParam } from "./job"; import { CreatableJob } from "./job"; import { Job } from "./job"; +import { JobRecentlyUpdateFilter } from "./job"; import { JobFilter } from "./job"; import { Tape } from "./tape"; import { TapeFilter } from "./tape"; @@ -222,6 +223,12 @@ export interface JobListRequest { * @generated from protobuf field: job.JobFilter list = 2; */ list: JobFilter; + } | { + oneofKind: "recentlyUpdate"; + /** + * @generated from protobuf field: job.JobRecentlyUpdateFilter recently_update = 3; + */ + recentlyUpdate: JobRecentlyUpdateFilter; } | { oneofKind: undefined; }; @@ -337,6 +344,10 @@ export interface JobGetLogReply { * @generated from protobuf field: bytes logs = 1; */ logs: Uint8Array; + /** + * @generated from protobuf field: int64 offset = 2; + */ + offset: bigint; } /** * @generated from protobuf message service.SourceListRequest @@ -1248,7 +1259,8 @@ class JobListRequest$Type extends MessageType { constructor() { super("service.JobListRequest", [ { no: 1, name: "mget", kind: "message", oneof: "param", T: () => JobMGetRequest }, - { no: 2, name: "list", kind: "message", oneof: "param", T: () => JobFilter } + { no: 2, name: "list", kind: "message", oneof: "param", T: () => JobFilter }, + { no: 3, name: "recently_update", kind: "message", oneof: "param", T: () => JobRecentlyUpdateFilter } ]); } create(value?: PartialMessage): JobListRequest { @@ -1275,6 +1287,12 @@ class JobListRequest$Type extends MessageType { list: JobFilter.internalBinaryRead(reader, reader.uint32(), options, (message.param as any).list) }; break; + case /* job.JobRecentlyUpdateFilter recently_update */ 3: + message.param = { + oneofKind: "recentlyUpdate", + recentlyUpdate: JobRecentlyUpdateFilter.internalBinaryRead(reader, reader.uint32(), options, (message.param as any).recentlyUpdate) + }; + break; default: let u = options.readUnknownField; if (u === "throw") @@ -1293,6 +1311,9 @@ class JobListRequest$Type extends MessageType { /* job.JobFilter list = 2; */ if (message.param.oneofKind === "list") JobFilter.internalBinaryWrite(message.param.list, writer.tag(2, WireType.LengthDelimited).fork(), options).join(); + /* job.JobRecentlyUpdateFilter recently_update = 3; */ + if (message.param.oneofKind === "recentlyUpdate") + JobRecentlyUpdateFilter.internalBinaryWrite(message.param.recentlyUpdate, writer.tag(3, WireType.LengthDelimited).fork(), options).join(); let u = options.writeUnknownFields; if (u !== false) (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); @@ -1833,11 +1854,12 @@ export const JobGetLogRequest = new JobGetLogRequest$Type(); class JobGetLogReply$Type extends MessageType { constructor() { super("service.JobGetLogReply", [ - { no: 1, name: "logs", kind: "scalar", T: 12 /*ScalarType.BYTES*/ } + { no: 1, name: "logs", kind: "scalar", T: 12 /*ScalarType.BYTES*/ }, + { no: 2, name: "offset", kind: "scalar", T: 3 /*ScalarType.INT64*/, L: 0 /*LongType.BIGINT*/ } ]); } create(value?: PartialMessage): JobGetLogReply { - const message = { logs: new Uint8Array(0) }; + const message = { logs: new Uint8Array(0), offset: 0n }; globalThis.Object.defineProperty(message, MESSAGE_TYPE, { enumerable: false, value: this }); if (value !== undefined) reflectionMergePartial(this, message, value); @@ -1851,6 +1873,9 @@ class JobGetLogReply$Type extends MessageType { case /* bytes logs */ 1: message.logs = reader.bytes(); break; + case /* int64 offset */ 2: + message.offset = reader.int64().toBigInt(); + break; default: let u = options.readUnknownField; if (u === "throw") @@ -1866,6 +1891,9 @@ class JobGetLogReply$Type extends MessageType { /* bytes logs = 1; */ if (message.logs.length) writer.tag(1, WireType.LengthDelimited).bytes(message.logs); + /* int64 offset = 2; */ + if (message.offset !== 0n) + writer.tag(2, WireType.Varint).int64(message.offset); let u = options.writeUnknownFields; if (u !== false) (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer); diff --git a/frontend/src/pages/jobs.tsx b/frontend/src/pages/jobs.tsx index cb5787a..51d8051 100644 --- a/frontend/src/pages/jobs.tsx +++ b/frontend/src/pages/jobs.tsx @@ -34,7 +34,7 @@ import { TreeView, TreeItem } from "@mui/x-tree-view"; import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; import ChevronRightIcon from "@mui/icons-material/ChevronRight"; -import { cli, fileBase } from "../api"; +import { cli, fileBase, JOB_STATUS_VISIBLE } from "../api"; import { sleep } from "../tools"; import { Job, JobDisplay, JobListRequest, JobNextRequest, JobStatus, CopyStatus, LibraryEntityType, JobDeleteRequest } from "../entity"; @@ -45,6 +45,7 @@ import { JobRestoreCopyingParam, JobRestoreStep, JobRestoreDisplay, JobRestoreSt import { RestoreTape } from "../entity"; import { formatFilesize, download } from "../tools"; +import { Nullable } from "tsdef"; export const JobsType = "jobs"; type DisplayableJob = Job & Partial; @@ -53,29 +54,79 @@ const RefreshContext = createContext<() => Promise>(async () => {}); export const JobsBrowser = () => { const [jobs, setJobs] = useState(null); - const refresh = useCallback(async () => { - const jobReplys = await cli.jobList(JobListRequest.create({ param: { oneofKind: "list", list: {} } })).response; - const displays = new Map(); - for (const reply of await Promise.all( - jobReplys.jobs - .filter((job) => job.status === JobStatus.PROCESSING) - .map((job) => cli.jobDisplay({ id: job.id }).response.then((reply) => ({ ...reply, jobID: job.id }))), - )) { - if (!reply.display) { - continue; + const [latestUpdateTimeNs, setLatestUpdateTimeNs] = useState(0n); + + const refresh = useCallback( + async (refresh?: boolean) => { + var results = Array.from(jobs || []); + const req: JobListRequest = refresh + ? { param: { oneofKind: "list", list: {} } } + : { param: { oneofKind: "recentlyUpdate", recentlyUpdate: { updateSinceNs: latestUpdateTimeNs } } }; + + const reply = await cli.jobList(req).response; + if (reply.jobs.length === 0) { + if (refresh) { + setJobs([]); + } + return; } - displays.set(reply.jobID, reply.display); - } + for (const job of reply.jobs) { + const foundIdx = results.findIndex((target) => target.id === job.id); + if (foundIdx >= 0) { + results[foundIdx] = job; + continue; + } + + results.push(job); + } + results = results.filter((job) => job && job.status < JOB_STATUS_VISIBLE).sort((a, b) => Number(b.createTimeNs - a.createTimeNs)); + + const displays = new Map(); + for (const reply of await Promise.all( + results + .filter((job) => job.status === JobStatus.PROCESSING) + .map((job) => cli.jobDisplay({ id: job.id }).response.then((reply) => ({ ...reply, jobID: job.id }))), + )) { + if (!reply.display) { + continue; + } + + displays.set(reply.jobID, reply.display); + } + + const targets = results.map((job) => ({ ...job, ...displays.get(job.id) })); + const latest = reply.jobs.reduce((latest, job) => { + if (!job || !job.updateTimeNs) { + return latest; + } + if (job.updateTimeNs > latest) { + return job.updateTimeNs; + } + return latest; + }, 0n); + console.log("refresh jobs list, targets=", targets, "latest=", latest); + + setLatestUpdateTimeNs(latest); + setJobs(targets); + }, + [jobs, setJobs, latestUpdateTimeNs, setLatestUpdateTimeNs], + ); + const refreshRef = useRef(refresh); + refreshRef.current = refresh; - const targets = jobReplys.jobs.map((job) => ({ ...job, ...displays.get(job.id) })); - console.log("refresh jobs list, ", targets); - setJobs(targets); - }, [setJobs]); useEffect(() => { - refresh(); - const timer = setInterval(refresh, 2000); + var timer: NodeJS.Timeout; + (async () => { + await refreshRef.current(true); + timer = setInterval(() => refreshRef.current(), 2000); + })(); + return () => { + if (!timer) { + return; + } + clearInterval(timer); }; }, []); @@ -650,31 +701,40 @@ const ViewLogDialog = ({ jobID }: { jobID: bigint }) => { const LogConsole = ({ jobId }: { jobId: bigint }) => { const [log, setLog] = useState(""); + const [offset, setOffset] = useState(0n); const bottom = useRef(null); - const refreshLog = useCallback(async () => { - const reply = await cli.jobGetLog({ jobId, offset: BigInt(log.length) }).response; + + const refresh = useCallback(async () => { + const reply = await cli.jobGetLog({ jobId, offset: offset }).response; setLog(log + new TextDecoder().decode(reply.logs)); + setOffset(reply.offset); + }, [log, setLog, offset, setOffset, bottom]); + const refreshRef = useRef(refresh); + refreshRef.current = refresh; - if (log.length === 0 && reply.logs.length > 0 && bottom && bottom.current) { - await sleep(10); - (bottom.current as HTMLElement).scrollIntoView(true); - await sleep(10); - (bottom.current as HTMLElement).parentElement?.scrollBy(0, 100); - } - }, [log, setLog, bottom]); useEffect(() => { - let closed = false; + var timer: NodeJS.Timeout; (async () => { - while (!closed) { - await refreshLog(); - await sleep(2000); + await refreshRef.current(); + if (bottom.current) { + const bottomElem = bottom.current as HTMLElement; + await sleep(10); + bottomElem.scrollIntoView(true); + await sleep(10); + bottomElem.parentElement?.scrollBy(0, 100); } + + timer = setInterval(() => refreshRef.current(), 2000); })(); return () => { - closed = true; + if (!timer) { + return; + } + + clearInterval(timer); }; - }, [refreshLog]); + }, [refresh]); return ( diff --git a/go.mod b/go.mod index 0124b4e..707ee7f 100644 --- a/go.mod +++ b/go.mod @@ -15,6 +15,7 @@ require ( github.com/improbable-eng/grpc-web v0.15.0 github.com/jessevdk/go-flags v1.5.0 github.com/json-iterator/go v1.1.12 + github.com/klauspost/compress v1.17.0 github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible github.com/modern-go/reflect2 v1.0.2 github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5 @@ -30,6 +31,7 @@ require ( ) replace ( + // for sqlite migrate bug github.com/glebarez/sqlite => github.com/samuelncui/gorm-sqlite v0.0.0-20231004150052-7f8c4fd3e561 gorm.io/driver/sqlite => github.com/samuelncui/gorm-sqlite v0.0.0-20231004151052-c8fdb51ac7b9 gorm.io/gorm => github.com/samuelncui/gorm v0.0.0-20231004143348-3fe5335dfd1e @@ -53,7 +55,6 @@ require ( github.com/hashicorp/errwrap v1.1.0 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect - github.com/klauspost/compress v1.11.7 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/leodido/go-urn v1.2.1 // indirect github.com/lestrrat-go/strftime v1.0.6 // indirect diff --git a/go.sum b/go.sum index 7150a12..969a27a 100644 --- a/go.sum +++ b/go.sum @@ -223,8 +223,9 @@ github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1 github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.11.7 h1:0hzRabrMN4tSTvMfnL3SCv1ZGeAP23ynzodBgaHeMeg= github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.17.0 h1:Rnbp4K9EjcDuVuHtd0dgA4qNuv9yKDYKK1ulpJwgrqM= +github.com/klauspost/compress v1.17.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= diff --git a/tools/pool.go b/tools/pool.go new file mode 100644 index 0000000..a37f05d --- /dev/null +++ b/tools/pool.go @@ -0,0 +1,25 @@ +package tools + +import "sync" + +type Pool[T any] struct { + inner sync.Pool +} + +func NewPool[T any](f func() T) *Pool[T] { + pool := &Pool[T]{ + inner: sync.Pool{ + New: func() interface{} { return f() }, + }, + } + + return pool +} + +func (p *Pool[T]) Get() T { + return p.inner.Get().(T) +} + +func (p *Pool[T]) Put(value T) { + p.inner.Put(value) +}