From 607fe3a146f14ad2af1158e454fd7cf63443973c Mon Sep 17 00:00:00 2001 From: ziming Date: Wed, 4 Jun 2025 11:51:39 +0800 Subject: [PATCH 01/14] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BB=BB=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/server/main.go | 2 + configs/config.yaml | 8 + configs/config_test.yaml | 8 + internal/biz/repo/order.go | 1 + internal/biz/wechat_query.go | 67 ++++ internal/conf/conf.pb.go | 597 ++++++++++++++++++++----------- internal/conf/conf.proto | 12 + internal/data/repoimpl/order.go | 19 + internal/pkg/rdsmq/logger.go | 15 + internal/pkg/rdsmq/manager.go | 47 +++ internal/pkg/rdsmq/rdsmq.go | 156 ++++++++ internal/server/http.go | 1 + internal/server/provider_set.go | 1 + internal/server/rds_consume.go | 46 +++ internal/service/cmb.go | 17 + internal/service/voucher.go | 7 + internal/service/wechat_query.go | 50 +++ 17 files changed, 846 insertions(+), 208 deletions(-) create mode 100644 internal/biz/wechat_query.go create mode 100644 internal/pkg/rdsmq/logger.go create mode 100644 internal/pkg/rdsmq/manager.go create mode 100644 internal/pkg/rdsmq/rdsmq.go create mode 100644 internal/server/rds_consume.go create mode 100644 internal/service/wechat_query.go diff --git a/cmd/server/main.go b/cmd/server/main.go index 362c44b..48e6aa6 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -59,6 +59,7 @@ func newApp( consumerServer *server.Consumer, cronServer *server.CronServer, wechatNotifyConsumer *server.WechatNotifyConsumer, + rdbConsumer *server.RdbConsumer, ) *kratos.App { return kratos.New( kratos.ID(id), @@ -70,6 +71,7 @@ func newApp( consumerServer, cronServer, wechatNotifyConsumer, + rdbConsumer, ), ) } diff --git a/configs/config.yaml b/configs/config.yaml index 19b20af..9425c90 100644 --- a/configs/config.yaml +++ b/configs/config.yaml @@ -84,6 +84,14 @@ cron: isOpen: true #是否启动 true/false command: "0 0 1 * * ?" # 每天凌晨1点执行一次 +rdsMQ: + wechatQuery: #发放结算 + name: "wechatQuery" + retryNum: 1 #重试次数 + numWorkers: 1 #协程数量,不配置默认为10 + waitTime: 1s #处理完成后等待时间 + isOpen: true #是否启动消费 true/false + #配置日志 logs: business: business.log #业务日志路径:如果不写日志,则不配置或配置为空 diff --git a/configs/config_test.yaml b/configs/config_test.yaml index 19b20af..9718289 100644 --- a/configs/config_test.yaml +++ b/configs/config_test.yaml @@ -84,6 +84,14 @@ cron: isOpen: true #是否启动 true/false command: "0 0 1 * * ?" # 每天凌晨1点执行一次 +rdsMQ: + wechatQuery: #发放结算 + name: "wechatQuery" + retryNum: 1 #重试次数 + numWorkers: 1 #协程数量,不配置默认为10 + waitTime: 1s #处理完成后等待时间 + isOpen: true #是否启动消费 true/false + #配置日志 logs: business: business.log #业务日志路径:如果不写日志,则不配置或配置为空 diff --git a/internal/biz/repo/order.go b/internal/biz/repo/order.go index a1c583a..8c9bab9 100644 --- a/internal/biz/repo/order.go +++ b/internal/biz/repo/order.go @@ -7,6 +7,7 @@ import ( ) type OrderRepo interface { + FinByStockIdInBatches(ctx context.Context, batchNo string, fun func(ctx context.Context, rows []*bo.OrderBo) error) error FindIngInBatches(ctx context.Context, fun func(ctx context.Context, rows []*bo.OrderBo) error) error FindInBatches(ctx context.Context, w *bo.FindInBatchesUseBo, fun func(ctx context.Context, rows []*bo.OrderBo) error) error GetByOutBizNo(ctx context.Context, t vo.OrderType, outBizNo string) (*bo.OrderBo, error) diff --git a/internal/biz/wechat_query.go b/internal/biz/wechat_query.go new file mode 100644 index 0000000..166d296 --- /dev/null +++ b/internal/biz/wechat_query.go @@ -0,0 +1,67 @@ +package biz + +import ( + "context" + "fmt" + "github.com/go-kratos/kratos/v2/log" + "time" + "voucher/internal/biz/bo" +) + +func (v *VoucherBiz) PushWechatQuery(ctx context.Context, productNo string) error { + + product, err := v.ProductRepo.GetByProductNo(ctx, productNo) + if err != nil { + return err + } + + queue := v.bc.RdsMQ.GetWechatQuery() + if queue == nil { + return fmt.Errorf("队列不存在") + } + + _, err = v.rdb.Rdb.RPush(ctx, queue.Name, product.BatchNo).Result() + if err != nil { + return fmt.Errorf("添加到队列失败:%v", err) + } + + return nil +} + +func (v *VoucherBiz) WechatQuery(ctx context.Context, batchNo string) error { + + if batchNo == "" { + return fmt.Errorf("batchNo is empty") + } + + return v.OrderRepo.FinByStockIdInBatches(ctx, batchNo, func(ctx context.Context, rows []*bo.OrderBo) error { + + for _, order := range rows { + + if err := v.wechatQuery(ctx, order); err != nil { + log.Errorf("微信查询券订单状态发生错误,batchNo:%s,orderNo:%s,couponId:%s,appId:%s,openId:%s,err:%v", + batchNo, order.OrderNo, order.VoucherNo, order.AppID, order.Account, err) + } + + } + + time.Sleep(1 * time.Second) + + return nil + }) + +} + +func (v *VoucherBiz) wechatQuery(ctx context.Context, order *bo.OrderBo) error { + + status, err := v.WechatCpnRepo.Query(ctx, order) + if err != nil { + return err + } + + if status.IsUse() { + return v.used(ctx, order) + } + + return nil +} diff --git a/internal/conf/conf.pb.go b/internal/conf/conf.pb.go index f400113..dec41c7 100644 --- a/internal/conf/conf.pb.go +++ b/internal/conf/conf.pb.go @@ -35,6 +35,7 @@ type Bootstrap struct { WechatNotifyMQ *WechatNotifyMQ `protobuf:"bytes,7,opt,name=wechatNotifyMQ,proto3" json:"wechatNotifyMQ,omitempty"` Alarm *Alarm `protobuf:"bytes,8,opt,name=alarm,proto3" json:"alarm,omitempty"` Cron *Cron `protobuf:"bytes,9,opt,name=cron,proto3" json:"cron,omitempty"` + RdsMQ *RdsMQ `protobuf:"bytes,10,opt,name=rdsMQ,proto3" json:"rdsMQ,omitempty"` } func (x *Bootstrap) Reset() { @@ -132,6 +133,13 @@ func (x *Bootstrap) GetCron() *Cron { return nil } +func (x *Bootstrap) GetRdsMQ() *RdsMQ { + if x != nil { + return x.RdsMQ + } + return nil +} + type Server struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -827,6 +835,53 @@ func (x *Cron) GetCommandMap() map[string]*Cron_CommandMap { return nil } +type RdsMQ struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + WechatQuery *RdsMQ_Queue `protobuf:"bytes,1,opt,name=wechatQuery,proto3" json:"wechatQuery,omitempty"` +} + +func (x *RdsMQ) Reset() { + *x = RdsMQ{} + if protoimpl.UnsafeEnabled { + mi := &file_conf_conf_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RdsMQ) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RdsMQ) ProtoMessage() {} + +func (x *RdsMQ) ProtoReflect() protoreflect.Message { + mi := &file_conf_conf_proto_msgTypes[10] + 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 RdsMQ.ProtoReflect.Descriptor instead. +func (*RdsMQ) Descriptor() ([]byte, []int) { + return file_conf_conf_proto_rawDescGZIP(), []int{10} +} + +func (x *RdsMQ) GetWechatQuery() *RdsMQ_Queue { + if x != nil { + return x.WechatQuery + } + return nil +} + type Logs struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -839,7 +894,7 @@ type Logs struct { func (x *Logs) Reset() { *x = Logs{} if protoimpl.UnsafeEnabled { - mi := &file_conf_conf_proto_msgTypes[10] + mi := &file_conf_conf_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -852,7 +907,7 @@ func (x *Logs) String() string { func (*Logs) ProtoMessage() {} func (x *Logs) ProtoReflect() protoreflect.Message { - mi := &file_conf_conf_proto_msgTypes[10] + mi := &file_conf_conf_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -865,7 +920,7 @@ func (x *Logs) ProtoReflect() protoreflect.Message { // Deprecated: Use Logs.ProtoReflect.Descriptor instead. func (*Logs) Descriptor() ([]byte, []int) { - return file_conf_conf_proto_rawDescGZIP(), []int{10} + return file_conf_conf_proto_rawDescGZIP(), []int{11} } func (x *Logs) GetBusiness() string { @@ -897,7 +952,7 @@ type Server_HTTP struct { func (x *Server_HTTP) Reset() { *x = Server_HTTP{} if protoimpl.UnsafeEnabled { - mi := &file_conf_conf_proto_msgTypes[11] + mi := &file_conf_conf_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -910,7 +965,7 @@ func (x *Server_HTTP) String() string { func (*Server_HTTP) ProtoMessage() {} func (x *Server_HTTP) ProtoReflect() protoreflect.Message { - mi := &file_conf_conf_proto_msgTypes[11] + mi := &file_conf_conf_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -977,7 +1032,7 @@ type Data_Database struct { func (x *Data_Database) Reset() { *x = Data_Database{} if protoimpl.UnsafeEnabled { - mi := &file_conf_conf_proto_msgTypes[12] + mi := &file_conf_conf_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -990,7 +1045,7 @@ func (x *Data_Database) String() string { func (*Data_Database) ProtoMessage() {} func (x *Data_Database) ProtoReflect() protoreflect.Message { - mi := &file_conf_conf_proto_msgTypes[12] + mi := &file_conf_conf_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1067,7 +1122,7 @@ type Data_Redis struct { func (x *Data_Redis) Reset() { *x = Data_Redis{} if protoimpl.UnsafeEnabled { - mi := &file_conf_conf_proto_msgTypes[13] + mi := &file_conf_conf_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1080,7 +1135,7 @@ func (x *Data_Redis) String() string { func (*Data_Redis) ProtoMessage() {} func (x *Data_Redis) ProtoReflect() protoreflect.Message { - mi := &file_conf_conf_proto_msgTypes[13] + mi := &file_conf_conf_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1171,7 +1226,7 @@ type Cron_CommandMap struct { func (x *Cron_CommandMap) Reset() { *x = Cron_CommandMap{} if protoimpl.UnsafeEnabled { - mi := &file_conf_conf_proto_msgTypes[15] + mi := &file_conf_conf_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1184,7 +1239,7 @@ func (x *Cron_CommandMap) String() string { func (*Cron_CommandMap) ProtoMessage() {} func (x *Cron_CommandMap) ProtoReflect() protoreflect.Message { - mi := &file_conf_conf_proto_msgTypes[15] + mi := &file_conf_conf_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1214,6 +1269,85 @@ func (x *Cron_CommandMap) GetCommand() string { return "" } +type RdsMQ_Queue struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + IsOpen bool `protobuf:"varint,2,opt,name=isOpen,proto3" json:"isOpen,omitempty"` + RetryNum uint32 `protobuf:"varint,3,opt,name=retryNum,proto3" json:"retryNum,omitempty"` + NumWorkers uint32 `protobuf:"varint,4,opt,name=numWorkers,proto3" json:"numWorkers,omitempty"` + WaitTime *durationpb.Duration `protobuf:"bytes,5,opt,name=waitTime,proto3" json:"waitTime,omitempty"` +} + +func (x *RdsMQ_Queue) Reset() { + *x = RdsMQ_Queue{} + if protoimpl.UnsafeEnabled { + mi := &file_conf_conf_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RdsMQ_Queue) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RdsMQ_Queue) ProtoMessage() {} + +func (x *RdsMQ_Queue) ProtoReflect() protoreflect.Message { + mi := &file_conf_conf_proto_msgTypes[18] + 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 RdsMQ_Queue.ProtoReflect.Descriptor instead. +func (*RdsMQ_Queue) Descriptor() ([]byte, []int) { + return file_conf_conf_proto_rawDescGZIP(), []int{10, 0} +} + +func (x *RdsMQ_Queue) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *RdsMQ_Queue) GetIsOpen() bool { + if x != nil { + return x.IsOpen + } + return false +} + +func (x *RdsMQ_Queue) GetRetryNum() uint32 { + if x != nil { + return x.RetryNum + } + return 0 +} + +func (x *RdsMQ_Queue) GetNumWorkers() uint32 { + if x != nil { + return x.NumWorkers + } + return 0 +} + +func (x *RdsMQ_Queue) GetWaitTime() *durationpb.Duration { + if x != nil { + return x.WaitTime + } + return nil +} + var File_conf_conf_proto protoreflect.FileDescriptor var file_conf_conf_proto_rawDesc = []byte{ @@ -1221,7 +1355,7 @@ var file_conf_conf_proto_rawDesc = []byte{ 0x6f, 0x12, 0x0e, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x22, 0xbb, 0x03, 0x0a, 0x09, 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x12, + 0x6f, 0x22, 0xe8, 0x03, 0x0a, 0x09, 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x12, 0x2e, 0x0a, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, @@ -1248,172 +1382,190 @@ var file_conf_conf_proto_rawDesc = []byte{ 0x72, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x41, 0x6c, 0x61, 0x72, 0x6d, 0x52, 0x05, 0x61, 0x6c, 0x61, 0x72, 0x6d, 0x12, 0x28, 0x0a, 0x04, 0x63, 0x72, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x63, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x43, 0x72, 0x6f, 0x6e, 0x52, 0x04, 0x63, 0x72, 0x6f, 0x6e, 0x22, - 0xff, 0x01, 0x0a, 0x06, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x2f, 0x0a, 0x04, 0x68, 0x74, - 0x74, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x76, 0x6f, 0x75, 0x63, 0x68, - 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x2e, 0x48, 0x54, 0x54, 0x50, 0x52, 0x04, 0x68, 0x74, 0x74, 0x70, 0x1a, 0xc3, 0x01, 0x0a, 0x04, - 0x48, 0x54, 0x54, 0x50, 0x12, 0x18, 0x0a, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x12, 0x12, - 0x0a, 0x04, 0x61, 0x64, 0x64, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x61, 0x64, - 0x64, 0x72, 0x12, 0x33, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, - 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x69, 0x73, 0x4f, 0x70, 0x65, - 0x6e, 0x53, 0x77, 0x61, 0x67, 0x67, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, - 0x69, 0x73, 0x4f, 0x70, 0x65, 0x6e, 0x53, 0x77, 0x61, 0x67, 0x67, 0x65, 0x72, 0x12, 0x32, 0x0a, - 0x14, 0x69, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x65, 0x71, 0x48, 0x65, - 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x69, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x65, 0x71, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, - 0x73, 0x22, 0x94, 0x05, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x12, 0x2d, 0x0a, 0x02, 0x64, 0x62, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, - 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x61, 0x74, - 0x61, 0x62, 0x61, 0x73, 0x65, 0x52, 0x02, 0x64, 0x62, 0x12, 0x30, 0x0a, 0x05, 0x72, 0x65, 0x64, - 0x69, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x76, 0x6f, 0x75, 0x63, 0x68, - 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x2e, 0x52, - 0x65, 0x64, 0x69, 0x73, 0x52, 0x05, 0x72, 0x65, 0x64, 0x69, 0x73, 0x1a, 0xc5, 0x01, 0x0a, 0x08, - 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x72, 0x69, 0x76, - 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, - 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x61, 0x78, 0x49, - 0x64, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x49, 0x64, - 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x61, 0x78, 0x4f, 0x70, 0x65, 0x6e, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x05, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x4f, 0x70, 0x65, 0x6e, 0x12, 0x3b, 0x0a, 0x0b, - 0x6d, 0x61, 0x78, 0x4c, 0x69, 0x66, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x6d, 0x61, - 0x78, 0x4c, 0x69, 0x66, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x69, 0x73, 0x44, - 0x65, 0x62, 0x75, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x69, 0x73, 0x44, 0x65, - 0x62, 0x75, 0x67, 0x1a, 0xe2, 0x02, 0x0a, 0x05, 0x52, 0x65, 0x64, 0x69, 0x73, 0x12, 0x18, 0x0a, - 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, - 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x64, 0x64, 0x72, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x61, 0x64, 0x64, 0x72, 0x12, 0x3b, 0x0a, 0x0b, 0x72, - 0x65, 0x61, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, + 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x43, 0x72, 0x6f, 0x6e, 0x52, 0x04, 0x63, 0x72, 0x6f, 0x6e, 0x12, + 0x2b, 0x0a, 0x05, 0x72, 0x64, 0x73, 0x4d, 0x51, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, + 0x2e, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, + 0x52, 0x64, 0x73, 0x4d, 0x51, 0x52, 0x05, 0x72, 0x64, 0x73, 0x4d, 0x51, 0x22, 0xff, 0x01, 0x0a, + 0x06, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x2f, 0x0a, 0x04, 0x68, 0x74, 0x74, 0x70, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x2e, + 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x48, 0x54, + 0x54, 0x50, 0x52, 0x04, 0x68, 0x74, 0x74, 0x70, 0x1a, 0xc3, 0x01, 0x0a, 0x04, 0x48, 0x54, 0x54, + 0x50, 0x12, 0x18, 0x0a, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x61, + 0x64, 0x64, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x61, 0x64, 0x64, 0x72, 0x12, + 0x33, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x72, 0x65, 0x61, - 0x64, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x3d, 0x0a, 0x0c, 0x77, 0x72, 0x69, 0x74, - 0x65, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, + 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x74, 0x69, 0x6d, + 0x65, 0x6f, 0x75, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x69, 0x73, 0x4f, 0x70, 0x65, 0x6e, 0x53, 0x77, + 0x61, 0x67, 0x67, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x69, 0x73, 0x4f, + 0x70, 0x65, 0x6e, 0x53, 0x77, 0x61, 0x67, 0x67, 0x65, 0x72, 0x12, 0x32, 0x0a, 0x14, 0x69, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x65, 0x71, 0x48, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x69, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x65, 0x71, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x22, 0x94, + 0x05, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x12, 0x2d, 0x0a, 0x02, 0x64, 0x62, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x63, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, + 0x73, 0x65, 0x52, 0x02, 0x64, 0x62, 0x12, 0x30, 0x0a, 0x05, 0x72, 0x65, 0x64, 0x69, 0x73, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x2e, + 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x64, 0x69, + 0x73, 0x52, 0x05, 0x72, 0x65, 0x64, 0x69, 0x73, 0x1a, 0xc5, 0x01, 0x0a, 0x08, 0x44, 0x61, 0x74, + 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x12, 0x16, 0x0a, + 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x61, 0x78, 0x49, 0x64, 0x6c, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x49, 0x64, 0x6c, 0x65, 0x12, + 0x18, 0x0a, 0x07, 0x6d, 0x61, 0x78, 0x4f, 0x70, 0x65, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x07, 0x6d, 0x61, 0x78, 0x4f, 0x70, 0x65, 0x6e, 0x12, 0x3b, 0x0a, 0x0b, 0x6d, 0x61, 0x78, + 0x4c, 0x69, 0x66, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x77, 0x72, 0x69, 0x74, 0x65, - 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, - 0x6f, 0x72, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, - 0x6f, 0x72, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6f, 0x6f, 0x6c, 0x53, 0x69, 0x7a, 0x65, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x6f, 0x6f, 0x6c, 0x53, 0x69, 0x7a, 0x65, 0x12, - 0x22, 0x0a, 0x0c, 0x6d, 0x69, 0x6e, 0x49, 0x64, 0x6c, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x73, 0x18, - 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x6d, 0x69, 0x6e, 0x49, 0x64, 0x6c, 0x65, 0x43, 0x6f, - 0x6e, 0x6e, 0x73, 0x12, 0x43, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x6e, 0x4d, 0x61, 0x78, 0x49, 0x64, - 0x6c, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, - 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x6e, 0x4d, 0x61, 0x78, - 0x49, 0x64, 0x6c, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x64, 0x62, 0x18, 0x09, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x64, 0x62, 0x22, 0x97, 0x02, 0x0a, 0x08, 0x52, 0x6f, 0x63, - 0x6b, 0x65, 0x74, 0x4d, 0x51, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x61, 0x64, 0x64, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x4b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x4b, 0x65, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x65, 0x63, 0x72, 0x65, - 0x74, 0x4b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, 0x63, 0x72, - 0x65, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x54, - 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x65, 0x63, 0x72, - 0x65, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x42, 0x0a, 0x08, 0x65, 0x76, 0x65, 0x6e, 0x74, - 0x4d, 0x61, 0x70, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x76, 0x6f, 0x75, 0x63, - 0x68, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x52, 0x6f, 0x63, 0x6b, 0x65, - 0x74, 0x4d, 0x51, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x52, 0x08, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x61, 0x70, 0x1a, 0x55, 0x0a, 0x0d, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, - 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2e, - 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, - 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x61, 0x70, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, - 0x38, 0x01, 0x22, 0x88, 0x01, 0x0a, 0x08, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x61, 0x70, 0x12, - 0x14, 0x0a, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x67, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x12, 0x28, 0x0a, 0x0f, 0x70, - 0x65, 0x72, 0x43, 0x6f, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x65, 0x43, 0x6e, 0x74, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x70, 0x65, 0x72, 0x43, 0x6f, 0x72, 0x6f, 0x75, 0x74, 0x69, - 0x6e, 0x65, 0x43, 0x6e, 0x74, 0x12, 0x26, 0x0a, 0x0e, 0x69, 0x73, 0x4f, 0x70, 0x65, 0x6e, 0x43, - 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x69, - 0x73, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x22, 0x92, 0x01, - 0x0a, 0x06, 0x57, 0x65, 0x63, 0x68, 0x61, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x63, 0x68, 0x49, - 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x63, 0x68, 0x49, 0x44, 0x12, 0x3e, - 0x0a, 0x1a, 0x6d, 0x63, 0x68, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, - 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x1a, 0x6d, 0x63, 0x68, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, - 0x74, 0x65, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x32, - 0x0a, 0x14, 0x77, 0x65, 0x63, 0x68, 0x61, 0x74, 0x50, 0x61, 0x79, 0x50, 0x75, 0x62, 0x6c, 0x69, - 0x63, 0x4b, 0x65, 0x79, 0x49, 0x44, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x77, 0x65, - 0x63, 0x68, 0x61, 0x74, 0x50, 0x61, 0x79, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, - 0x49, 0x44, 0x22, 0xd7, 0x02, 0x0a, 0x03, 0x43, 0x6d, 0x62, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, - 0x61, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x61, 0x69, 0x64, 0x12, 0x16, - 0x0a, 0x06, 0x73, 0x6d, 0x32, 0x50, 0x72, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, - 0x73, 0x6d, 0x32, 0x50, 0x72, 0x6b, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6d, 0x32, 0x50, 0x75, 0x6b, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6d, 0x32, 0x50, 0x75, 0x6b, 0x12, 0x1c, - 0x0a, 0x09, 0x63, 0x6d, 0x62, 0x53, 0x6d, 0x32, 0x50, 0x69, 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x09, 0x63, 0x6d, 0x62, 0x53, 0x6d, 0x32, 0x50, 0x69, 0x6b, 0x12, 0x1c, 0x0a, 0x09, - 0x63, 0x6d, 0x62, 0x53, 0x6d, 0x32, 0x50, 0x75, 0x6b, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x09, 0x63, 0x6d, 0x62, 0x53, 0x6d, 0x32, 0x50, 0x75, 0x6b, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, - 0x79, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, - 0x79, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6d, 0x62, 0x4b, 0x65, 0x79, - 0x41, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6d, 0x62, - 0x4b, 0x65, 0x79, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x6f, 0x72, 0x67, 0x4e, - 0x6f, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x72, 0x67, 0x4e, 0x6f, 0x12, 0x1c, - 0x0a, 0x09, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x55, 0x72, 0x6c, 0x18, 0x0a, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x09, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x55, 0x72, 0x6c, 0x12, 0x28, 0x0a, 0x0f, - 0x6e, 0x6f, 0x74, 0x69, 0x63, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x44, 0x61, 0x79, 0x73, 0x18, - 0x0b, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x6e, 0x6f, 0x74, 0x69, 0x63, 0x65, 0x53, 0x74, 0x61, - 0x72, 0x74, 0x44, 0x61, 0x79, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x6e, 0x6f, 0x74, 0x69, 0x63, 0x65, - 0x45, 0x6e, 0x64, 0x44, 0x61, 0x79, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x6e, - 0x6f, 0x74, 0x69, 0x63, 0x65, 0x45, 0x6e, 0x64, 0x44, 0x61, 0x79, 0x73, 0x22, 0xc6, 0x02, 0x0a, - 0x0e, 0x57, 0x65, 0x63, 0x68, 0x61, 0x74, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x4d, 0x51, 0x12, - 0x20, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4b, 0x65, 0x79, 0x49, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4b, 0x65, 0x79, 0x49, - 0x64, 0x12, 0x28, 0x0a, 0x0f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4b, 0x65, 0x79, 0x53, 0x65, - 0x63, 0x72, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x61, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x4b, 0x65, 0x79, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x65, - 0x6e, 0x64, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, - 0x6e, 0x64, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x67, 0x69, 0x6f, - 0x6e, 0x49, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x67, 0x69, 0x6f, - 0x6e, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, - 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, - 0x65, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, - 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x67, - 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x67, 0x72, - 0x6f, 0x75, 0x70, 0x49, 0x64, 0x12, 0x26, 0x0a, 0x0e, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, - 0x72, 0x54, 0x61, 0x67, 0x55, 0x72, 0x6c, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x72, - 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x54, 0x61, 0x67, 0x55, 0x72, 0x6c, 0x12, 0x26, 0x0a, - 0x0e, 0x69, 0x73, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x18, - 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x69, 0x73, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x6f, 0x6e, - 0x73, 0x75, 0x6d, 0x65, 0x72, 0x22, 0x73, 0x0a, 0x05, 0x41, 0x6c, 0x61, 0x72, 0x6d, 0x12, 0x1e, - 0x0a, 0x0a, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x55, 0x52, 0x4c, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0a, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x55, 0x52, 0x4c, 0x12, 0x16, - 0x0a, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, - 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x74, 0x41, 0x6c, 0x6c, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x61, 0x74, 0x41, 0x6c, 0x6c, 0x12, 0x1c, 0x0a, 0x09, - 0x61, 0x74, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x09, 0x61, 0x74, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x73, 0x22, 0x84, 0x02, 0x0a, 0x04, 0x43, - 0x72, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x69, 0x73, 0x4f, 0x70, 0x65, 0x6e, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x06, 0x69, 0x73, 0x4f, 0x70, 0x65, 0x6e, 0x12, 0x44, 0x0a, 0x0a, 0x63, - 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x4d, 0x61, 0x70, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x24, 0x2e, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x2e, 0x43, 0x72, 0x6f, 0x6e, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x4d, 0x61, 0x70, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x4d, 0x61, - 0x70, 0x1a, 0x3e, 0x0a, 0x0a, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x4d, 0x61, 0x70, 0x12, - 0x16, 0x0a, 0x06, 0x69, 0x73, 0x4f, 0x70, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x06, 0x69, 0x73, 0x4f, 0x70, 0x65, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, - 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, - 0x64, 0x1a, 0x5e, 0x0a, 0x0f, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x4d, 0x61, 0x70, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x35, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x2e, - 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x43, 0x72, 0x6f, 0x6e, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, - 0x61, 0x6e, 0x64, 0x4d, 0x61, 0x70, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, - 0x01, 0x22, 0x3a, 0x0a, 0x04, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x62, 0x75, 0x73, - 0x69, 0x6e, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x62, 0x75, 0x73, - 0x69, 0x6e, 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x42, 0x17, 0x5a, - 0x15, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x2f, 0x63, 0x70, 0x6e, 0x2f, 0x63, 0x6f, 0x6e, - 0x66, 0x3b, 0x63, 0x6f, 0x6e, 0x66, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x6d, 0x61, 0x78, 0x4c, 0x69, + 0x66, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x69, 0x73, 0x44, 0x65, 0x62, 0x75, + 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x69, 0x73, 0x44, 0x65, 0x62, 0x75, 0x67, + 0x1a, 0xe2, 0x02, 0x0a, 0x05, 0x52, 0x65, 0x64, 0x69, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6e, 0x65, + 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6e, 0x65, 0x74, + 0x77, 0x6f, 0x72, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x64, 0x64, 0x72, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x61, 0x64, 0x64, 0x72, 0x12, 0x3b, 0x0a, 0x0b, 0x72, 0x65, 0x61, 0x64, + 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x72, 0x65, 0x61, 0x64, 0x54, 0x69, + 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x3d, 0x0a, 0x0c, 0x77, 0x72, 0x69, 0x74, 0x65, 0x54, 0x69, + 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x77, 0x72, 0x69, 0x74, 0x65, 0x54, 0x69, 0x6d, + 0x65, 0x6f, 0x75, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, + 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6f, 0x6f, 0x6c, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x08, 0x70, 0x6f, 0x6f, 0x6c, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x22, 0x0a, 0x0c, + 0x6d, 0x69, 0x6e, 0x49, 0x64, 0x6c, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x73, 0x18, 0x07, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x0c, 0x6d, 0x69, 0x6e, 0x49, 0x64, 0x6c, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x73, + 0x12, 0x43, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x6e, 0x4d, 0x61, 0x78, 0x49, 0x64, 0x6c, 0x65, 0x54, + 0x69, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x6e, 0x4d, 0x61, 0x78, 0x49, 0x64, 0x6c, + 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x64, 0x62, 0x18, 0x09, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x02, 0x64, 0x62, 0x22, 0x97, 0x02, 0x0a, 0x08, 0x52, 0x6f, 0x63, 0x6b, 0x65, 0x74, + 0x4d, 0x51, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x61, 0x64, 0x64, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x4b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x4b, 0x65, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x4b, 0x65, + 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x4b, + 0x65, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x54, 0x6f, 0x6b, 0x65, + 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x54, + 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x42, 0x0a, 0x08, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x61, 0x70, + 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, + 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x52, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x4d, 0x51, + 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, + 0x65, 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x61, 0x70, 0x1a, 0x55, 0x0a, 0x0d, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2e, 0x0a, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x76, 0x6f, 0x75, + 0x63, 0x68, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x4d, 0x61, 0x70, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, + 0x88, 0x01, 0x0a, 0x08, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x61, 0x70, 0x12, 0x14, 0x0a, 0x05, + 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x67, 0x72, 0x6f, + 0x75, 0x70, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x12, 0x28, 0x0a, 0x0f, 0x70, 0x65, 0x72, 0x43, + 0x6f, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x65, 0x43, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x05, 0x52, 0x0f, 0x70, 0x65, 0x72, 0x43, 0x6f, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x65, 0x43, + 0x6e, 0x74, 0x12, 0x26, 0x0a, 0x0e, 0x69, 0x73, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x6f, 0x6e, 0x73, + 0x75, 0x6d, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x69, 0x73, 0x4f, 0x70, + 0x65, 0x6e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x22, 0x92, 0x01, 0x0a, 0x06, 0x57, + 0x65, 0x63, 0x68, 0x61, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x63, 0x68, 0x49, 0x44, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x63, 0x68, 0x49, 0x44, 0x12, 0x3e, 0x0a, 0x1a, 0x6d, + 0x63, 0x68, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x53, 0x65, 0x72, + 0x69, 0x61, 0x6c, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x1a, 0x6d, 0x63, 0x68, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x53, + 0x65, 0x72, 0x69, 0x61, 0x6c, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x32, 0x0a, 0x14, 0x77, + 0x65, 0x63, 0x68, 0x61, 0x74, 0x50, 0x61, 0x79, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, + 0x79, 0x49, 0x44, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x77, 0x65, 0x63, 0x68, 0x61, + 0x74, 0x50, 0x61, 0x79, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x49, 0x44, 0x22, + 0xd7, 0x02, 0x0a, 0x03, 0x43, 0x6d, 0x62, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x69, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x61, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, + 0x6d, 0x32, 0x50, 0x72, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6d, 0x32, + 0x50, 0x72, 0x6b, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6d, 0x32, 0x50, 0x75, 0x6b, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6d, 0x32, 0x50, 0x75, 0x6b, 0x12, 0x1c, 0x0a, 0x09, 0x63, + 0x6d, 0x62, 0x53, 0x6d, 0x32, 0x50, 0x69, 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x63, 0x6d, 0x62, 0x53, 0x6d, 0x32, 0x50, 0x69, 0x6b, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6d, 0x62, + 0x53, 0x6d, 0x32, 0x50, 0x75, 0x6b, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6d, + 0x62, 0x53, 0x6d, 0x32, 0x50, 0x75, 0x6b, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x41, 0x6c, + 0x69, 0x61, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x41, 0x6c, + 0x69, 0x61, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6d, 0x62, 0x4b, 0x65, 0x79, 0x41, 0x6c, 0x69, + 0x61, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6d, 0x62, 0x4b, 0x65, 0x79, + 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x6f, 0x72, 0x67, 0x4e, 0x6f, 0x18, 0x09, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x72, 0x67, 0x4e, 0x6f, 0x12, 0x1c, 0x0a, 0x09, 0x6e, + 0x6f, 0x74, 0x69, 0x66, 0x79, 0x55, 0x72, 0x6c, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x55, 0x72, 0x6c, 0x12, 0x28, 0x0a, 0x0f, 0x6e, 0x6f, 0x74, + 0x69, 0x63, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x44, 0x61, 0x79, 0x73, 0x18, 0x0b, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x0f, 0x6e, 0x6f, 0x74, 0x69, 0x63, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x44, + 0x61, 0x79, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x6e, 0x6f, 0x74, 0x69, 0x63, 0x65, 0x45, 0x6e, 0x64, + 0x44, 0x61, 0x79, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x6e, 0x6f, 0x74, 0x69, + 0x63, 0x65, 0x45, 0x6e, 0x64, 0x44, 0x61, 0x79, 0x73, 0x22, 0xc6, 0x02, 0x0a, 0x0e, 0x57, 0x65, + 0x63, 0x68, 0x61, 0x74, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x4d, 0x51, 0x12, 0x20, 0x0a, 0x0b, + 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4b, 0x65, 0x79, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4b, 0x65, 0x79, 0x49, 0x64, 0x12, 0x28, + 0x0a, 0x0f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4b, 0x65, 0x79, 0x53, 0x65, 0x63, 0x72, 0x65, + 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4b, + 0x65, 0x79, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x50, + 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x6e, 0x64, 0x50, + 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x49, 0x64, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x49, 0x64, + 0x12, 0x1e, 0x0a, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, + 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x67, 0x72, 0x6f, 0x75, + 0x70, 0x49, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x67, 0x72, 0x6f, 0x75, 0x70, + 0x49, 0x64, 0x12, 0x26, 0x0a, 0x0e, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x54, 0x61, + 0x67, 0x55, 0x72, 0x6c, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x72, 0x65, 0x67, 0x69, + 0x73, 0x74, 0x65, 0x72, 0x54, 0x61, 0x67, 0x55, 0x72, 0x6c, 0x12, 0x26, 0x0a, 0x0e, 0x69, 0x73, + 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x18, 0x0b, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x0e, 0x69, 0x73, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, + 0x65, 0x72, 0x22, 0x73, 0x0a, 0x05, 0x41, 0x6c, 0x61, 0x72, 0x6d, 0x12, 0x1e, 0x0a, 0x0a, 0x77, + 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x55, 0x52, 0x4c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0a, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x55, 0x52, 0x4c, 0x12, 0x16, 0x0a, 0x06, 0x73, + 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x65, 0x63, + 0x72, 0x65, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x74, 0x41, 0x6c, 0x6c, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x05, 0x61, 0x74, 0x41, 0x6c, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x74, 0x4d, + 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x61, 0x74, + 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x73, 0x22, 0x84, 0x02, 0x0a, 0x04, 0x43, 0x72, 0x6f, 0x6e, + 0x12, 0x16, 0x0a, 0x06, 0x69, 0x73, 0x4f, 0x70, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x06, 0x69, 0x73, 0x4f, 0x70, 0x65, 0x6e, 0x12, 0x44, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, + 0x61, 0x6e, 0x64, 0x4d, 0x61, 0x70, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x76, + 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x43, 0x72, + 0x6f, 0x6e, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x52, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x4d, 0x61, 0x70, 0x1a, 0x3e, + 0x0a, 0x0a, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x4d, 0x61, 0x70, 0x12, 0x16, 0x0a, 0x06, + 0x69, 0x73, 0x4f, 0x70, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x69, 0x73, + 0x4f, 0x70, 0x65, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x1a, 0x5e, + 0x0a, 0x0f, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x6b, 0x65, 0x79, 0x12, 0x35, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x2e, 0x43, 0x72, 0x6f, 0x6e, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, + 0x4d, 0x61, 0x70, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xef, + 0x01, 0x0a, 0x05, 0x52, 0x64, 0x73, 0x4d, 0x51, 0x12, 0x3d, 0x0a, 0x0b, 0x77, 0x65, 0x63, 0x68, + 0x61, 0x74, 0x51, 0x75, 0x65, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, + 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x52, + 0x64, 0x73, 0x4d, 0x51, 0x2e, 0x51, 0x75, 0x65, 0x75, 0x65, 0x52, 0x0b, 0x77, 0x65, 0x63, 0x68, + 0x61, 0x74, 0x51, 0x75, 0x65, 0x72, 0x79, 0x1a, 0xa6, 0x01, 0x0a, 0x05, 0x51, 0x75, 0x65, 0x75, + 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x69, 0x73, 0x4f, 0x70, 0x65, 0x6e, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x69, 0x73, 0x4f, 0x70, 0x65, 0x6e, 0x12, 0x1a, 0x0a, + 0x08, 0x72, 0x65, 0x74, 0x72, 0x79, 0x4e, 0x75, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x08, 0x72, 0x65, 0x74, 0x72, 0x79, 0x4e, 0x75, 0x6d, 0x12, 0x1e, 0x0a, 0x0a, 0x6e, 0x75, 0x6d, + 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x6e, + 0x75, 0x6d, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x73, 0x12, 0x35, 0x0a, 0x08, 0x77, 0x61, 0x69, + 0x74, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x77, 0x61, 0x69, 0x74, 0x54, 0x69, 0x6d, 0x65, + 0x22, 0x3a, 0x0a, 0x04, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x62, 0x75, 0x73, 0x69, + 0x6e, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x62, 0x75, 0x73, 0x69, + 0x6e, 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x42, 0x17, 0x5a, 0x15, + 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x2f, 0x63, 0x70, 0x6e, 0x2f, 0x63, 0x6f, 0x6e, 0x66, + 0x3b, 0x63, 0x6f, 0x6e, 0x66, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1428,7 +1580,7 @@ func file_conf_conf_proto_rawDescGZIP() []byte { return file_conf_conf_proto_rawDescData } -var file_conf_conf_proto_msgTypes = make([]protoimpl.MessageInfo, 17) +var file_conf_conf_proto_msgTypes = make([]protoimpl.MessageInfo, 19) var file_conf_conf_proto_goTypes = []any{ (*Bootstrap)(nil), // 0: voucher.config.Bootstrap (*Server)(nil), // 1: voucher.config.Server @@ -1440,18 +1592,20 @@ var file_conf_conf_proto_goTypes = []any{ (*WechatNotifyMQ)(nil), // 7: voucher.config.WechatNotifyMQ (*Alarm)(nil), // 8: voucher.config.Alarm (*Cron)(nil), // 9: voucher.config.Cron - (*Logs)(nil), // 10: voucher.config.Logs - (*Server_HTTP)(nil), // 11: voucher.config.Server.HTTP - (*Data_Database)(nil), // 12: voucher.config.Data.Database - (*Data_Redis)(nil), // 13: voucher.config.Data.Redis - nil, // 14: voucher.config.RocketMQ.EventMapEntry - (*Cron_CommandMap)(nil), // 15: voucher.config.Cron.CommandMap - nil, // 16: voucher.config.Cron.CommandMapEntry - (*durationpb.Duration)(nil), // 17: google.protobuf.Duration + (*RdsMQ)(nil), // 10: voucher.config.RdsMQ + (*Logs)(nil), // 11: voucher.config.Logs + (*Server_HTTP)(nil), // 12: voucher.config.Server.HTTP + (*Data_Database)(nil), // 13: voucher.config.Data.Database + (*Data_Redis)(nil), // 14: voucher.config.Data.Redis + nil, // 15: voucher.config.RocketMQ.EventMapEntry + (*Cron_CommandMap)(nil), // 16: voucher.config.Cron.CommandMap + nil, // 17: voucher.config.Cron.CommandMapEntry + (*RdsMQ_Queue)(nil), // 18: voucher.config.RdsMQ.Queue + (*durationpb.Duration)(nil), // 19: google.protobuf.Duration } var file_conf_conf_proto_depIdxs = []int32{ 1, // 0: voucher.config.Bootstrap.server:type_name -> voucher.config.Server - 10, // 1: voucher.config.Bootstrap.logs:type_name -> voucher.config.Logs + 11, // 1: voucher.config.Bootstrap.logs:type_name -> voucher.config.Logs 2, // 2: voucher.config.Bootstrap.data:type_name -> voucher.config.Data 3, // 3: voucher.config.Bootstrap.rocketMQ:type_name -> voucher.config.RocketMQ 5, // 4: voucher.config.Bootstrap.wechat:type_name -> voucher.config.Wechat @@ -1459,23 +1613,26 @@ var file_conf_conf_proto_depIdxs = []int32{ 7, // 6: voucher.config.Bootstrap.wechatNotifyMQ:type_name -> voucher.config.WechatNotifyMQ 8, // 7: voucher.config.Bootstrap.alarm:type_name -> voucher.config.Alarm 9, // 8: voucher.config.Bootstrap.cron:type_name -> voucher.config.Cron - 11, // 9: voucher.config.Server.http:type_name -> voucher.config.Server.HTTP - 12, // 10: voucher.config.Data.db:type_name -> voucher.config.Data.Database - 13, // 11: voucher.config.Data.redis:type_name -> voucher.config.Data.Redis - 14, // 12: voucher.config.RocketMQ.eventMap:type_name -> voucher.config.RocketMQ.EventMapEntry - 16, // 13: voucher.config.Cron.commandMap:type_name -> voucher.config.Cron.CommandMapEntry - 17, // 14: voucher.config.Server.HTTP.timeout:type_name -> google.protobuf.Duration - 17, // 15: voucher.config.Data.Database.maxLifetime:type_name -> google.protobuf.Duration - 17, // 16: voucher.config.Data.Redis.readTimeout:type_name -> google.protobuf.Duration - 17, // 17: voucher.config.Data.Redis.writeTimeout:type_name -> google.protobuf.Duration - 17, // 18: voucher.config.Data.Redis.connMaxIdleTime:type_name -> google.protobuf.Duration - 4, // 19: voucher.config.RocketMQ.EventMapEntry.value:type_name -> voucher.config.EventMap - 15, // 20: voucher.config.Cron.CommandMapEntry.value:type_name -> voucher.config.Cron.CommandMap - 21, // [21:21] is the sub-list for method output_type - 21, // [21:21] is the sub-list for method input_type - 21, // [21:21] is the sub-list for extension type_name - 21, // [21:21] is the sub-list for extension extendee - 0, // [0:21] is the sub-list for field type_name + 10, // 9: voucher.config.Bootstrap.rdsMQ:type_name -> voucher.config.RdsMQ + 12, // 10: voucher.config.Server.http:type_name -> voucher.config.Server.HTTP + 13, // 11: voucher.config.Data.db:type_name -> voucher.config.Data.Database + 14, // 12: voucher.config.Data.redis:type_name -> voucher.config.Data.Redis + 15, // 13: voucher.config.RocketMQ.eventMap:type_name -> voucher.config.RocketMQ.EventMapEntry + 17, // 14: voucher.config.Cron.commandMap:type_name -> voucher.config.Cron.CommandMapEntry + 18, // 15: voucher.config.RdsMQ.wechatQuery:type_name -> voucher.config.RdsMQ.Queue + 19, // 16: voucher.config.Server.HTTP.timeout:type_name -> google.protobuf.Duration + 19, // 17: voucher.config.Data.Database.maxLifetime:type_name -> google.protobuf.Duration + 19, // 18: voucher.config.Data.Redis.readTimeout:type_name -> google.protobuf.Duration + 19, // 19: voucher.config.Data.Redis.writeTimeout:type_name -> google.protobuf.Duration + 19, // 20: voucher.config.Data.Redis.connMaxIdleTime:type_name -> google.protobuf.Duration + 4, // 21: voucher.config.RocketMQ.EventMapEntry.value:type_name -> voucher.config.EventMap + 16, // 22: voucher.config.Cron.CommandMapEntry.value:type_name -> voucher.config.Cron.CommandMap + 19, // 23: voucher.config.RdsMQ.Queue.waitTime:type_name -> google.protobuf.Duration + 24, // [24:24] is the sub-list for method output_type + 24, // [24:24] 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_conf_conf_proto_init() } @@ -1605,7 +1762,7 @@ func file_conf_conf_proto_init() { } } file_conf_conf_proto_msgTypes[10].Exporter = func(v any, i int) any { - switch v := v.(*Logs); i { + switch v := v.(*RdsMQ); i { case 0: return &v.state case 1: @@ -1617,7 +1774,7 @@ func file_conf_conf_proto_init() { } } file_conf_conf_proto_msgTypes[11].Exporter = func(v any, i int) any { - switch v := v.(*Server_HTTP); i { + switch v := v.(*Logs); i { case 0: return &v.state case 1: @@ -1629,7 +1786,7 @@ func file_conf_conf_proto_init() { } } file_conf_conf_proto_msgTypes[12].Exporter = func(v any, i int) any { - switch v := v.(*Data_Database); i { + switch v := v.(*Server_HTTP); i { case 0: return &v.state case 1: @@ -1641,6 +1798,18 @@ func file_conf_conf_proto_init() { } } file_conf_conf_proto_msgTypes[13].Exporter = func(v any, i int) any { + switch v := v.(*Data_Database); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_conf_conf_proto_msgTypes[14].Exporter = func(v any, i int) any { switch v := v.(*Data_Redis); i { case 0: return &v.state @@ -1652,7 +1821,7 @@ func file_conf_conf_proto_init() { return nil } } - file_conf_conf_proto_msgTypes[15].Exporter = func(v any, i int) any { + file_conf_conf_proto_msgTypes[16].Exporter = func(v any, i int) any { switch v := v.(*Cron_CommandMap); i { case 0: return &v.state @@ -1664,6 +1833,18 @@ func file_conf_conf_proto_init() { return nil } } + file_conf_conf_proto_msgTypes[18].Exporter = func(v any, i int) any { + switch v := v.(*RdsMQ_Queue); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -1671,7 +1852,7 @@ func file_conf_conf_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_conf_conf_proto_rawDesc, NumEnums: 0, - NumMessages: 17, + NumMessages: 19, NumExtensions: 0, NumServices: 0, }, diff --git a/internal/conf/conf.proto b/internal/conf/conf.proto index 707713b..b548e46 100644 --- a/internal/conf/conf.proto +++ b/internal/conf/conf.proto @@ -15,6 +15,7 @@ message Bootstrap { WechatNotifyMQ wechatNotifyMQ = 7; Alarm alarm = 8; Cron cron = 9; + RdsMQ rdsMQ = 10; } message Server { @@ -118,6 +119,17 @@ message Cron { map commandMap = 2; } +message RdsMQ { + message Queue { + string name = 1; + bool isOpen = 2; + uint32 retryNum = 3; + uint32 numWorkers = 4; + google.protobuf.Duration waitTime = 5; + } + Queue wechatQuery = 1; +} + message Logs { string business = 1; string access = 2; diff --git a/internal/data/repoimpl/order.go b/internal/data/repoimpl/order.go index d7780b0..a2f4c2f 100644 --- a/internal/data/repoimpl/order.go +++ b/internal/data/repoimpl/order.go @@ -30,6 +30,25 @@ func (p *OrderRepoImpl) DB(ctx context.Context) *gorm.DB { return p.db.DB(ctx).Model(model.Order{}) } +func (p *OrderRepoImpl) FinByStockIdInBatches(ctx context.Context, batchNo string, fun func(ctx context.Context, rows []*bo.OrderBo) error) error { + + var results = make([]*model.Order, 0) + + result := p.DB(ctx). + Where("batch_no = ?", batchNo). + Where("status = ?", vo.OrderStatusSuccess.GetValue()). + Limit(20). + FindInBatches(&results, 10, func(tx *gorm.DB, batch int) error { + return fun(ctx, p.ToBos(results)) + }) + + if result.Error != nil { + return result.Error + } + + return nil +} + func (p *OrderRepoImpl) FindIngInBatches(ctx context.Context, fun func(ctx context.Context, rows []*bo.OrderBo) error) error { var results = make([]*model.Order, 0) diff --git a/internal/pkg/rdsmq/logger.go b/internal/pkg/rdsmq/logger.go new file mode 100644 index 0000000..f50ba65 --- /dev/null +++ b/internal/pkg/rdsmq/logger.go @@ -0,0 +1,15 @@ +package rdsmq + +type Logger interface { + // Debugf logs a formatted debugging message. + Debugf(format string, args ...interface{}) + + // Infof logs a formatted informational message. + Infof(format string, args ...interface{}) + + // Warnf logs a formatted warning message. + Warnf(format string, args ...interface{}) + + // Errorf logs a formatted error message. + Errorf(format string, args ...interface{}) +} diff --git a/internal/pkg/rdsmq/manager.go b/internal/pkg/rdsmq/manager.go new file mode 100644 index 0000000..517a571 --- /dev/null +++ b/internal/pkg/rdsmq/manager.go @@ -0,0 +1,47 @@ +package rdsmq + +import ( + "context" + "fmt" + "sync" +) + +// ConsumerManager 消费者管理器 +type ConsumerManager struct { + ConsumerConfigs []*ConsumeConfig +} + +func NewConsumerManager() *ConsumerManager { + return &ConsumerManager{} +} + +func (r *ConsumerManager) Add(config *ConsumeConfig) { + r.ConsumerConfigs = append(r.ConsumerConfigs, config) +} + +func (r *ConsumerManager) Start(ctx context.Context) { + var wg sync.WaitGroup + for _, c := range r.ConsumerConfigs { + if _, err := c.Rdb.Ping(ctx).Result(); err != nil { + panic(fmt.Sprintf("Redis connection failed: %v", err)) + } + + wg.Add(1) + go func(co *ConsumeConfig) { + defer func() { + wg.Done() + if err := recover(); err != nil { + fmt.Printf("panic", err) + } + }() + co.Start(ctx) + }(c) + } + wg.Wait() +} + +func (r *ConsumerManager) Stop(ctx context.Context) { + for _, c := range r.ConsumerConfigs { + c.Stop(ctx) + } +} diff --git a/internal/pkg/rdsmq/rdsmq.go b/internal/pkg/rdsmq/rdsmq.go new file mode 100644 index 0000000..e1ff23f --- /dev/null +++ b/internal/pkg/rdsmq/rdsmq.go @@ -0,0 +1,156 @@ +package rdsmq + +import ( + "context" + "fmt" + "github.com/redis/go-redis/v9" + "sync" + "time" +) + +type ConsumeConfig struct { + // Redis + Rdb *redis.Client + // 队列名称 + QueueName string + // 限制启用的协程数量 + NumWorkers uint32 + // 处理完成后等待时间 + WaitTime time.Duration + // 重试次数 + RetryNum uint32 + // 消费函数 + Fn func(context.Context, string) error + // 日志 + Logger Logger + // 协程控制 + numWorkersChan chan struct{} +} + +func (r *ConsumeConfig) init(_ context.Context) { + if r.RetryNum > 5 { + panic("RetryNum must be less than 5") + } + + if r.NumWorkers == 0 { + r.NumWorkers = 10 + } + + r.numWorkersChan = make(chan struct{}, r.NumWorkers) +} + +func (r *ConsumeConfig) Start(ctx context.Context) { + fmt.Printf("RdsMQ Starting to dequeue from [%s]", r.QueueName) + + r.init(ctx) + defer r.close(ctx) + + var wg sync.WaitGroup + for { + // 使用 BLPop 获取消息 + results, err := r.Rdb.BLPop(ctx, 0, r.QueueName).Result() + if err != nil { + r.Logger.Errorf("BLPop on %s Failed to get message: %v", r.QueueName, err) + time.Sleep(time.Second * 10) // 等待一段时间 + continue + } + + // 处理消息 + if len(results) < 2 { + panic(fmt.Sprintf("Invalid result length from BLPop on [%s]: %v", r.QueueName, results)) + } + + key := results[0] // 队列名称 + value := results[1] // 消息内容 + + wg.Add(1) + go func(key, value string) { + + defer func() { + wg.Done() + if err := recover(); err != nil { + r.Logger.Errorf("rds panic [%v]", err) + } + }() + + r.numWorkersChan <- struct{}{} // 获取信号量 + defer func() { <-r.numWorkersChan }() // 释放信号量 + + // 处理消息的业务逻辑 + r.consumer(ctx, key, value) + }(key, value) + + if r.WaitTime > 0 { + // 可选:合理设置等待时间 + time.Sleep(r.WaitTime) // 等待一段时间 + } + } + wg.Wait() +} + +func (r *ConsumeConfig) consumer(ctx context.Context, queueName string, value string) { + if err := r.Fn(ctx, value); err == nil { + r.Logger.Errorf("BLPop on %s Failed to process message [%s] after retry %d times, err[%v]\n", queueName, value, r.RetryNum, err) + return + } + + if r.RetryNum > 0 { + r.retry(ctx, queueName, value) + } +} + +func (r *ConsumeConfig) retry(ctx context.Context, queueName string, value string) { + retryNum := uint32(0) + retryInterval := 5 * time.Second // 初始重试间隔 + + // 创建一个定时器,定期尝试处理消息 + lockTicker := time.NewTicker(retryInterval) + defer lockTicker.Stop() + + for { + select { + case <-lockTicker.C: + if retryNum < r.RetryNum { + + err := r.Fn(ctx, value) + if err == nil { + return // 成功处理消息,退出 + } + + // 错误分类处理 + if isRecoverableError(err) { + r.Logger.Errorf("BLPop on %s Failed to process message [%s] after retry %d times, err[%v]\n", queueName, value, retryNum, err) + retryNum++ + // 动态调整重试间隔 + retryInterval = time.Duration(float64(retryInterval) * 1.5) // 每次增加 50% + lockTicker.Reset(retryInterval) // 重置定时器 + } else { + r.Logger.Errorf("BLPop on %s Non-recoverable error for message [%s]: %v\n", queueName, value, err) + return // 立即退出 + } + } else { + r.Logger.Warnf("BLPop on %s Max retries reached for message [%s]\n", queueName, value) + return // 达到最大重试次数,退出 + } + case <-ctx.Done(): + r.Logger.Warnf("BLPop on %s push consumer close tick. [%s]\n", queueName, value) + return + } + } +} + +// 示例函数,判断错误是否可恢复 +func isRecoverableError(_ error) bool { + // 根据具体情况实现错误分类逻辑 + return true // 假设所有错误都可恢复,实际情况中应进行详细判断 +} + +func (r *ConsumeConfig) close(_ context.Context) { + if r.numWorkersChan != nil { + close(r.numWorkersChan) + } +} + +func (r *ConsumeConfig) Stop(ctx context.Context) { + r.close(ctx) +} diff --git a/internal/server/http.go b/internal/server/http.go index f573347..636e471 100644 --- a/internal/server/http.go +++ b/internal/server/http.go @@ -39,6 +39,7 @@ func NewHTTPServer( srv.Route("/voucher/").GET("notifyRetry/{id}", cmb.NotifyRetry) srv.Route("/voucher/").GET("queryOrder/{order_no}", cmb.QueryOrder) srv.Route("/voucher/").GET("registerTag/{product_no}", cmb.RegisterTag) + srv.Route("/voucher/").GET("pushWechatQuery/{product_no}", cmb.PushWechatQuery) v1.RegisterCmbHTTPServer(srv, cmb) diff --git a/internal/server/provider_set.go b/internal/server/provider_set.go index 13460f0..00d6438 100644 --- a/internal/server/provider_set.go +++ b/internal/server/provider_set.go @@ -10,4 +10,5 @@ var ProviderSetServer = wire.NewSet( NewConsumer, NewWechatNotifyConsumer, NewCronServer, + NewRdbConsumer, ) diff --git a/internal/server/rds_consume.go b/internal/server/rds_consume.go new file mode 100644 index 0000000..e5fa79c --- /dev/null +++ b/internal/server/rds_consume.go @@ -0,0 +1,46 @@ +package server + +import ( + "context" + "fmt" + "github.com/go-kratos/kratos/v2/log" + "github.com/go-kratos/kratos/v2/transport" + "voucher/internal/conf" + "voucher/internal/pkg/rdsmq" + "voucher/internal/service" +) + +var _ transport.Server = (*RdbConsumer)(nil) + +type RdbConsumer struct { + hLog *log.Helper + conf *conf.Bootstrap + manager *rdsmq.ConsumerManager + voucherService *service.VoucherService +} + +func NewRdbConsumer( + hLog *log.Helper, + conf *conf.Bootstrap, + voucherService *service.VoucherService, +) *RdbConsumer { + manager := rdsmq.NewConsumerManager() + + if cf := voucherService.GetConfig(); cf != nil { + manager.Add(cf) + } + + return &RdbConsumer{hLog: hLog, conf: conf, manager: manager} +} + +func (c *RdbConsumer) Start(ctx context.Context) error { + c.manager.Start(ctx) + return nil +} + +func (c *RdbConsumer) Stop(ctx context.Context) error { + fmt.Println("关闭 RdbConsumer 中...") + c.manager.Stop(ctx) + fmt.Println("关闭 RdbConsumer 完成...") + return nil +} diff --git a/internal/service/cmb.go b/internal/service/cmb.go index 6ceabdf..2d2d260 100644 --- a/internal/service/cmb.go +++ b/internal/service/cmb.go @@ -112,3 +112,20 @@ func (this *CmbService) RegisterTag(ctx http.Context) error { "data": productNo, }) } + +func (this *CmbService) PushWechatQuery(ctx http.Context) error { + + productNo := ctx.Vars().Get("product_no") + if productNo == "" { + return fmt.Errorf("product_no is empty") + } + + err := this.VoucherBiz.PushWechatQuery(ctx, productNo) + if err != nil { + return err + } + + return ctx.JSON(http2.StatusOK, map[string]interface{}{ + "data": productNo, + }) +} diff --git a/internal/service/voucher.go b/internal/service/voucher.go index 82dbbbb..c663d55 100644 --- a/internal/service/voucher.go +++ b/internal/service/voucher.go @@ -11,6 +11,7 @@ import ( "voucher/internal/biz" "voucher/internal/biz/bo" "voucher/internal/conf" + "voucher/internal/data" "voucher/internal/pkg/mq" ) @@ -18,17 +19,23 @@ type VoucherService struct { bc *conf.Bootstrap cron *cron.Cron VoucherBiz *biz.VoucherBiz + rdb *data.Rdb + logHelper *log.Helper } func NewVoucherService( bc *conf.Bootstrap, cron *cron.Cron, VoucherBiz *biz.VoucherBiz, + rdb *data.Rdb, + logHelper *log.Helper, ) *VoucherService { return &VoucherService{ bc: bc, cron: cron, VoucherBiz: VoucherBiz, + rdb: rdb, + logHelper: logHelper, } } diff --git a/internal/service/wechat_query.go b/internal/service/wechat_query.go new file mode 100644 index 0000000..96f3209 --- /dev/null +++ b/internal/service/wechat_query.go @@ -0,0 +1,50 @@ +package service + +import ( + "context" + "fmt" + "github.com/go-kratos/kratos/v2/log" + "time" + "voucher/internal/pkg/lock" + "voucher/internal/pkg/rdsmq" +) + +func (s *VoucherService) GetConfig() *rdsmq.ConsumeConfig { + + queue := s.bc.RdsMQ.GetWechatQuery() + if queue == nil { + return nil + } + + if !queue.GetIsOpen() { + log.Warn(fmt.Sprintf("[%s]RdsMQ is not open", queue.Name)) + return nil + } + + return &rdsmq.ConsumeConfig{ + Rdb: s.rdb.Rdb, + QueueName: queue.Name, + NumWorkers: queue.NumWorkers, + WaitTime: queue.GetWaitTime().AsDuration(), + RetryNum: queue.RetryNum, + Fn: s.Handle, + Logger: s.logHelper, + } +} + +func (s *VoucherService) Handle(ctx context.Context, msg string) error { + + if msg == "" { + s.logHelper.Errorf("RdsMQ keySend error: batchNo is empty") + return nil + } + + return lock.NewMutex(s.rdb.Rdb, time.Hour*10).Lock(ctx, fmt.Sprintf("cmb_wechant_query_%s", msg), func(ctx context.Context) error { + + if err := s.VoucherBiz.WechatQuery(ctx, msg); err != nil { + s.logHelper.Error(err) + } + + return nil + }) +} From c89fb9f27a5c1ac29c5a2852223a4489565517f8 Mon Sep 17 00:00:00 2001 From: ziming Date: Wed, 4 Jun 2025 11:54:52 +0800 Subject: [PATCH 02/14] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BB=BB=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/v1/cmb_cpn.proto | 6 ------ internal/service/mock.go | 9 --------- third_party/swagger_ui/openapi.yaml | 18 ------------------ 3 files changed, 33 deletions(-) diff --git a/api/v1/cmb_cpn.proto b/api/v1/cmb_cpn.proto index a3cd78e..ae03540 100644 --- a/api/v1/cmb_cpn.proto +++ b/api/v1/cmb_cpn.proto @@ -62,12 +62,6 @@ service Cmb { }; } - rpc Test (Empty) returns (Empty) { - option (google.api.http) = { - post: "/voucher/cmb/v1/test", - body: "*" - }; - } } message OrderRetryRequest { diff --git a/internal/service/mock.go b/internal/service/mock.go index 549e4e0..4b71eaa 100644 --- a/internal/service/mock.go +++ b/internal/service/mock.go @@ -62,12 +62,3 @@ func (s *CmbService) DecryptBody(ctx context.Context, request *v1.EncryptBodyReq DecryptBody: decryptBody, }, nil } - -func (s *CmbService) Test(ctx context.Context, request *v1.Empty) (*v1.Empty, error) { - - if err := s.VoucherBiz.ExecuteNotice(ctx); err != nil { - return nil, err - } - - return nil, nil -} diff --git a/third_party/swagger_ui/openapi.yaml b/third_party/swagger_ui/openapi.yaml index 26d9946..368aa0c 100644 --- a/third_party/swagger_ui/openapi.yaml +++ b/third_party/swagger_ui/openapi.yaml @@ -150,24 +150,6 @@ paths: application/json: schema: $ref: '#/components/schemas/api.v1.CmbRequest' - /voucher/cmb/v1/test: - post: - tags: - - Cmb - operationId: Cmb_Test - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/api.v1.Empty' - required: true - responses: - "200": - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/api.v1.Empty' components: schemas: api.v1.CmbOrderRequest: From c556912b1b501f4127a260502fa6449c4ea8dcd1 Mon Sep 17 00:00:00 2001 From: ziming Date: Thu, 5 Jun 2025 10:30:25 +0800 Subject: [PATCH 03/14] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BB=BB=E5=8A=A12?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/data/repoimpl/order.go | 1 - 1 file changed, 1 deletion(-) diff --git a/internal/data/repoimpl/order.go b/internal/data/repoimpl/order.go index a2f4c2f..33a78e9 100644 --- a/internal/data/repoimpl/order.go +++ b/internal/data/repoimpl/order.go @@ -37,7 +37,6 @@ func (p *OrderRepoImpl) FinByStockIdInBatches(ctx context.Context, batchNo strin result := p.DB(ctx). Where("batch_no = ?", batchNo). Where("status = ?", vo.OrderStatusSuccess.GetValue()). - Limit(20). FindInBatches(&results, 10, func(tx *gorm.DB, batch int) error { return fun(ctx, p.ToBos(results)) }) From d11ff47f0c3a49d5fd871873171ea6a797b84eed Mon Sep 17 00:00:00 2001 From: ziming Date: Thu, 5 Jun 2025 13:46:55 +0800 Subject: [PATCH 04/14] =?UTF-8?q?=E8=BF=87=E6=9C=9F=E4=B8=8D=E5=81=9A?= =?UTF-8?q?=E9=80=9A=E7=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/biz/wechat_notify.go | 3 ++- internal/biz/wechat_query.go | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/internal/biz/wechat_notify.go b/internal/biz/wechat_notify.go index 280e9e7..0661fa0 100644 --- a/internal/biz/wechat_notify.go +++ b/internal/biz/wechat_notify.go @@ -78,7 +78,8 @@ func (v *VoucherBiz) expired(ctx context.Context, order *bo.OrderBo) error { return err } - return v.notify(ctx, order) + //return v.notify(ctx, order) + return nil // 过期不做通知 } func (v *VoucherBiz) notify(ctx context.Context, order *bo.OrderBo) error { diff --git a/internal/biz/wechat_query.go b/internal/biz/wechat_query.go index 166d296..df37155 100644 --- a/internal/biz/wechat_query.go +++ b/internal/biz/wechat_query.go @@ -61,6 +61,8 @@ func (v *VoucherBiz) wechatQuery(ctx context.Context, order *bo.OrderBo) error { if status.IsUse() { return v.used(ctx, order) + } else if status.IsExpired() { + return v.expired(ctx, order) } return nil From 70c2f65dbfa938c2ebd94b4a4c5a397a76564c41 Mon Sep 17 00:00:00 2001 From: ziming Date: Thu, 5 Jun 2025 14:48:23 +0800 Subject: [PATCH 05/14] =?UTF-8?q?=E9=A2=86=E5=8F=96=E6=88=90=E5=8A=9F?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E6=A0=B8=E9=94=80=E7=8A=B6=E6=80=81=EF=BC=8C?= =?UTF-8?q?=E8=BF=87=E6=9C=9F=E4=B8=8D=E5=81=9A=E9=80=9A=E7=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/biz/wechat_query.go | 9 +++++++++ internal/data/repoimpl/order.go | 2 +- internal/service/wechat_query.go | 13 ++++--------- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/internal/biz/wechat_query.go b/internal/biz/wechat_query.go index df37155..83a0561 100644 --- a/internal/biz/wechat_query.go +++ b/internal/biz/wechat_query.go @@ -34,10 +34,19 @@ func (v *VoucherBiz) WechatQuery(ctx context.Context, batchNo string) error { return fmt.Errorf("batchNo is empty") } + log.Infof("微信查询券订单状态,batchNo:%s", batchNo) + + num := 0 return v.OrderRepo.FinByStockIdInBatches(ctx, batchNo, func(ctx context.Context, rows []*bo.OrderBo) error { + if len(rows) == 0 { + log.Infof("微信查询券订单状态,batchNo[%s],已处理[%d]单,无订单,结束执行", batchNo, num) + return nil + } + for _, order := range rows { + num += 1 if err := v.wechatQuery(ctx, order); err != nil { log.Errorf("微信查询券订单状态发生错误,batchNo:%s,orderNo:%s,couponId:%s,appId:%s,openId:%s,err:%v", batchNo, order.OrderNo, order.VoucherNo, order.AppID, order.Account, err) diff --git a/internal/data/repoimpl/order.go b/internal/data/repoimpl/order.go index 33a78e9..79d388e 100644 --- a/internal/data/repoimpl/order.go +++ b/internal/data/repoimpl/order.go @@ -37,7 +37,7 @@ func (p *OrderRepoImpl) FinByStockIdInBatches(ctx context.Context, batchNo strin result := p.DB(ctx). Where("batch_no = ?", batchNo). Where("status = ?", vo.OrderStatusSuccess.GetValue()). - FindInBatches(&results, 10, func(tx *gorm.DB, batch int) error { + FindInBatches(&results, 20, func(tx *gorm.DB, batch int) error { return fun(ctx, p.ToBos(results)) }) diff --git a/internal/service/wechat_query.go b/internal/service/wechat_query.go index 96f3209..89a4b4c 100644 --- a/internal/service/wechat_query.go +++ b/internal/service/wechat_query.go @@ -4,8 +4,6 @@ import ( "context" "fmt" "github.com/go-kratos/kratos/v2/log" - "time" - "voucher/internal/pkg/lock" "voucher/internal/pkg/rdsmq" ) @@ -39,12 +37,9 @@ func (s *VoucherService) Handle(ctx context.Context, msg string) error { return nil } - return lock.NewMutex(s.rdb.Rdb, time.Hour*10).Lock(ctx, fmt.Sprintf("cmb_wechant_query_%s", msg), func(ctx context.Context) error { + if err := s.VoucherBiz.WechatQuery(ctx, msg); err != nil { + s.logHelper.Error(err) + } - if err := s.VoucherBiz.WechatQuery(ctx, msg); err != nil { - s.logHelper.Error(err) - } - - return nil - }) + return nil } From 5eebfb7b915a30480ec3b25dc210bd7f9bc74da4 Mon Sep 17 00:00:00 2001 From: ziming Date: Thu, 5 Jun 2025 15:13:38 +0800 Subject: [PATCH 06/14] =?UTF-8?q?=E9=A2=86=E5=8F=96=E6=88=90=E5=8A=9F?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E6=A0=B8=E9=94=80=E7=8A=B6=E6=80=81=EF=BC=8C?= =?UTF-8?q?=E8=BF=87=E6=9C=9F=E4=B8=8D=E5=81=9A=E9=80=9A=E7=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/service/wechat_query.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/internal/service/wechat_query.go b/internal/service/wechat_query.go index 89a4b4c..687ec5d 100644 --- a/internal/service/wechat_query.go +++ b/internal/service/wechat_query.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "github.com/go-kratos/kratos/v2/log" + "time" "voucher/internal/pkg/rdsmq" ) @@ -30,16 +31,18 @@ func (s *VoucherService) GetConfig() *rdsmq.ConsumeConfig { } } -func (s *VoucherService) Handle(ctx context.Context, msg string) error { +func (s *VoucherService) Handle(ctx context.Context, batchNo string) error { - if msg == "" { + if batchNo == "" { s.logHelper.Errorf("RdsMQ keySend error: batchNo is empty") return nil } - if err := s.VoucherBiz.WechatQuery(ctx, msg); err != nil { + start := time.Now() + if err := s.VoucherBiz.WechatQuery(ctx, batchNo); err != nil { s.logHelper.Error(err) } + log.Warnf("处理耗时:%s,batchNo:%s", time.Now().Sub(start).String(), batchNo) return nil } From e440b477f418cbc9aa9458588374547455195d94 Mon Sep 17 00:00:00 2001 From: ziming Date: Thu, 5 Jun 2025 15:14:23 +0800 Subject: [PATCH 07/14] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E5=88=B8=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E5=A4=84=E7=90=86=E8=80=97=E6=97=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/service/wechat_query.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/wechat_query.go b/internal/service/wechat_query.go index 687ec5d..64a1417 100644 --- a/internal/service/wechat_query.go +++ b/internal/service/wechat_query.go @@ -42,7 +42,7 @@ func (s *VoucherService) Handle(ctx context.Context, batchNo string) error { if err := s.VoucherBiz.WechatQuery(ctx, batchNo); err != nil { s.logHelper.Error(err) } - log.Warnf("处理耗时:%s,batchNo:%s", time.Now().Sub(start).String(), batchNo) + log.Warnf("微信券查询处理耗时:%s,batchNo:%s", time.Now().Sub(start).String(), batchNo) return nil } From 0df46d71ba4ae4327e7ef6e8f0ccf2989634a576 Mon Sep 17 00:00:00 2001 From: ziming Date: Thu, 5 Jun 2025 15:31:08 +0800 Subject: [PATCH 08/14] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E5=88=B8=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E5=A4=84=E7=90=86=E8=80=97=E6=97=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/service/wechat_query.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/internal/service/wechat_query.go b/internal/service/wechat_query.go index 64a1417..13884ee 100644 --- a/internal/service/wechat_query.go +++ b/internal/service/wechat_query.go @@ -39,10 +39,14 @@ func (s *VoucherService) Handle(ctx context.Context, batchNo string) error { } start := time.Now() + fmt.Printf("微信券查询处理开始:%s,batchNo:%s", start.String(), batchNo) + if err := s.VoucherBiz.WechatQuery(ctx, batchNo); err != nil { s.logHelper.Error(err) } + log.Warnf("微信券查询处理耗时:%s,batchNo:%s", time.Now().Sub(start).String(), batchNo) + fmt.Printf("微信券查询处理耗时:%s,batchNo:%s", time.Now().Sub(start).String(), batchNo) return nil } From 69c4171a20a71f1fcf7fd9f52f0955aa08a844c4 Mon Sep 17 00:00:00 2001 From: ziming Date: Thu, 5 Jun 2025 18:27:22 +0800 Subject: [PATCH 09/14] wechat retry --- configs/config.yaml | 6 +++ internal/biz/repo/order.go | 1 + internal/biz/wechat_retry.go | 62 +++++++++++++++++++++++++ internal/conf/conf.pb.go | 77 +++++++++++++++++++------------- internal/conf/conf.proto | 1 + internal/data/repoimpl/order.go | 19 ++++++++ internal/server/http.go | 1 + internal/server/rds_consume.go | 4 ++ internal/service/cmb.go | 17 +++++++ internal/service/wechat_retry.go | 52 +++++++++++++++++++++ 10 files changed, 208 insertions(+), 32 deletions(-) create mode 100644 internal/biz/wechat_retry.go create mode 100644 internal/service/wechat_retry.go diff --git a/configs/config.yaml b/configs/config.yaml index 9425c90..95b9bef 100644 --- a/configs/config.yaml +++ b/configs/config.yaml @@ -91,6 +91,12 @@ rdsMQ: numWorkers: 1 #协程数量,不配置默认为10 waitTime: 1s #处理完成后等待时间 isOpen: true #是否启动消费 true/false + orderRetry: #发放结算 + name: "orderRetry" + retryNum: 1 #重试次数 + numWorkers: 1 #协程数量,不配置默认为10 + waitTime: 1s #处理完成后等待时间 + isOpen: true #是否启动消费 true/false #配置日志 logs: diff --git a/internal/biz/repo/order.go b/internal/biz/repo/order.go index 8c9bab9..2cb954f 100644 --- a/internal/biz/repo/order.go +++ b/internal/biz/repo/order.go @@ -8,6 +8,7 @@ import ( type OrderRepo interface { FinByStockIdInBatches(ctx context.Context, batchNo string, fun func(ctx context.Context, rows []*bo.OrderBo) error) error + FinFailByStockIdInBatches(ctx context.Context, batchNo string, fun func(ctx context.Context, rows []*bo.OrderBo) error) error FindIngInBatches(ctx context.Context, fun func(ctx context.Context, rows []*bo.OrderBo) error) error FindInBatches(ctx context.Context, w *bo.FindInBatchesUseBo, fun func(ctx context.Context, rows []*bo.OrderBo) error) error GetByOutBizNo(ctx context.Context, t vo.OrderType, outBizNo string) (*bo.OrderBo, error) diff --git a/internal/biz/wechat_retry.go b/internal/biz/wechat_retry.go new file mode 100644 index 0000000..321205f --- /dev/null +++ b/internal/biz/wechat_retry.go @@ -0,0 +1,62 @@ +package biz + +import ( + "context" + "fmt" + "github.com/go-kratos/kratos/v2/log" + "time" + "voucher/internal/biz/bo" +) + +func (v *VoucherBiz) PushWechatRetry(ctx context.Context, productNo string) error { + + product, err := v.ProductRepo.GetByProductNo(ctx, productNo) + if err != nil { + return err + } + + queue := v.bc.RdsMQ.GetWechatRetry() + if queue == nil { + return fmt.Errorf("队列不存在") + } + + _, err = v.rdb.Rdb.RPush(ctx, queue.Name, product.BatchNo).Result() + if err != nil { + return fmt.Errorf("添加到队列失败:%v", err) + } + + return nil +} + +func (v *VoucherBiz) WechatRetry(ctx context.Context, batchNo string) error { + + if batchNo == "" { + return fmt.Errorf("batchNo is empty") + } + + log.Infof("失败订单重试开始,batchNo:%s", batchNo) + + num := 0 + return v.OrderRepo.FinFailByStockIdInBatches(ctx, batchNo, func(ctx context.Context, rows []*bo.OrderBo) error { + + if len(rows) == 0 { + log.Infof("微信查询券订单状态,batchNo[%s],已处理[%d]单,无订单,结束执行", batchNo, num) + return nil + } + + for _, order := range rows { + + num += 1 + if err := v.orderRetry(ctx, order); err != nil { + log.Errorf("失败订单重试发生错误,batchNo:%s,orderNo:%s,appId:%s,openId:%s,err:%v", + batchNo, order.OrderNo, order.AppID, order.Account, err) + } + + } + + time.Sleep(1 * time.Second) + + return nil + }) + +} diff --git a/internal/conf/conf.pb.go b/internal/conf/conf.pb.go index dec41c7..dc691b8 100644 --- a/internal/conf/conf.pb.go +++ b/internal/conf/conf.pb.go @@ -841,6 +841,7 @@ type RdsMQ struct { unknownFields protoimpl.UnknownFields WechatQuery *RdsMQ_Queue `protobuf:"bytes,1,opt,name=wechatQuery,proto3" json:"wechatQuery,omitempty"` + WechatRetry *RdsMQ_Queue `protobuf:"bytes,2,opt,name=wechatRetry,proto3" json:"wechatRetry,omitempty"` } func (x *RdsMQ) Reset() { @@ -882,6 +883,13 @@ func (x *RdsMQ) GetWechatQuery() *RdsMQ_Queue { return nil } +func (x *RdsMQ) GetWechatRetry() *RdsMQ_Queue { + if x != nil { + return x.WechatRetry + } + return nil +} + type Logs struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1544,28 +1552,32 @@ var file_conf_conf_proto_rawDesc = []byte{ 0x6b, 0x65, 0x79, 0x12, 0x35, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x43, 0x72, 0x6f, 0x6e, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, - 0x4d, 0x61, 0x70, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xef, - 0x01, 0x0a, 0x05, 0x52, 0x64, 0x73, 0x4d, 0x51, 0x12, 0x3d, 0x0a, 0x0b, 0x77, 0x65, 0x63, 0x68, + 0x4d, 0x61, 0x70, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xae, + 0x02, 0x0a, 0x05, 0x52, 0x64, 0x73, 0x4d, 0x51, 0x12, 0x3d, 0x0a, 0x0b, 0x77, 0x65, 0x63, 0x68, 0x61, 0x74, 0x51, 0x75, 0x65, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x52, 0x64, 0x73, 0x4d, 0x51, 0x2e, 0x51, 0x75, 0x65, 0x75, 0x65, 0x52, 0x0b, 0x77, 0x65, 0x63, 0x68, - 0x61, 0x74, 0x51, 0x75, 0x65, 0x72, 0x79, 0x1a, 0xa6, 0x01, 0x0a, 0x05, 0x51, 0x75, 0x65, 0x75, - 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x69, 0x73, 0x4f, 0x70, 0x65, 0x6e, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x69, 0x73, 0x4f, 0x70, 0x65, 0x6e, 0x12, 0x1a, 0x0a, - 0x08, 0x72, 0x65, 0x74, 0x72, 0x79, 0x4e, 0x75, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, - 0x08, 0x72, 0x65, 0x74, 0x72, 0x79, 0x4e, 0x75, 0x6d, 0x12, 0x1e, 0x0a, 0x0a, 0x6e, 0x75, 0x6d, - 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x6e, - 0x75, 0x6d, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x73, 0x12, 0x35, 0x0a, 0x08, 0x77, 0x61, 0x69, - 0x74, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x77, 0x61, 0x69, 0x74, 0x54, 0x69, 0x6d, 0x65, - 0x22, 0x3a, 0x0a, 0x04, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x62, 0x75, 0x73, 0x69, - 0x6e, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x62, 0x75, 0x73, 0x69, - 0x6e, 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x42, 0x17, 0x5a, 0x15, - 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x2f, 0x63, 0x70, 0x6e, 0x2f, 0x63, 0x6f, 0x6e, 0x66, - 0x3b, 0x63, 0x6f, 0x6e, 0x66, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x61, 0x74, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x3d, 0x0a, 0x0b, 0x77, 0x65, 0x63, 0x68, 0x61, + 0x74, 0x52, 0x65, 0x74, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x76, + 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x52, 0x64, + 0x73, 0x4d, 0x51, 0x2e, 0x51, 0x75, 0x65, 0x75, 0x65, 0x52, 0x0b, 0x77, 0x65, 0x63, 0x68, 0x61, + 0x74, 0x52, 0x65, 0x74, 0x72, 0x79, 0x1a, 0xa6, 0x01, 0x0a, 0x05, 0x51, 0x75, 0x65, 0x75, 0x65, + 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x69, 0x73, 0x4f, 0x70, 0x65, 0x6e, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x69, 0x73, 0x4f, 0x70, 0x65, 0x6e, 0x12, 0x1a, 0x0a, 0x08, + 0x72, 0x65, 0x74, 0x72, 0x79, 0x4e, 0x75, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, + 0x72, 0x65, 0x74, 0x72, 0x79, 0x4e, 0x75, 0x6d, 0x12, 0x1e, 0x0a, 0x0a, 0x6e, 0x75, 0x6d, 0x57, + 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x6e, 0x75, + 0x6d, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x73, 0x12, 0x35, 0x0a, 0x08, 0x77, 0x61, 0x69, 0x74, + 0x54, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x77, 0x61, 0x69, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x22, + 0x3a, 0x0a, 0x04, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x62, 0x75, 0x73, 0x69, 0x6e, + 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x62, 0x75, 0x73, 0x69, 0x6e, + 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x42, 0x17, 0x5a, 0x15, 0x76, + 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x2f, 0x63, 0x70, 0x6e, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x3b, + 0x63, 0x6f, 0x6e, 0x66, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1620,19 +1632,20 @@ var file_conf_conf_proto_depIdxs = []int32{ 15, // 13: voucher.config.RocketMQ.eventMap:type_name -> voucher.config.RocketMQ.EventMapEntry 17, // 14: voucher.config.Cron.commandMap:type_name -> voucher.config.Cron.CommandMapEntry 18, // 15: voucher.config.RdsMQ.wechatQuery:type_name -> voucher.config.RdsMQ.Queue - 19, // 16: voucher.config.Server.HTTP.timeout:type_name -> google.protobuf.Duration - 19, // 17: voucher.config.Data.Database.maxLifetime:type_name -> google.protobuf.Duration - 19, // 18: voucher.config.Data.Redis.readTimeout:type_name -> google.protobuf.Duration - 19, // 19: voucher.config.Data.Redis.writeTimeout:type_name -> google.protobuf.Duration - 19, // 20: voucher.config.Data.Redis.connMaxIdleTime:type_name -> google.protobuf.Duration - 4, // 21: voucher.config.RocketMQ.EventMapEntry.value:type_name -> voucher.config.EventMap - 16, // 22: voucher.config.Cron.CommandMapEntry.value:type_name -> voucher.config.Cron.CommandMap - 19, // 23: voucher.config.RdsMQ.Queue.waitTime:type_name -> google.protobuf.Duration - 24, // [24:24] is the sub-list for method output_type - 24, // [24:24] 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 + 18, // 16: voucher.config.RdsMQ.wechatRetry:type_name -> voucher.config.RdsMQ.Queue + 19, // 17: voucher.config.Server.HTTP.timeout:type_name -> google.protobuf.Duration + 19, // 18: voucher.config.Data.Database.maxLifetime:type_name -> google.protobuf.Duration + 19, // 19: voucher.config.Data.Redis.readTimeout:type_name -> google.protobuf.Duration + 19, // 20: voucher.config.Data.Redis.writeTimeout:type_name -> google.protobuf.Duration + 19, // 21: voucher.config.Data.Redis.connMaxIdleTime:type_name -> google.protobuf.Duration + 4, // 22: voucher.config.RocketMQ.EventMapEntry.value:type_name -> voucher.config.EventMap + 16, // 23: voucher.config.Cron.CommandMapEntry.value:type_name -> voucher.config.Cron.CommandMap + 19, // 24: voucher.config.RdsMQ.Queue.waitTime:type_name -> google.protobuf.Duration + 25, // [25:25] is the sub-list for method output_type + 25, // [25:25] is the sub-list for method input_type + 25, // [25:25] is the sub-list for extension type_name + 25, // [25:25] is the sub-list for extension extendee + 0, // [0:25] is the sub-list for field type_name } func init() { file_conf_conf_proto_init() } diff --git a/internal/conf/conf.proto b/internal/conf/conf.proto index b548e46..cb15acf 100644 --- a/internal/conf/conf.proto +++ b/internal/conf/conf.proto @@ -128,6 +128,7 @@ message RdsMQ { google.protobuf.Duration waitTime = 5; } Queue wechatQuery = 1; + Queue wechatRetry = 2; } message Logs { diff --git a/internal/data/repoimpl/order.go b/internal/data/repoimpl/order.go index 79d388e..9d2d180 100644 --- a/internal/data/repoimpl/order.go +++ b/internal/data/repoimpl/order.go @@ -48,6 +48,25 @@ func (p *OrderRepoImpl) FinByStockIdInBatches(ctx context.Context, batchNo strin return nil } +func (p *OrderRepoImpl) FinFailByStockIdInBatches(ctx context.Context, batchNo string, fun func(ctx context.Context, rows []*bo.OrderBo) error) error { + + var results = make([]*model.Order, 0) + + result := p.DB(ctx). + Where("batch_no = ?", batchNo). + Where("status = ?", vo.OrderStatusFail.GetValue()). + Where("remark <> ?", "error: code = 500 reason = WechatFAIL message = 微信返回错误:该用户账号异常,无法领券。商家可联系微信支付或让用户联系微信支付客服处理。 metadat"). + FindInBatches(&results, 50, func(tx *gorm.DB, batch int) error { + return fun(ctx, p.ToBos(results)) + }) + + if result.Error != nil { + return result.Error + } + + return nil +} + func (p *OrderRepoImpl) FindIngInBatches(ctx context.Context, fun func(ctx context.Context, rows []*bo.OrderBo) error) error { var results = make([]*model.Order, 0) diff --git a/internal/server/http.go b/internal/server/http.go index 636e471..c3e4e80 100644 --- a/internal/server/http.go +++ b/internal/server/http.go @@ -40,6 +40,7 @@ func NewHTTPServer( srv.Route("/voucher/").GET("queryOrder/{order_no}", cmb.QueryOrder) srv.Route("/voucher/").GET("registerTag/{product_no}", cmb.RegisterTag) srv.Route("/voucher/").GET("pushWechatQuery/{product_no}", cmb.PushWechatQuery) + srv.Route("/voucher/").GET("pushWechatQuery/{product_no}", cmb.PushWechatRetry) v1.RegisterCmbHTTPServer(srv, cmb) diff --git a/internal/server/rds_consume.go b/internal/server/rds_consume.go index e5fa79c..9eed6ef 100644 --- a/internal/server/rds_consume.go +++ b/internal/server/rds_consume.go @@ -30,6 +30,10 @@ func NewRdbConsumer( manager.Add(cf) } + if cf2 := voucherService.GetWechatConfig(); cf2 != nil { + manager.Add(cf2) + } + return &RdbConsumer{hLog: hLog, conf: conf, manager: manager} } diff --git a/internal/service/cmb.go b/internal/service/cmb.go index 2d2d260..bcbdc12 100644 --- a/internal/service/cmb.go +++ b/internal/service/cmb.go @@ -129,3 +129,20 @@ func (this *CmbService) PushWechatQuery(ctx http.Context) error { "data": productNo, }) } + +func (this *CmbService) PushWechatRetry(ctx http.Context) error { + + productNo := ctx.Vars().Get("product_no") + if productNo == "" { + return fmt.Errorf("product_no is empty") + } + + err := this.VoucherBiz.PushWechatRetry(ctx, productNo) + if err != nil { + return err + } + + return ctx.JSON(http2.StatusOK, map[string]interface{}{ + "data": productNo, + }) +} diff --git a/internal/service/wechat_retry.go b/internal/service/wechat_retry.go new file mode 100644 index 0000000..04a8bfd --- /dev/null +++ b/internal/service/wechat_retry.go @@ -0,0 +1,52 @@ +package service + +import ( + "context" + "fmt" + "github.com/go-kratos/kratos/v2/log" + "time" + "voucher/internal/pkg/rdsmq" +) + +func (s *VoucherService) GetWechatConfig() *rdsmq.ConsumeConfig { + + queue := s.bc.RdsMQ.GetWechatRetry() + if queue == nil { + return nil + } + + if !queue.GetIsOpen() { + log.Warn(fmt.Sprintf("[%s]RdsMQ is not open", queue.Name)) + return nil + } + + return &rdsmq.ConsumeConfig{ + Rdb: s.rdb.Rdb, + QueueName: queue.Name, + NumWorkers: queue.NumWorkers, + WaitTime: queue.GetWaitTime().AsDuration(), + RetryNum: queue.RetryNum, + Fn: s.HandleWechat, + Logger: s.logHelper, + } +} + +func (s *VoucherService) HandleWechat(ctx context.Context, batchNo string) error { + + if batchNo == "" { + s.logHelper.Errorf("RdsMQ keySend error: batchNo is empty") + return nil + } + + start := time.Now() + fmt.Printf("失败订单重试处理开始:%s,batchNo:%s", start.String(), batchNo) + + if err := s.VoucherBiz.WechatRetry(ctx, batchNo); err != nil { + s.logHelper.Error(err) + } + + log.Warnf("失败订单重试处理耗时:%s,batchNo:%s", time.Now().Sub(start).String(), batchNo) + fmt.Printf("失败订单重试处理耗时:%s,batchNo:%s", time.Now().Sub(start).String(), batchNo) + + return nil +} From 7a02c6047cc718fe5a94fc0311698944ff52f01b Mon Sep 17 00:00:00 2001 From: ziming Date: Thu, 5 Jun 2025 18:28:14 +0800 Subject: [PATCH 10/14] wechat retry --- internal/server/http.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/server/http.go b/internal/server/http.go index c3e4e80..c89501c 100644 --- a/internal/server/http.go +++ b/internal/server/http.go @@ -40,7 +40,7 @@ func NewHTTPServer( srv.Route("/voucher/").GET("queryOrder/{order_no}", cmb.QueryOrder) srv.Route("/voucher/").GET("registerTag/{product_no}", cmb.RegisterTag) srv.Route("/voucher/").GET("pushWechatQuery/{product_no}", cmb.PushWechatQuery) - srv.Route("/voucher/").GET("pushWechatQuery/{product_no}", cmb.PushWechatRetry) + srv.Route("/voucher/").GET("pushWechatRetry/{product_no}", cmb.PushWechatRetry) v1.RegisterCmbHTTPServer(srv, cmb) From 15de8ab27746990826a0692a5f5b0e2563fe2f7c Mon Sep 17 00:00:00 2001 From: ziming Date: Fri, 6 Jun 2025 09:04:10 +0800 Subject: [PATCH 11/14] FinByStockIdInBatches --- internal/data/repoimpl/order.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/data/repoimpl/order.go b/internal/data/repoimpl/order.go index 9d2d180..0be4e8b 100644 --- a/internal/data/repoimpl/order.go +++ b/internal/data/repoimpl/order.go @@ -37,7 +37,7 @@ func (p *OrderRepoImpl) FinByStockIdInBatches(ctx context.Context, batchNo strin result := p.DB(ctx). Where("batch_no = ?", batchNo). Where("status = ?", vo.OrderStatusSuccess.GetValue()). - FindInBatches(&results, 20, func(tx *gorm.DB, batch int) error { + FindInBatches(&results, 50, func(tx *gorm.DB, batch int) error { return fun(ctx, p.ToBos(results)) }) From 3362eec30120e56cac71187222be48af9fa31da3 Mon Sep 17 00:00:00 2001 From: ziming Date: Fri, 6 Jun 2025 09:07:27 +0800 Subject: [PATCH 12/14] WechatQuery --- internal/biz/wechat_query.go | 19 ++++++++++++------- internal/service/wechat_query.go | 7 ------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/internal/biz/wechat_query.go b/internal/biz/wechat_query.go index 83a0561..ebef404 100644 --- a/internal/biz/wechat_query.go +++ b/internal/biz/wechat_query.go @@ -34,15 +34,12 @@ func (v *VoucherBiz) WechatQuery(ctx context.Context, batchNo string) error { return fmt.Errorf("batchNo is empty") } - log.Infof("微信查询券订单状态,batchNo:%s", batchNo) + start := time.Now() + log.Warnf("微信券查询处理开始:%s,batchNo:%s", start.String(), batchNo) + fmt.Printf("微信券查询处理开始:%s,batchNo:%s", start.String(), batchNo) num := 0 - return v.OrderRepo.FinByStockIdInBatches(ctx, batchNo, func(ctx context.Context, rows []*bo.OrderBo) error { - - if len(rows) == 0 { - log.Infof("微信查询券订单状态,batchNo[%s],已处理[%d]单,无订单,结束执行", batchNo, num) - return nil - } + err := v.OrderRepo.FinByStockIdInBatches(ctx, batchNo, func(ctx context.Context, rows []*bo.OrderBo) error { for _, order := range rows { @@ -59,6 +56,14 @@ func (v *VoucherBiz) WechatQuery(ctx context.Context, batchNo string) error { return nil }) + if err != nil { + return err + } + + log.Warnf("微信券查询处理耗时:%s,batchNo:%s,处理%d单", time.Now().Sub(start).String(), batchNo, num) + fmt.Printf("微信券查询处理耗时:%s,batchNo:%s,处理%d单", time.Now().Sub(start).String(), batchNo, num) + + return nil } func (v *VoucherBiz) wechatQuery(ctx context.Context, order *bo.OrderBo) error { diff --git a/internal/service/wechat_query.go b/internal/service/wechat_query.go index 13884ee..98d7813 100644 --- a/internal/service/wechat_query.go +++ b/internal/service/wechat_query.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "github.com/go-kratos/kratos/v2/log" - "time" "voucher/internal/pkg/rdsmq" ) @@ -38,15 +37,9 @@ func (s *VoucherService) Handle(ctx context.Context, batchNo string) error { return nil } - start := time.Now() - fmt.Printf("微信券查询处理开始:%s,batchNo:%s", start.String(), batchNo) - if err := s.VoucherBiz.WechatQuery(ctx, batchNo); err != nil { s.logHelper.Error(err) } - log.Warnf("微信券查询处理耗时:%s,batchNo:%s", time.Now().Sub(start).String(), batchNo) - fmt.Printf("微信券查询处理耗时:%s,batchNo:%s", time.Now().Sub(start).String(), batchNo) - return nil } From 994e47b4d0577fb6a9ecbaca970cc2e5abb92f5f Mon Sep 17 00:00:00 2001 From: ziming Date: Fri, 6 Jun 2025 09:13:42 +0800 Subject: [PATCH 13/14] WechatQuery --- internal/biz/wechat_query.go | 10 +--------- internal/biz/wechat_retry.go | 14 ++++++++------ internal/service/wechat_query.go | 2 +- internal/service/wechat_retry.go | 7 ------- 4 files changed, 10 insertions(+), 23 deletions(-) diff --git a/internal/biz/wechat_query.go b/internal/biz/wechat_query.go index ebef404..4ab32b2 100644 --- a/internal/biz/wechat_query.go +++ b/internal/biz/wechat_query.go @@ -30,10 +30,6 @@ func (v *VoucherBiz) PushWechatQuery(ctx context.Context, productNo string) erro func (v *VoucherBiz) WechatQuery(ctx context.Context, batchNo string) error { - if batchNo == "" { - return fmt.Errorf("batchNo is empty") - } - start := time.Now() log.Warnf("微信券查询处理开始:%s,batchNo:%s", start.String(), batchNo) fmt.Printf("微信券查询处理开始:%s,batchNo:%s", start.String(), batchNo) @@ -56,14 +52,10 @@ func (v *VoucherBiz) WechatQuery(ctx context.Context, batchNo string) error { return nil }) - if err != nil { - return err - } - log.Warnf("微信券查询处理耗时:%s,batchNo:%s,处理%d单", time.Now().Sub(start).String(), batchNo, num) fmt.Printf("微信券查询处理耗时:%s,batchNo:%s,处理%d单", time.Now().Sub(start).String(), batchNo, num) - return nil + return err } func (v *VoucherBiz) wechatQuery(ctx context.Context, order *bo.OrderBo) error { diff --git a/internal/biz/wechat_retry.go b/internal/biz/wechat_retry.go index 321205f..c5fe0c0 100644 --- a/internal/biz/wechat_retry.go +++ b/internal/biz/wechat_retry.go @@ -30,14 +30,12 @@ func (v *VoucherBiz) PushWechatRetry(ctx context.Context, productNo string) erro func (v *VoucherBiz) WechatRetry(ctx context.Context, batchNo string) error { - if batchNo == "" { - return fmt.Errorf("batchNo is empty") - } - - log.Infof("失败订单重试开始,batchNo:%s", batchNo) + start := time.Now() + log.Warnf("失败订单重试开始:%s,batchNo:%s", start.String(), batchNo) + fmt.Printf("失败订单重试开始:%s,batchNo:%s", start.String(), batchNo) num := 0 - return v.OrderRepo.FinFailByStockIdInBatches(ctx, batchNo, func(ctx context.Context, rows []*bo.OrderBo) error { + err := v.OrderRepo.FinFailByStockIdInBatches(ctx, batchNo, func(ctx context.Context, rows []*bo.OrderBo) error { if len(rows) == 0 { log.Infof("微信查询券订单状态,batchNo[%s],已处理[%d]单,无订单,结束执行", batchNo, num) @@ -59,4 +57,8 @@ func (v *VoucherBiz) WechatRetry(ctx context.Context, batchNo string) error { return nil }) + log.Warnf("微信券查询处理耗时:%s,batchNo:%s,处理%d单", time.Now().Sub(start).String(), batchNo, num) + fmt.Printf("微信券查询处理耗时:%s,batchNo:%s,处理%d单", time.Now().Sub(start).String(), batchNo, num) + + return err } diff --git a/internal/service/wechat_query.go b/internal/service/wechat_query.go index 98d7813..35a2a9f 100644 --- a/internal/service/wechat_query.go +++ b/internal/service/wechat_query.go @@ -33,7 +33,7 @@ func (s *VoucherService) GetConfig() *rdsmq.ConsumeConfig { func (s *VoucherService) Handle(ctx context.Context, batchNo string) error { if batchNo == "" { - s.logHelper.Errorf("RdsMQ keySend error: batchNo is empty") + s.logHelper.Errorf("wechat query error: batchNo is empty") return nil } diff --git a/internal/service/wechat_retry.go b/internal/service/wechat_retry.go index 04a8bfd..34cc754 100644 --- a/internal/service/wechat_retry.go +++ b/internal/service/wechat_retry.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "github.com/go-kratos/kratos/v2/log" - "time" "voucher/internal/pkg/rdsmq" ) @@ -38,15 +37,9 @@ func (s *VoucherService) HandleWechat(ctx context.Context, batchNo string) error return nil } - start := time.Now() - fmt.Printf("失败订单重试处理开始:%s,batchNo:%s", start.String(), batchNo) - if err := s.VoucherBiz.WechatRetry(ctx, batchNo); err != nil { s.logHelper.Error(err) } - log.Warnf("失败订单重试处理耗时:%s,batchNo:%s", time.Now().Sub(start).String(), batchNo) - fmt.Printf("失败订单重试处理耗时:%s,batchNo:%s", time.Now().Sub(start).String(), batchNo) - return nil } From b70eda503b8a2178b34af30ab8e23876a9e9f038 Mon Sep 17 00:00:00 2001 From: ziming Date: Fri, 6 Jun 2025 09:16:50 +0800 Subject: [PATCH 14/14] WechatQuery --- internal/biz/repo/order.go | 2 +- internal/biz/wechat_query.go | 2 +- internal/data/repoimpl/order.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/biz/repo/order.go b/internal/biz/repo/order.go index 2cb954f..e3520d8 100644 --- a/internal/biz/repo/order.go +++ b/internal/biz/repo/order.go @@ -7,7 +7,7 @@ import ( ) type OrderRepo interface { - FinByStockIdInBatches(ctx context.Context, batchNo string, fun func(ctx context.Context, rows []*bo.OrderBo) error) error + FinSucByStockIdInBatches(ctx context.Context, batchNo string, fun func(ctx context.Context, rows []*bo.OrderBo) error) error FinFailByStockIdInBatches(ctx context.Context, batchNo string, fun func(ctx context.Context, rows []*bo.OrderBo) error) error FindIngInBatches(ctx context.Context, fun func(ctx context.Context, rows []*bo.OrderBo) error) error FindInBatches(ctx context.Context, w *bo.FindInBatchesUseBo, fun func(ctx context.Context, rows []*bo.OrderBo) error) error diff --git a/internal/biz/wechat_query.go b/internal/biz/wechat_query.go index 4ab32b2..b725138 100644 --- a/internal/biz/wechat_query.go +++ b/internal/biz/wechat_query.go @@ -35,7 +35,7 @@ func (v *VoucherBiz) WechatQuery(ctx context.Context, batchNo string) error { fmt.Printf("微信券查询处理开始:%s,batchNo:%s", start.String(), batchNo) num := 0 - err := v.OrderRepo.FinByStockIdInBatches(ctx, batchNo, func(ctx context.Context, rows []*bo.OrderBo) error { + err := v.OrderRepo.FinSucByStockIdInBatches(ctx, batchNo, func(ctx context.Context, rows []*bo.OrderBo) error { for _, order := range rows { diff --git a/internal/data/repoimpl/order.go b/internal/data/repoimpl/order.go index 0be4e8b..d00826f 100644 --- a/internal/data/repoimpl/order.go +++ b/internal/data/repoimpl/order.go @@ -30,7 +30,7 @@ func (p *OrderRepoImpl) DB(ctx context.Context) *gorm.DB { return p.db.DB(ctx).Model(model.Order{}) } -func (p *OrderRepoImpl) FinByStockIdInBatches(ctx context.Context, batchNo string, fun func(ctx context.Context, rows []*bo.OrderBo) error) error { +func (p *OrderRepoImpl) FinSucByStockIdInBatches(ctx context.Context, batchNo string, fun func(ctx context.Context, rows []*bo.OrderBo) error) error { var results = make([]*model.Order, 0)