mirror of
https://github.com/samuelncui/yatm.git
synced 2026-04-23 17:20:38 +00:00
fix: change tape error
This commit is contained in:
@@ -17,8 +17,8 @@ func (api *API) JobGetLog(ctx context.Context, req *entity.JobGetLogRequest) (*e
|
||||
return &entity.JobGetLogReply{Logs: []byte{}}, nil
|
||||
}
|
||||
|
||||
if req.Offset > 0 {
|
||||
if _, err := reader.Seek(req.Offset, 0); err != nil {
|
||||
if req.Offset != nil {
|
||||
if _, err := reader.Seek(*req.Offset, 0); err != nil {
|
||||
return nil, fmt.Errorf("seek log file fail, offset= %d, %w", req.Offset, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/abc950309/tapewriter/apis"
|
||||
"github.com/abc950309/tapewriter/entity"
|
||||
@@ -17,6 +18,7 @@ import (
|
||||
"github.com/abc950309/tapewriter/resource"
|
||||
"github.com/abc950309/tapewriter/tools"
|
||||
"github.com/improbable-eng/grpc-web/go/grpcweb"
|
||||
"github.com/sirupsen/logrus"
|
||||
"google.golang.org/grpc"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
@@ -110,6 +112,15 @@ func main() {
|
||||
Addr: conf.Listen,
|
||||
}
|
||||
|
||||
go func() {
|
||||
<-tools.ShutdownContext.Done()
|
||||
logrus.Infof("Graceful shutdown, wait for working process")
|
||||
start := time.Now()
|
||||
tools.Wait()
|
||||
logrus.Infof("Graceful shutdown, wait done, duration= %s", time.Since(start))
|
||||
srv.Shutdown(context.Background())
|
||||
}()
|
||||
|
||||
log.Printf("http server listening at %v", srv.Addr)
|
||||
if err := srv.ListenAndServe(); err != nil {
|
||||
log.Fatalf("failed to serve: %v", err)
|
||||
|
||||
@@ -412,11 +412,12 @@ type JobDisplayArchive struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
CopyedBytes int64 `protobuf:"varint,1,opt,name=copyedBytes,proto3" json:"copyedBytes,omitempty"`
|
||||
CopyedFiles int64 `protobuf:"varint,2,opt,name=copyedFiles,proto3" json:"copyedFiles,omitempty"`
|
||||
TotalBytes int64 `protobuf:"varint,3,opt,name=totalBytes,proto3" json:"totalBytes,omitempty"`
|
||||
TotalFiles int64 `protobuf:"varint,4,opt,name=totalFiles,proto3" json:"totalFiles,omitempty"`
|
||||
Speed int64 `protobuf:"varint,5,opt,name=speed,proto3" json:"speed,omitempty"`
|
||||
CopyedBytes int64 `protobuf:"varint,1,opt,name=copyedBytes,proto3" json:"copyedBytes,omitempty"`
|
||||
CopyedFiles int64 `protobuf:"varint,2,opt,name=copyedFiles,proto3" json:"copyedFiles,omitempty"`
|
||||
TotalBytes int64 `protobuf:"varint,3,opt,name=totalBytes,proto3" json:"totalBytes,omitempty"`
|
||||
TotalFiles int64 `protobuf:"varint,4,opt,name=totalFiles,proto3" json:"totalFiles,omitempty"`
|
||||
Speed *int64 `protobuf:"varint,5,opt,name=speed,proto3,oneof" json:"speed,omitempty"`
|
||||
StartTime int64 `protobuf:"varint,6,opt,name=startTime,proto3" json:"startTime,omitempty"`
|
||||
}
|
||||
|
||||
func (x *JobDisplayArchive) Reset() {
|
||||
@@ -480,8 +481,15 @@ func (x *JobDisplayArchive) GetTotalFiles() int64 {
|
||||
}
|
||||
|
||||
func (x *JobDisplayArchive) GetSpeed() int64 {
|
||||
if x != nil && x.Speed != nil {
|
||||
return *x.Speed
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *JobDisplayArchive) GetStartTime() int64 {
|
||||
if x != nil {
|
||||
return x.Speed
|
||||
return x.StartTime
|
||||
}
|
||||
return 0
|
||||
}
|
||||
@@ -527,7 +535,7 @@ var file_job_archive_proto_rawDesc = []byte{
|
||||
0x76, 0x65, 0x53, 0x74, 0x65, 0x70, 0x52, 0x04, 0x73, 0x74, 0x65, 0x70, 0x12, 0x2d, 0x0a, 0x07,
|
||||
0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e,
|
||||
0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x74, 0x61,
|
||||
0x74, 0x65, 0x52, 0x07, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x22, 0xad, 0x01, 0x0a, 0x11,
|
||||
0x74, 0x65, 0x52, 0x07, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x22, 0xda, 0x01, 0x0a, 0x11,
|
||||
0x4a, 0x6f, 0x62, 0x44, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76,
|
||||
0x65, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x70, 0x79, 0x65, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x63, 0x6f, 0x70, 0x79, 0x65, 0x64, 0x42, 0x79,
|
||||
@@ -537,16 +545,19 @@ var file_job_archive_proto_rawDesc = []byte{
|
||||
0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c,
|
||||
0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x46, 0x69,
|
||||
0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c,
|
||||
0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x70, 0x65, 0x65, 0x64, 0x18, 0x05,
|
||||
0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x73, 0x70, 0x65, 0x65, 0x64, 0x2a, 0x4a, 0x0a, 0x0e, 0x4a,
|
||||
0x6f, 0x62, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x53, 0x74, 0x65, 0x70, 0x12, 0x0b, 0x0a,
|
||||
0x07, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x57, 0x61,
|
||||
0x69, 0x74, 0x46, 0x6f, 0x72, 0x54, 0x61, 0x70, 0x65, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x43,
|
||||
0x6f, 0x70, 0x79, 0x69, 0x6e, 0x67, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x08, 0x46, 0x69, 0x6e, 0x69,
|
||||
0x73, 0x68, 0x65, 0x64, 0x10, 0xff, 0x01, 0x42, 0x28, 0x5a, 0x26, 0x67, 0x69, 0x74, 0x68, 0x75,
|
||||
0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x62, 0x63, 0x39, 0x35, 0x30, 0x33, 0x30, 0x39, 0x2f,
|
||||
0x74, 0x61, 0x70, 0x65, 0x77, 0x72, 0x69, 0x74, 0x65, 0x72, 0x2f, 0x65, 0x6e, 0x74, 0x69, 0x74,
|
||||
0x79, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x19, 0x0a, 0x05, 0x73, 0x70, 0x65, 0x65, 0x64, 0x18, 0x05,
|
||||
0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x05, 0x73, 0x70, 0x65, 0x65, 0x64, 0x88, 0x01, 0x01,
|
||||
0x12, 0x1c, 0x0a, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20,
|
||||
0x01, 0x28, 0x03, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x42, 0x08,
|
||||
0x0a, 0x06, 0x5f, 0x73, 0x70, 0x65, 0x65, 0x64, 0x2a, 0x4a, 0x0a, 0x0e, 0x4a, 0x6f, 0x62, 0x41,
|
||||
0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x53, 0x74, 0x65, 0x70, 0x12, 0x0b, 0x0a, 0x07, 0x50, 0x65,
|
||||
0x6e, 0x64, 0x69, 0x6e, 0x67, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x57, 0x61, 0x69, 0x74, 0x46,
|
||||
0x6f, 0x72, 0x54, 0x61, 0x70, 0x65, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x6f, 0x70, 0x79,
|
||||
0x69, 0x6e, 0x67, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x08, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65,
|
||||
0x64, 0x10, 0xff, 0x01, 0x42, 0x28, 0x5a, 0x26, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63,
|
||||
0x6f, 0x6d, 0x2f, 0x61, 0x62, 0x63, 0x39, 0x35, 0x30, 0x33, 0x30, 0x39, 0x2f, 0x74, 0x61, 0x70,
|
||||
0x65, 0x77, 0x72, 0x69, 0x74, 0x65, 0x72, 0x2f, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x62, 0x06,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -686,6 +697,7 @@ func file_job_archive_proto_init() {
|
||||
(*JobArchiveNextParam_Copying)(nil),
|
||||
(*JobArchiveNextParam_Finished)(nil),
|
||||
}
|
||||
file_job_archive_proto_msgTypes[6].OneofWrappers = []interface{}{}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
|
||||
@@ -46,4 +46,5 @@ message JobDisplayArchive {
|
||||
int64 totalFiles = 4;
|
||||
|
||||
optional int64 speed = 5;
|
||||
int64 startTime = 6;
|
||||
}
|
||||
|
||||
@@ -1029,7 +1029,7 @@ type JobDisplayReply struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Display *JobDisplay `protobuf:"bytes,1,opt,name=display,proto3,oneof" json:"display,omitempty"`
|
||||
Display *JobDisplay `protobuf:"bytes,1,opt,name=display,proto3" json:"display,omitempty"`
|
||||
}
|
||||
|
||||
func (x *JobDisplayReply) Reset() {
|
||||
@@ -1076,8 +1076,8 @@ type JobGetLogRequest struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
JobId int64 `protobuf:"varint,1,opt,name=job_id,json=jobId,proto3" json:"job_id,omitempty"`
|
||||
Offset int64 `protobuf:"varint,2,opt,name=offset,proto3" json:"offset,omitempty"`
|
||||
JobId int64 `protobuf:"varint,1,opt,name=job_id,json=jobId,proto3" json:"job_id,omitempty"`
|
||||
Offset *int64 `protobuf:"varint,2,opt,name=offset,proto3,oneof" json:"offset,omitempty"`
|
||||
}
|
||||
|
||||
func (x *JobGetLogRequest) Reset() {
|
||||
@@ -1120,8 +1120,8 @@ func (x *JobGetLogRequest) GetJobId() int64 {
|
||||
}
|
||||
|
||||
func (x *JobGetLogRequest) GetOffset() int64 {
|
||||
if x != nil {
|
||||
return x.Offset
|
||||
if x != nil && x.Offset != nil {
|
||||
return *x.Offset
|
||||
}
|
||||
return 0
|
||||
}
|
||||
@@ -1447,93 +1447,93 @@ var file_service_proto_rawDesc = []byte{
|
||||
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, 0x4d, 0x0a, 0x0f, 0x4a, 0x6f, 0x62, 0x44, 0x69, 0x73, 0x70, 0x6c,
|
||||
0x61, 0x79, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x2e, 0x0a, 0x07, 0x64, 0x69, 0x73, 0x70, 0x6c,
|
||||
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, 0x48, 0x00, 0x52, 0x07, 0x64, 0x69, 0x73,
|
||||
0x70, 0x6c, 0x61, 0x79, 0x88, 0x01, 0x01, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x64, 0x69, 0x73, 0x70,
|
||||
0x6c, 0x61, 0x79, 0x22, 0x41, 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, 0x16,
|
||||
0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06,
|
||||
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, 0x32, 0xf6, 0x06,
|
||||
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, 0x4d, 0x47, 0x65, 0x74,
|
||||
0x12, 0x18, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x54, 0x61, 0x70, 0x65, 0x4d,
|
||||
0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x73, 0x65, 0x72,
|
||||
0x76, 0x69, 0x63, 0x65, 0x2e, 0x54, 0x61, 0x70, 0x65, 0x4d, 0x47, 0x65, 0x74, 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, 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, 0x42, 0x28, 0x5a, 0x26, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
|
||||
0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x62, 0x63, 0x39, 0x35, 0x30, 0x33, 0x30, 0x39, 0x2f, 0x74,
|
||||
0x61, 0x70, 0x65, 0x77, 0x72, 0x69, 0x74, 0x65, 0x72, 0x2f, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79,
|
||||
0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
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, 0x32, 0xf6, 0x06, 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, 0x4d, 0x47, 0x65, 0x74, 0x12,
|
||||
0x18, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x54, 0x61, 0x70, 0x65, 0x4d, 0x47,
|
||||
0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x73, 0x65, 0x72, 0x76,
|
||||
0x69, 0x63, 0x65, 0x2e, 0x54, 0x61, 0x70, 0x65, 0x4d, 0x47, 0x65, 0x74, 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, 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, 0x42, 0x28, 0x5a, 0x26, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,
|
||||
0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x62, 0x63, 0x39, 0x35, 0x30, 0x33, 0x30, 0x39, 0x2f, 0x74, 0x61,
|
||||
0x70, 0x65, 0x77, 0x72, 0x69, 0x74, 0x65, 0x72, 0x2f, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x62,
|
||||
0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -1982,7 +1982,7 @@ func file_service_proto_init() {
|
||||
(*JobListRequest_Mget)(nil),
|
||||
(*JobListRequest_List)(nil),
|
||||
}
|
||||
file_service_proto_msgTypes[20].OneofWrappers = []interface{}{}
|
||||
file_service_proto_msgTypes[21].OneofWrappers = []interface{}{}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
|
||||
@@ -106,7 +106,7 @@ func (e *Executor) Submit(ctx context.Context, job *Job, param *entity.JobNextPa
|
||||
return err
|
||||
}
|
||||
|
||||
exe.submit(param.GetArchive())
|
||||
exe.submit(ctx, param.GetArchive())
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -109,19 +109,19 @@ func (e *Executor) GetJob(ctx context.Context, id int64) (*Job, error) {
|
||||
func (e *Executor) ListJob(ctx context.Context, filter *entity.JobFilter) ([]*Job, error) {
|
||||
db := e.db.WithContext(ctx)
|
||||
if filter.Status != nil {
|
||||
db.Where("status = ?", *filter.Status)
|
||||
db = db.Where("status = ?", *filter.Status)
|
||||
}
|
||||
|
||||
if filter.Limit != nil {
|
||||
db.Limit(int(*filter.Limit))
|
||||
db = db.Limit(int(*filter.Limit))
|
||||
} else {
|
||||
db.Limit(20)
|
||||
db = db.Limit(20)
|
||||
}
|
||||
if filter.Offset != nil {
|
||||
db.Offset(int(*filter.Offset))
|
||||
db = db.Offset(int(*filter.Offset))
|
||||
}
|
||||
|
||||
db.Order("create_time DESC")
|
||||
db = db.Order("create_time DESC")
|
||||
|
||||
jobs := make([]*Job, 0, 20)
|
||||
if r := db.Find(&jobs); r.Error != nil {
|
||||
|
||||
@@ -15,7 +15,10 @@ func (e *Executor) getArchiveDisplay(ctx context.Context, job *Job) (*entity.Job
|
||||
display.CopyedFiles = atomic.LoadInt64(&exe.progress.files)
|
||||
display.TotalBytes = atomic.LoadInt64(&exe.progress.totalBytes)
|
||||
display.TotalFiles = atomic.LoadInt64(&exe.progress.totalFiles)
|
||||
display.Speed = atomic.LoadInt64(&exe.progress.speed)
|
||||
display.StartTime = exe.progress.startTime.Unix()
|
||||
|
||||
speed := atomic.LoadInt64(&exe.progress.speed)
|
||||
display.Speed = &speed
|
||||
}
|
||||
|
||||
return display, nil
|
||||
|
||||
@@ -46,15 +46,13 @@ func (e *Executor) newArchiveExecutor(ctx context.Context, job *Job) (*jobArchiv
|
||||
logger.SetOutput(io.MultiWriter(os.Stderr, logFile))
|
||||
|
||||
exe := &jobArchiveExecutor{
|
||||
ctx: context.Background(),
|
||||
exe: e,
|
||||
job: job,
|
||||
|
||||
state: job.State.GetArchive(),
|
||||
|
||||
progress: new(progress),
|
||||
logFile: logFile,
|
||||
logger: logger,
|
||||
logFile: logFile,
|
||||
logger: logger,
|
||||
}
|
||||
|
||||
runningArchives.Store(job.ID, exe)
|
||||
@@ -62,7 +60,6 @@ func (e *Executor) newArchiveExecutor(ctx context.Context, job *Job) (*jobArchiv
|
||||
}
|
||||
|
||||
type jobArchiveExecutor struct {
|
||||
ctx context.Context
|
||||
exe *Executor
|
||||
job *Job
|
||||
|
||||
@@ -74,22 +71,23 @@ type jobArchiveExecutor struct {
|
||||
logger *logrus.Logger
|
||||
}
|
||||
|
||||
func (a *jobArchiveExecutor) submit(param *entity.JobArchiveNextParam) {
|
||||
if err := a.handle(param); err != nil {
|
||||
a.logger.WithContext(a.ctx).Infof("handler param fail, err= %w", err)
|
||||
func (a *jobArchiveExecutor) submit(ctx context.Context, param *entity.JobArchiveNextParam) {
|
||||
if err := a.handle(ctx, param); err != nil {
|
||||
a.logger.WithContext(ctx).Infof("handler param fail, err= %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (a *jobArchiveExecutor) handle(param *entity.JobArchiveNextParam) error {
|
||||
func (a *jobArchiveExecutor) handle(ctx context.Context, param *entity.JobArchiveNextParam) error {
|
||||
if p := param.GetCopying(); p != nil {
|
||||
if err := a.switchStep(entity.JobArchiveStep_Copying, entity.JobStatus_Processing, mapset.NewThreadUnsafeSet(entity.JobArchiveStep_WaitForTape)); err != nil {
|
||||
if err := a.switchStep(ctx, entity.JobArchiveStep_Copying, entity.JobStatus_Processing, mapset.NewThreadUnsafeSet(entity.JobArchiveStep_WaitForTape)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
go tools.Wrap(a.ctx, func() {
|
||||
_, err := a.makeTape(p.Device, p.Barcode, p.Name)
|
||||
if err != nil {
|
||||
a.logger.WithContext(a.ctx).WithError(err).Errorf("make type has error, barcode= '%s' name= '%s'", p.Barcode, p.Name)
|
||||
tools.Working()
|
||||
go tools.Wrap(ctx, func() {
|
||||
defer tools.Done()
|
||||
if err := a.makeTape(tools.ShutdownContext, p.Device, p.Barcode, p.Name); err != nil {
|
||||
a.logger.WithContext(ctx).WithError(err).Errorf("make type has error, barcode= '%s' name= '%s'", p.Barcode, p.Name)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -97,11 +95,11 @@ func (a *jobArchiveExecutor) handle(param *entity.JobArchiveNextParam) error {
|
||||
}
|
||||
|
||||
if p := param.GetWaitForTape(); p != nil {
|
||||
return a.switchStep(entity.JobArchiveStep_WaitForTape, entity.JobStatus_Processing, mapset.NewThreadUnsafeSet(entity.JobArchiveStep_Pending, entity.JobArchiveStep_Copying))
|
||||
return a.switchStep(ctx, entity.JobArchiveStep_WaitForTape, entity.JobStatus_Processing, mapset.NewThreadUnsafeSet(entity.JobArchiveStep_Pending, entity.JobArchiveStep_Copying))
|
||||
}
|
||||
|
||||
if p := param.GetFinished(); p != nil {
|
||||
if err := a.switchStep(entity.JobArchiveStep_Finished, entity.JobStatus_Completed, mapset.NewThreadUnsafeSet(entity.JobArchiveStep_Copying)); err != nil {
|
||||
if err := a.switchStep(ctx, entity.JobArchiveStep_Finished, entity.JobStatus_Completed, mapset.NewThreadUnsafeSet(entity.JobArchiveStep_Copying)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -113,51 +111,48 @@ func (a *jobArchiveExecutor) handle(param *entity.JobArchiveNextParam) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *jobArchiveExecutor) makeTape(device, barcode, name string) (*library.Tape, error) {
|
||||
func (a *jobArchiveExecutor) makeTape(ctx context.Context, device, barcode, name string) (rerr error) {
|
||||
if !a.exe.occupyDevice(device) {
|
||||
return nil, fmt.Errorf("device is using, device= %s", device)
|
||||
return fmt.Errorf("device is using, device= %s", device)
|
||||
}
|
||||
defer a.exe.releaseDevice(device)
|
||||
defer a.makeTapeFinished()
|
||||
defer a.makeTapeFinished(tools.WithoutTimeout(ctx))
|
||||
|
||||
encryption, keyPath, keyRecycle, err := a.exe.newKey()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
time.Sleep(time.Second)
|
||||
keyRecycle()
|
||||
}()
|
||||
defer keyRecycle()
|
||||
|
||||
if err := runCmd(a.logger, a.exe.makeEncryptCmd(a.ctx, device, keyPath, barcode, name)); err != nil {
|
||||
return nil, fmt.Errorf("run encrypt script fail, %w", err)
|
||||
if err := runCmd(a.logger, a.exe.makeEncryptCmd(ctx, device, keyPath, barcode, name)); err != nil {
|
||||
return fmt.Errorf("run encrypt script fail, %w", err)
|
||||
}
|
||||
|
||||
mkfsCmd := exec.CommandContext(a.ctx, a.exe.mkfsScript)
|
||||
mkfsCmd := exec.CommandContext(ctx, a.exe.mkfsScript)
|
||||
mkfsCmd.Env = append(mkfsCmd.Env, fmt.Sprintf("DEVICE=%s", device), fmt.Sprintf("TAPE_BARCODE=%s", barcode), fmt.Sprintf("TAPE_NAME=%s", name))
|
||||
if err := runCmd(a.logger, mkfsCmd); err != nil {
|
||||
return nil, fmt.Errorf("run mkfs script fail, %w", err)
|
||||
return fmt.Errorf("run mkfs script fail, %w", err)
|
||||
}
|
||||
|
||||
mountPoint, err := os.MkdirTemp("", "*.ltfs")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("create temp mountpoint, %w", err)
|
||||
return fmt.Errorf("create temp mountpoint, %w", err)
|
||||
}
|
||||
|
||||
mountCmd := exec.CommandContext(a.ctx, a.exe.mountScript)
|
||||
mountCmd := exec.CommandContext(ctx, a.exe.mountScript)
|
||||
mountCmd.Env = append(mountCmd.Env, fmt.Sprintf("DEVICE=%s", device), fmt.Sprintf("MOUNT_POINT=%s", mountPoint))
|
||||
if err := runCmd(a.logger, mountCmd); err != nil {
|
||||
return nil, fmt.Errorf("run mount script fail, %w", err)
|
||||
return fmt.Errorf("run mount script fail, %w", err)
|
||||
}
|
||||
defer func() {
|
||||
umountCmd := exec.CommandContext(a.ctx, a.exe.umountScript)
|
||||
umountCmd := exec.CommandContext(tools.WithoutTimeout(ctx), a.exe.umountScript)
|
||||
umountCmd.Env = append(umountCmd.Env, fmt.Sprintf("MOUNT_POINT=%s", mountPoint))
|
||||
if err := runCmd(a.logger, umountCmd); err != nil {
|
||||
a.logger.WithContext(a.ctx).WithError(err).Errorf("run umount script fail, %s", mountPoint)
|
||||
a.logger.WithContext(ctx).WithError(err).Errorf("run umount script fail, %s", mountPoint)
|
||||
return
|
||||
}
|
||||
if err := os.Remove(mountPoint); err != nil {
|
||||
a.logger.WithContext(a.ctx).WithError(err).Errorf("remove mount point fail, %s", mountPoint)
|
||||
a.logger.WithContext(ctx).WithError(err).Errorf("remove mount point fail, %s", mountPoint)
|
||||
return
|
||||
}
|
||||
}()
|
||||
@@ -177,6 +172,10 @@ func (a *jobArchiveExecutor) makeTape(device, barcode, name string) (*library.Ta
|
||||
|
||||
reportHander, reportGetter := acp.NewReportGetter()
|
||||
opts = append(opts, acp.WithEventHandler(reportHander))
|
||||
|
||||
a.progress = newProgress()
|
||||
defer func() { a.progress = nil }()
|
||||
|
||||
opts = append(opts, acp.WithEventHandler(func(ev acp.Event) {
|
||||
switch e := ev.(type) {
|
||||
case *acp.EventUpdateCount:
|
||||
@@ -184,9 +183,12 @@ func (a *jobArchiveExecutor) makeTape(device, barcode, name string) (*library.Ta
|
||||
atomic.StoreInt64(&a.progress.totalFiles, e.Files)
|
||||
return
|
||||
case *acp.EventUpdateProgress:
|
||||
atomic.StoreInt64(&a.progress.bytes, e.Bytes)
|
||||
a.progress.setBytes(e.Bytes)
|
||||
atomic.StoreInt64(&a.progress.files, e.Files)
|
||||
return
|
||||
case *acp.EventReportError:
|
||||
a.logger.WithContext(ctx).Errorf("acp report error, src= '%s' dst= '%s' err= '%s'", e.Error.Src, e.Error.Dst, e.Error.Err)
|
||||
return
|
||||
case *acp.EventUpdateJob:
|
||||
job := e.Job
|
||||
src := entity.NewSourceFromACPJob(job)
|
||||
@@ -196,11 +198,17 @@ func (a *jobArchiveExecutor) makeTape(device, barcode, name string) (*library.Ta
|
||||
case "pending":
|
||||
targetStatus = entity.CopyStatus_Pending
|
||||
case "preparing":
|
||||
a.logger.Infof("file '%s' starts to prepare for copy, size= %d", src.RealPath(), job.Size)
|
||||
targetStatus = entity.CopyStatus_Running
|
||||
case "finished":
|
||||
a.logger.Infof("file '%s' copy finished, size= %d", src.RealPath(), job.Size)
|
||||
a.logger.WithContext(ctx).Infof("file '%s' copy finished, size= %d", src.RealPath(), job.Size)
|
||||
targetStatus = entity.CopyStatus_Staged
|
||||
|
||||
for dst, err := range job.FailTargets {
|
||||
if err == nil {
|
||||
continue
|
||||
}
|
||||
a.logger.WithContext(ctx).WithError(err).Errorf("file '%s' copy fail, dst= '%s'", src.RealPath(), dst)
|
||||
}
|
||||
default:
|
||||
return
|
||||
}
|
||||
@@ -218,72 +226,89 @@ func (a *jobArchiveExecutor) makeTape(device, barcode, name string) (*library.Ta
|
||||
}
|
||||
target.Status = targetStatus
|
||||
|
||||
if _, err := a.exe.SaveJob(a.ctx, a.job); err != nil {
|
||||
logrus.WithContext(a.ctx).Infof("save job for update file fail, name= %s", job.Base+path.Join(job.Path...))
|
||||
if _, err := a.exe.SaveJob(ctx, a.job); err != nil {
|
||||
logrus.WithContext(ctx).Infof("save job for update file fail, name= %s", job.Base+path.Join(job.Path...))
|
||||
}
|
||||
return
|
||||
}
|
||||
}))
|
||||
|
||||
copyer, err := acp.New(a.ctx, opts...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("start copy fail, %w", err)
|
||||
}
|
||||
copyer.Wait()
|
||||
defer func() {
|
||||
ctx := tools.WithoutTimeout(ctx)
|
||||
|
||||
report := reportGetter()
|
||||
sort.Slice(report.Jobs, func(i, j int) bool {
|
||||
return entity.NewSourceFromACPJob(report.Jobs[i]).Compare(entity.NewSourceFromACPJob(report.Jobs[j])) < 0
|
||||
})
|
||||
|
||||
filteredJobs := make([]*acp.Job, 0, len(report.Jobs))
|
||||
files := make([]*library.TapeFile, 0, len(report.Jobs))
|
||||
for _, job := range report.Jobs {
|
||||
if len(job.SuccessTargets) == 0 {
|
||||
continue
|
||||
}
|
||||
if !job.Mode.IsRegular() {
|
||||
continue
|
||||
}
|
||||
|
||||
hash, err := hex.DecodeString(job.SHA256)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("decode sha256 fail, err= %w", err)
|
||||
}
|
||||
|
||||
files = append(files, &library.TapeFile{
|
||||
Path: path.Join(job.Path...),
|
||||
Size: job.Size,
|
||||
Mode: job.Mode,
|
||||
ModTime: job.ModTime,
|
||||
WriteTime: job.WriteTime,
|
||||
Hash: hash,
|
||||
report := reportGetter()
|
||||
sort.Slice(report.Jobs, func(i, j int) bool {
|
||||
return entity.NewSourceFromACPJob(report.Jobs[i]).Compare(entity.NewSourceFromACPJob(report.Jobs[j])) < 0
|
||||
})
|
||||
filteredJobs = append(filteredJobs, job)
|
||||
}
|
||||
|
||||
tape, err := a.exe.lib.CreateTape(a.ctx, &library.Tape{
|
||||
Barcode: barcode,
|
||||
Name: name,
|
||||
Encryption: encryption,
|
||||
CreateTime: time.Now(),
|
||||
}, files)
|
||||
reportFile, err := a.exe.newReportWriter(barcode)
|
||||
if err != nil {
|
||||
a.logger.WithContext(ctx).WithError(err).Warnf("open report file fail, barcode= '%s'", barcode)
|
||||
} else {
|
||||
defer reportFile.Close()
|
||||
reportFile.Write([]byte(report.ToJSONString(false)))
|
||||
}
|
||||
|
||||
filteredJobs := make([]*acp.Job, 0, len(report.Jobs))
|
||||
files := make([]*library.TapeFile, 0, len(report.Jobs))
|
||||
for _, job := range report.Jobs {
|
||||
if len(job.SuccessTargets) == 0 {
|
||||
continue
|
||||
}
|
||||
if !job.Mode.IsRegular() {
|
||||
continue
|
||||
}
|
||||
|
||||
hash, err := hex.DecodeString(job.SHA256)
|
||||
if err != nil {
|
||||
a.logger.WithContext(ctx).WithError(err).Warnf("decode sha256 fail, path= '%s'", entity.NewSourceFromACPJob(job).RealPath())
|
||||
continue
|
||||
}
|
||||
|
||||
files = append(files, &library.TapeFile{
|
||||
Path: path.Join(job.Path...),
|
||||
Size: job.Size,
|
||||
Mode: job.Mode,
|
||||
ModTime: job.ModTime,
|
||||
WriteTime: job.WriteTime,
|
||||
Hash: hash,
|
||||
})
|
||||
filteredJobs = append(filteredJobs, job)
|
||||
}
|
||||
|
||||
tape, err := a.exe.lib.CreateTape(ctx, &library.Tape{
|
||||
Barcode: barcode,
|
||||
Name: name,
|
||||
Encryption: encryption,
|
||||
CreateTime: time.Now(),
|
||||
}, files)
|
||||
if err != nil {
|
||||
rerr = tools.AppendError(rerr, fmt.Errorf("create tape fail, barcode= '%s' name= '%s', %w", barcode, name, err))
|
||||
return
|
||||
}
|
||||
a.logger.Infof("create tape success, tape_id= %d", tape.ID)
|
||||
|
||||
if err := a.exe.lib.TrimFiles(ctx); err != nil {
|
||||
a.logger.WithError(err).Warnf("trim library files fail")
|
||||
}
|
||||
|
||||
if err := a.markSourcesAsSubmited(ctx, filteredJobs); err != nil {
|
||||
rerr = tools.AppendError(rerr, fmt.Errorf("mark source as submited fail, %w", err))
|
||||
return
|
||||
}
|
||||
}()
|
||||
|
||||
copyer, err := acp.New(ctx, opts...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("create tape fail, barcode= '%s' name= '%s', %w", barcode, name, err)
|
||||
}
|
||||
if err := a.exe.lib.TrimFiles(a.ctx); err != nil {
|
||||
a.logger.WithError(err).Warnf("trim library files fail")
|
||||
rerr = fmt.Errorf("start copy fail, %w", err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := a.markSourcesAsSubmited(filteredJobs); err != nil {
|
||||
a.submit(&entity.JobArchiveNextParam{Param: &entity.JobArchiveNextParam_WaitForTape{WaitForTape: &entity.JobArchiveWaitForTapeParam{}}})
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return tape, nil
|
||||
copyer.Wait()
|
||||
return
|
||||
}
|
||||
|
||||
func (a *jobArchiveExecutor) switchStep(target entity.JobArchiveStep, status entity.JobStatus, expect mapset.Set[entity.JobArchiveStep]) error {
|
||||
func (a *jobArchiveExecutor) switchStep(ctx context.Context, target entity.JobArchiveStep, status entity.JobStatus, expect mapset.Set[entity.JobArchiveStep]) error {
|
||||
a.stateLock.Lock()
|
||||
defer a.stateLock.Unlock()
|
||||
|
||||
@@ -293,14 +318,14 @@ func (a *jobArchiveExecutor) switchStep(target entity.JobArchiveStep, status ent
|
||||
|
||||
a.state.Step = target
|
||||
a.job.Status = status
|
||||
if _, err := a.exe.SaveJob(a.ctx, a.job); err != nil {
|
||||
if _, err := a.exe.SaveJob(ctx, a.job); err != nil {
|
||||
return fmt.Errorf("switch to step copying, save job fail, %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *jobArchiveExecutor) markSourcesAsSubmited(jobs []*acp.Job) error {
|
||||
func (a *jobArchiveExecutor) markSourcesAsSubmited(ctx context.Context, jobs []*acp.Job) error {
|
||||
a.stateLock.Lock()
|
||||
defer a.stateLock.Unlock()
|
||||
|
||||
@@ -322,14 +347,9 @@ func (a *jobArchiveExecutor) markSourcesAsSubmited(jobs []*acp.Job) error {
|
||||
target.Status = entity.CopyStatus_Submited
|
||||
}
|
||||
|
||||
if _, err := a.exe.SaveJob(a.ctx, a.job); err != nil {
|
||||
if _, err := a.exe.SaveJob(ctx, a.job); err != nil {
|
||||
return fmt.Errorf("mark sources as submited, save job, %w", err)
|
||||
}
|
||||
|
||||
atomic.StoreInt64(&a.progress.bytes, 0)
|
||||
atomic.StoreInt64(&a.progress.files, 0)
|
||||
atomic.StoreInt64(&a.progress.totalBytes, 0)
|
||||
atomic.StoreInt64(&a.progress.totalFiles, 0)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -348,10 +368,10 @@ func (a *jobArchiveExecutor) getTodoSources() int {
|
||||
return todo
|
||||
}
|
||||
|
||||
func (a *jobArchiveExecutor) makeTapeFinished() {
|
||||
func (a *jobArchiveExecutor) makeTapeFinished(ctx context.Context) {
|
||||
if a.getTodoSources() > 0 {
|
||||
a.submit(&entity.JobArchiveNextParam{Param: &entity.JobArchiveNextParam_WaitForTape{WaitForTape: &entity.JobArchiveWaitForTapeParam{}}})
|
||||
a.submit(ctx, &entity.JobArchiveNextParam{Param: &entity.JobArchiveNextParam_WaitForTape{WaitForTape: &entity.JobArchiveWaitForTapeParam{}}})
|
||||
} else {
|
||||
a.submit(&entity.JobArchiveNextParam{Param: &entity.JobArchiveNextParam_Finished{Finished: &entity.JobArchiveFinishedParam{}}})
|
||||
a.submit(ctx, &entity.JobArchiveNextParam{Param: &entity.JobArchiveNextParam_Finished{Finished: &entity.JobArchiveFinishedParam{}}})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,3 +48,21 @@ func runCmd(logger *logrus.Logger, cmd *exec.Cmd) error {
|
||||
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
func (e *Executor) reportPath(barcode string) (string, string) {
|
||||
return path.Join(e.workDirectory, "write-reports"), fmt.Sprintf("%s.log", barcode)
|
||||
}
|
||||
|
||||
func (e *Executor) newReportWriter(barcode string) (*os.File, error) {
|
||||
dir, filename := e.reportPath(barcode)
|
||||
if err := os.MkdirAll(dir, 0755); err != nil {
|
||||
return nil, fmt.Errorf("make job log dir fail, path= '%s', err= %w", dir, err)
|
||||
}
|
||||
|
||||
file, err := os.OpenFile(path.Join(dir, filename), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("create file fail, path= '%s', err= %w", path.Join(dir, filename), err)
|
||||
}
|
||||
|
||||
return file, nil
|
||||
}
|
||||
|
||||
@@ -1,8 +1,55 @@
|
||||
package executor
|
||||
|
||||
import (
|
||||
"sync/atomic"
|
||||
"time"
|
||||
)
|
||||
|
||||
const SpeedLen = 30
|
||||
|
||||
type speedEvent struct {
|
||||
bytes int64
|
||||
time time.Time
|
||||
}
|
||||
|
||||
type progress struct {
|
||||
speed int64
|
||||
speedEvents []speedEvent
|
||||
speedLen int
|
||||
speedIdx int
|
||||
|
||||
startTime time.Time
|
||||
speed int64
|
||||
|
||||
totalBytes, totalFiles int64
|
||||
bytes, files int64
|
||||
}
|
||||
|
||||
func newProgress() *progress {
|
||||
return &progress{speedEvents: make([]speedEvent, SpeedLen), speedLen: SpeedLen, startTime: time.Now()}
|
||||
}
|
||||
|
||||
func (p *progress) setBytes(bytes int64) {
|
||||
atomic.StoreInt64(&p.bytes, bytes)
|
||||
now := time.Now()
|
||||
|
||||
p.speedEvents[p.speedIdx] = speedEvent{bytes: bytes, time: now}
|
||||
for earliest := p.speedIdx; ; {
|
||||
earliest++
|
||||
if earliest >= p.speedLen {
|
||||
earliest = 0
|
||||
}
|
||||
if earliest == p.speedIdx {
|
||||
break
|
||||
}
|
||||
|
||||
if !p.speedEvents[earliest].time.IsZero() {
|
||||
p.speed = (bytes - p.speedEvents[earliest].bytes) * 1e9 / now.Sub(p.speedEvents[earliest].time).Nanoseconds()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
p.speedIdx++
|
||||
if p.speedIdx >= p.speedLen {
|
||||
p.speedIdx = 0
|
||||
}
|
||||
}
|
||||
|
||||
1
frontend/.gitignore
vendored
1
frontend/.gitignore
vendored
@@ -22,3 +22,4 @@ dist-ssr
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
.env
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
"chonky-icon-fontawesome": "^2.3.2",
|
||||
"fast-text-encoding": "^1.0.6",
|
||||
"filesize": "^10.0.5",
|
||||
"format-duration": "^2.0.0",
|
||||
"moment": "^2.29.4",
|
||||
"react": "^18.2.0",
|
||||
"react-dnd": "^11.1.3",
|
||||
@@ -34,6 +35,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@protobuf-ts/plugin": "^2.8.2",
|
||||
"@types/node": "^18.11.14",
|
||||
"@types/react": "^18.0.17",
|
||||
"@types/react-dom": "^18.0.6",
|
||||
"@vitejs/plugin-react": "^2.1.0",
|
||||
|
||||
12
frontend/pnpm-lock.yaml
generated
12
frontend/pnpm-lock.yaml
generated
@@ -13,6 +13,7 @@ specifiers:
|
||||
'@protobuf-ts/plugin': ^2.8.2
|
||||
'@protobuf-ts/runtime': ^2.8.2
|
||||
'@protobuf-ts/runtime-rpc': ^2.8.2
|
||||
'@types/node': ^18.11.14
|
||||
'@types/react': ^18.0.17
|
||||
'@types/react-dom': ^18.0.6
|
||||
'@vitejs/plugin-react': ^2.1.0
|
||||
@@ -20,6 +21,7 @@ specifiers:
|
||||
chonky-icon-fontawesome: ^2.3.2
|
||||
fast-text-encoding: ^1.0.6
|
||||
filesize: ^10.0.5
|
||||
format-duration: ^2.0.0
|
||||
less: ^4.1.3
|
||||
moment: ^2.29.4
|
||||
prettier: 2.7.1
|
||||
@@ -48,6 +50,7 @@ dependencies:
|
||||
chonky-icon-fontawesome: 2.3.2_qge232svojtclvlhf4p5efbcfu
|
||||
fast-text-encoding: 1.0.6
|
||||
filesize: 10.0.5
|
||||
format-duration: 2.0.0
|
||||
moment: 2.29.4
|
||||
react: 18.2.0
|
||||
react-dnd: 11.1.3_biqbaboplfbrettd7655fr4n2y
|
||||
@@ -57,6 +60,7 @@ dependencies:
|
||||
|
||||
devDependencies:
|
||||
'@protobuf-ts/plugin': 2.8.2
|
||||
'@types/node': 18.11.14
|
||||
'@types/react': 18.0.21
|
||||
'@types/react-dom': 18.0.6
|
||||
'@vitejs/plugin-react': 2.1.0_vite@3.1.8
|
||||
@@ -1043,6 +1047,10 @@ packages:
|
||||
resolution: {integrity: sha512-qDpXKGgwKywnQt/64fH1O0LiPA++QGIYeykEUiZ51HymKVRLnUSGcRuF60IfpPeeXiuRwiR/W4y7S5VzbrgLCA==}
|
||||
dev: false
|
||||
|
||||
/@types/node/18.11.14:
|
||||
resolution: {integrity: sha512-0KXV57tENYmmJMl+FekeW9V3O/rlcqGQQJ/hNh9r8pKIj304pskWuEd8fCyNT86g/TpO0gcOTiLzsHLEURFMIQ==}
|
||||
dev: true
|
||||
|
||||
/@types/parse-json/4.0.0:
|
||||
resolution: {integrity: sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==}
|
||||
dev: false
|
||||
@@ -1657,6 +1665,10 @@ packages:
|
||||
resolution: {integrity: sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==}
|
||||
dev: false
|
||||
|
||||
/format-duration/2.0.0:
|
||||
resolution: {integrity: sha512-ARqJ9qXm71pw3SGAY7bibf8lRLvltOXLjWjzzR3UrUjHu1zdeYpA/Z+u+ltdhrfRa440OjEsHNzdmuZViqqQWQ==}
|
||||
dev: false
|
||||
|
||||
/fsevents/2.3.2:
|
||||
resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
|
||||
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
|
||||
|
||||
@@ -7,7 +7,7 @@ import moment from "moment";
|
||||
const apiBase: string = (() => {
|
||||
const base = (window as any).apiBase as string;
|
||||
if (!base || base === "%%API_BASE%%") {
|
||||
return "http://127.0.0.1:8080/services";
|
||||
return "http://localhost:5173/services";
|
||||
}
|
||||
return base;
|
||||
})();
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
padding: 0.5em;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
overflow-y: hidden;
|
||||
|
||||
.browser-container {
|
||||
margin: 0;
|
||||
@@ -26,6 +27,7 @@
|
||||
height: 100%;
|
||||
|
||||
.browser {
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
padding-right: 0.5em;
|
||||
|
||||
@@ -45,6 +47,19 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.job-list {
|
||||
min-height: min-content;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
overflow-y: scroll;
|
||||
// -ms-overflow-style: none; /* IE and Edge */
|
||||
// scrollbar-width: none; /* Firefox */
|
||||
|
||||
// &::-webkit-scrollbar {
|
||||
// display: none;
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -115,6 +115,10 @@ export interface JobDisplayArchive {
|
||||
* @generated from protobuf field: optional int64 speed = 5;
|
||||
*/
|
||||
speed?: bigint;
|
||||
/**
|
||||
* @generated from protobuf field: int64 startTime = 6;
|
||||
*/
|
||||
startTime: bigint;
|
||||
}
|
||||
/**
|
||||
* @generated from protobuf enum job_archive.JobArchiveStep
|
||||
@@ -429,11 +433,12 @@ class JobDisplayArchive$Type extends MessageType<JobDisplayArchive> {
|
||||
{ no: 2, name: "copyedFiles", kind: "scalar", T: 3 /*ScalarType.INT64*/, L: 0 /*LongType.BIGINT*/ },
|
||||
{ no: 3, name: "totalBytes", kind: "scalar", T: 3 /*ScalarType.INT64*/, L: 0 /*LongType.BIGINT*/ },
|
||||
{ no: 4, name: "totalFiles", kind: "scalar", T: 3 /*ScalarType.INT64*/, L: 0 /*LongType.BIGINT*/ },
|
||||
{ no: 5, name: "speed", kind: "scalar", opt: true, T: 3 /*ScalarType.INT64*/, L: 0 /*LongType.BIGINT*/ }
|
||||
{ no: 5, name: "speed", kind: "scalar", opt: true, T: 3 /*ScalarType.INT64*/, L: 0 /*LongType.BIGINT*/ },
|
||||
{ no: 6, name: "startTime", kind: "scalar", T: 3 /*ScalarType.INT64*/, L: 0 /*LongType.BIGINT*/ }
|
||||
]);
|
||||
}
|
||||
create(value?: PartialMessage<JobDisplayArchive>): JobDisplayArchive {
|
||||
const message = { copyedBytes: 0n, copyedFiles: 0n, totalBytes: 0n, totalFiles: 0n };
|
||||
const message = { copyedBytes: 0n, copyedFiles: 0n, totalBytes: 0n, totalFiles: 0n, startTime: 0n };
|
||||
globalThis.Object.defineProperty(message, MESSAGE_TYPE, { enumerable: false, value: this });
|
||||
if (value !== undefined)
|
||||
reflectionMergePartial<JobDisplayArchive>(this, message, value);
|
||||
@@ -459,6 +464,9 @@ class JobDisplayArchive$Type extends MessageType<JobDisplayArchive> {
|
||||
case /* optional int64 speed */ 5:
|
||||
message.speed = reader.int64().toBigInt();
|
||||
break;
|
||||
case /* int64 startTime */ 6:
|
||||
message.startTime = reader.int64().toBigInt();
|
||||
break;
|
||||
default:
|
||||
let u = options.readUnknownField;
|
||||
if (u === "throw")
|
||||
@@ -486,6 +494,9 @@ class JobDisplayArchive$Type extends MessageType<JobDisplayArchive> {
|
||||
/* optional int64 speed = 5; */
|
||||
if (message.speed !== undefined)
|
||||
writer.tag(5, WireType.Varint).int64(message.speed);
|
||||
/* int64 startTime = 6; */
|
||||
if (message.startTime !== 0n)
|
||||
writer.tag(6, WireType.Varint).int64(message.startTime);
|
||||
let u = options.writeUnknownFields;
|
||||
if (u !== false)
|
||||
(u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Fragment, ChangeEvent } from "react";
|
||||
import { useState, useRef, useEffect, useMemo, useCallback, FC } from "react";
|
||||
import { assert } from "@protobuf-ts/runtime";
|
||||
import format from "format-duration";
|
||||
|
||||
import Grid from "@mui/material/Grid";
|
||||
import Box from "@mui/material/Box";
|
||||
@@ -75,9 +76,11 @@ export const JobsBrowser = () => {
|
||||
</List>
|
||||
</Grid>
|
||||
<Grid className="browser" item xs={10}>
|
||||
{jobs.map((job) => (
|
||||
<GetJobCard job={job} key={job.id.toString()} refresh={refresh} />
|
||||
))}
|
||||
<div className="job-list">
|
||||
{jobs.map((job) => (
|
||||
<GetJobCard job={job} key={job.id.toString()} refresh={refresh} />
|
||||
))}
|
||||
</div>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Box>
|
||||
@@ -113,38 +116,6 @@ const ArchiveCard = ({
|
||||
display: JobDisplayArchive | null;
|
||||
refresh: () => Promise<void>;
|
||||
}): JSX.Element => {
|
||||
const [lastDisplay, setLastDisplay] = useState<ArchiveLastDisplay | null>(null);
|
||||
const [speed, setSpeed] = useState<number>(NaN);
|
||||
const diffDisplay = useCallback(
|
||||
(current: ArchiveLastDisplay | null) => {
|
||||
if (!lastDisplay) {
|
||||
setLastDisplay(current);
|
||||
return;
|
||||
}
|
||||
if (!current) {
|
||||
setLastDisplay(current);
|
||||
setSpeed(NaN);
|
||||
return;
|
||||
}
|
||||
|
||||
const duration = current.lastUpdate - lastDisplay.lastUpdate;
|
||||
if (duration) {
|
||||
const speed = ((Number(current.copyedBytes) - Number(lastDisplay.copyedBytes)) / duration) * 1000;
|
||||
setSpeed(speed);
|
||||
}
|
||||
|
||||
setLastDisplay(current);
|
||||
},
|
||||
[lastDisplay, setLastDisplay, setSpeed]
|
||||
);
|
||||
useEffect(() => {
|
||||
if (!display) {
|
||||
diffDisplay(null);
|
||||
return;
|
||||
}
|
||||
diffDisplay({ copyedBytes: display.copyedBytes, lastUpdate: Date.now() });
|
||||
}, [display]);
|
||||
|
||||
const [fields, progress] = useMemo(() => {
|
||||
const totalFiles = state.sources.length;
|
||||
let submitedFiles = 0,
|
||||
@@ -161,11 +132,25 @@ const ArchiveCard = ({
|
||||
|
||||
const copyedFiles = submitedFiles + Number(display?.copyedFiles || 0n);
|
||||
const copyedBytes = submitedBytes + Number(display?.copyedBytes || 0n);
|
||||
const avgSpeed = (() => {
|
||||
if (!display || !display.copyedBytes || !display.startTime) {
|
||||
return NaN;
|
||||
}
|
||||
|
||||
const duration = Date.now() / 1000 - Number(display.startTime);
|
||||
if (duration <= 0) {
|
||||
return NaN;
|
||||
}
|
||||
|
||||
return Number(display.copyedBytes) / duration;
|
||||
})();
|
||||
|
||||
const progress = (totalBytes > 0 ? copyedBytes / totalBytes : 1) * 100;
|
||||
const fields = [
|
||||
{ name: "Current Step", value: JobArchiveStep[state.step] },
|
||||
{ name: "Current Speed", value: !Number.isNaN(speed) ? `${formatFilesize(speed)}/s` : "--" },
|
||||
{ name: "Current Speed", value: display?.speed ? `${formatFilesize(display?.speed)}/s` : "--" },
|
||||
{ name: "Average Speed", value: !isNaN(avgSpeed) ? `${formatFilesize(avgSpeed)}/s` : "--" },
|
||||
{ name: "Estimated Time", value: !isNaN(avgSpeed) ? format(((totalBytes - copyedBytes) * 1000) / avgSpeed) : "--" },
|
||||
{ name: "Total Files", value: totalFiles },
|
||||
{ name: "Total Bytes", value: formatFilesize(totalBytes) },
|
||||
{ name: "Submited Files", value: submitedFiles },
|
||||
@@ -175,7 +160,7 @@ const ArchiveCard = ({
|
||||
];
|
||||
|
||||
return [fields, progress];
|
||||
}, [state, display, speed]);
|
||||
}, [state, display]);
|
||||
|
||||
return (
|
||||
<JobCard
|
||||
@@ -379,7 +364,7 @@ const LogConsole = ({ jobId }: { jobId: bigint }) => {
|
||||
return () => {
|
||||
closed = true;
|
||||
};
|
||||
}, []);
|
||||
}, [refreshLog]);
|
||||
|
||||
return <pre>{log || "loading..."}</pre>;
|
||||
};
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es2020",
|
||||
"composite": true,
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "Node",
|
||||
|
||||
@@ -1,15 +1,26 @@
|
||||
import { defineConfig } from "vite";
|
||||
import { defineConfig, loadEnv } from "vite";
|
||||
import react from "@vitejs/plugin-react";
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
build: {
|
||||
target: "es2020",
|
||||
},
|
||||
optimizeDeps: {
|
||||
esbuildOptions: {
|
||||
export default defineConfig(({ command, mode }) => {
|
||||
const env = loadEnv(mode, process.cwd(), "");
|
||||
console.log(env);
|
||||
|
||||
return {
|
||||
plugins: [react()],
|
||||
build: {
|
||||
target: "es2020",
|
||||
},
|
||||
},
|
||||
optimizeDeps: {
|
||||
esbuildOptions: {
|
||||
target: "es2020",
|
||||
},
|
||||
},
|
||||
server: {
|
||||
proxy: {
|
||||
// target http://localhost:5173
|
||||
"/services": env.DEV_SERVICE_BASE,
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
2
go.mod
2
go.mod
@@ -3,7 +3,7 @@ module github.com/abc950309/tapewriter
|
||||
go 1.18
|
||||
|
||||
require (
|
||||
github.com/abc950309/acp v0.0.0-20221212144614-c5de5e555428
|
||||
github.com/abc950309/acp v0.0.0-20221213054500-913956ff10a1
|
||||
github.com/aws/aws-sdk-go v1.44.118
|
||||
github.com/davecgh/go-spew v1.1.1
|
||||
github.com/deckarep/golang-set/v2 v2.1.0
|
||||
|
||||
6
go.sum
6
go.sum
@@ -21,6 +21,12 @@ github.com/abc950309/acp v0.0.0-20221211170531-ae151264e710 h1:WedtGWyNGXdHZDft0
|
||||
github.com/abc950309/acp v0.0.0-20221211170531-ae151264e710/go.mod h1:5RsleINAlZ326MJ8fmoCW9IJdnlpa6ZVdHqufsfcQMI=
|
||||
github.com/abc950309/acp v0.0.0-20221212144614-c5de5e555428 h1:NQDEsoxNJDxdMuZCJq0R9hqeaR64X8oyEhx0PKUCSwo=
|
||||
github.com/abc950309/acp v0.0.0-20221212144614-c5de5e555428/go.mod h1:5RsleINAlZ326MJ8fmoCW9IJdnlpa6ZVdHqufsfcQMI=
|
||||
github.com/abc950309/acp v0.0.0-20221213013859-b7a44e4c0071 h1:sKxesiKeO5dX+TY96m0iegmqvthqH+lN7q5LRG2e8ck=
|
||||
github.com/abc950309/acp v0.0.0-20221213013859-b7a44e4c0071/go.mod h1:5RsleINAlZ326MJ8fmoCW9IJdnlpa6ZVdHqufsfcQMI=
|
||||
github.com/abc950309/acp v0.0.0-20221213025816-edd8196e43e6 h1:lgO5pSBYSHqkCYP3/iiFefcsi7udjX1NaujO2cPx5JE=
|
||||
github.com/abc950309/acp v0.0.0-20221213025816-edd8196e43e6/go.mod h1:7gK/wICIhVBZ6B2AZm+0uN06wDhKLSsq4TME/fwJUJI=
|
||||
github.com/abc950309/acp v0.0.0-20221213054500-913956ff10a1 h1:UgiD4G3c3WROUHp+elpLVvKuW0+9xErtgkilnDb+XdU=
|
||||
github.com/abc950309/acp v0.0.0-20221213054500-913956ff10a1/go.mod h1:7gK/wICIhVBZ6B2AZm+0uN06wDhKLSsq4TME/fwJUJI=
|
||||
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
set -ex;
|
||||
|
||||
sleep 15
|
||||
sleep 2
|
||||
umount ${MOUNT_POINT}
|
||||
sleep 60
|
||||
|
||||
42
tools/context.go
Normal file
42
tools/context.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package tools
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
type noTimeout struct {
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
func (c noTimeout) Deadline() (time.Time, bool) { return time.Time{}, false }
|
||||
func (c noTimeout) Done() <-chan struct{} { return nil }
|
||||
func (c noTimeout) Err() error { return nil }
|
||||
func (c noTimeout) Value(key interface{}) interface{} { return c.ctx.Value(key) }
|
||||
|
||||
// WithoutCancel returns a context that is never canceled.
|
||||
func WithoutTimeout(ctx context.Context) context.Context {
|
||||
return noTimeout{ctx: ctx}
|
||||
}
|
||||
|
||||
var (
|
||||
ShutdownContext context.Context
|
||||
)
|
||||
|
||||
func init() {
|
||||
c := make(chan os.Signal, 1)
|
||||
signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
|
||||
|
||||
bgctx, cancel := context.WithCancel(context.Background())
|
||||
go func() {
|
||||
oscall := <-c
|
||||
log.Printf("system call: %+v", oscall)
|
||||
cancel()
|
||||
}()
|
||||
|
||||
ShutdownContext = bgctx
|
||||
}
|
||||
12
tools/error.go
Normal file
12
tools/error.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package tools
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/go-multierror"
|
||||
)
|
||||
|
||||
func AppendError(err, e error) error {
|
||||
if err != nil {
|
||||
return multierror.Append(err, e)
|
||||
}
|
||||
return e
|
||||
}
|
||||
19
tools/working.go
Normal file
19
tools/working.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package tools
|
||||
|
||||
import "sync"
|
||||
|
||||
var (
|
||||
wg sync.WaitGroup
|
||||
)
|
||||
|
||||
func Working() {
|
||||
wg.Add(1)
|
||||
}
|
||||
|
||||
func Done() {
|
||||
wg.Done()
|
||||
}
|
||||
|
||||
func Wait() {
|
||||
wg.Wait()
|
||||
}
|
||||
Reference in New Issue
Block a user