github.com/weedge/lib@v0.0.0-20230424045628-a36dcc1d90e4/chain/link.go (about) 1 //@author wuyong 2 //@date 2020/7/7 3 //@desc simple link processor 4 5 package chain 6 7 import ( 8 "fmt" 9 "reflect" 10 "time" 11 12 "github.com/weedge/lib/log" 13 //JsonIter "github.com/json-iterator/go" 14 ) 15 16 type IParam interface { 17 ValidateData() bool 18 } 19 20 type IProcessor interface { 21 Process(input IParam) (err error, output IParam) 22 } 23 24 const ( 25 PROCESS_STATUS_UNDO = iota 26 PROCESS_STATUS_DOING 27 PROCESS_STATUS_OK 28 PROCESS_STATUS_FAIL 29 ) 30 31 // ctx->ctx->ctx 32 type LinkItem struct { 33 IsPass bool 34 Id int 35 Name string 36 Cost int64 37 Processor IProcessor 38 Status int 39 Next *LinkItem 40 } 41 42 type Link struct { 43 Head *LinkItem 44 Tail *LinkItem 45 Length int 46 } 47 48 func NewLinkItem(isPass bool, name string, processor IProcessor) (linkItem *LinkItem) { 49 return &LinkItem{IsPass: isPass, Name: name, Processor: processor, Status: PROCESS_STATUS_UNDO} 50 } 51 52 func (item *LinkItem) SetNext(linkItem *LinkItem) { 53 item.Next = linkItem 54 } 55 56 func InitLink(head *LinkItem) (link *Link) { 57 if head == nil { 58 return 59 } 60 61 return &Link{Head: head, Tail: head, Length: 1} 62 } 63 64 func (link *Link) SetNextItem(linkItem *LinkItem) { 65 if linkItem == nil { 66 return 67 } 68 linkItem.Id = link.Length 69 link.Tail.SetNext(linkItem) 70 link.Length += 1 71 link.Tail = link.Tail.Next 72 } 73 74 func (l *Link) Handle(input IParam) (err error) { 75 var output IParam 76 var preTime int64 77 p := l.Head 78 for p != nil { 79 log.Infof("id[%d]_%s_input_%s[%v]", p.Id, p.Name, reflect.TypeOf(input).String(), input) 80 81 preTime = time.Now().UnixNano() 82 p.Status = PROCESS_STATUS_DOING 83 err, output = p.Processor.Process(input) 84 p.Cost = int64((time.Now().UnixNano() - preTime) / 1000000) 85 if err != nil { 86 p.Status = PROCESS_STATUS_FAIL 87 log.Errorf("%s process err", p.Name) 88 if !p.IsPass { 89 return 90 } 91 log.Infof("%s process pass", p.Name) 92 } else { 93 p.Status = PROCESS_STATUS_OK 94 log.Infof("%s process ok", p.Name) 95 } 96 97 if p.Next == nil { //end print output 98 log.Infof("%s_output[%v]", p.Name, output) 99 } 100 101 input = output 102 p = p.Next 103 } //end for 104 105 return 106 } 107 108 func (l *Link) CheckSameName() (err error) { 109 mapName := map[string]struct{}{} 110 p := l.Head 111 for p != nil { 112 if _, ok := mapName[p.Name]; ok { 113 return fmt.Errorf("have the same name: %s", p.Name) 114 } 115 p = p.Next 116 } 117 return 118 } 119 120 func (l *Link) GetAllProcessorCost() (mapCost map[string]int64) { 121 mapCost = map[string]int64{} 122 p := l.Head 123 for p != nil { 124 mapCost[p.Name] = p.Cost 125 p = p.Next 126 } 127 128 return 129 } 130 131 func (l *Link) FormatCost() (str string) { 132 totalCost := int64(0) 133 p := l.Head 134 for p != nil { 135 str += fmt.Sprintf("%s_pass[%t]_status[%d]_cost[%d]->", p.Name, p.IsPass, p.Status, p.Cost) 136 totalCost += p.Cost 137 p = p.Next 138 } 139 str += fmt.Sprintf("totalCost:%d", totalCost) 140 return 141 } 142 143 func (l *Link) HandleMap(input map[string]interface{}) (err error) { 144 return 145 } 146 147 func (l *Link) HandleRpc(input []byte) (err error) { 148 return 149 }