github.com/15mga/kiwi@v0.0.2-0.20240324021231-b95d5c3ac751/core/router.go (about) 1 package core 2 3 import ( 4 "github.com/15mga/kiwi" 5 "github.com/15mga/kiwi/util" 6 "github.com/15mga/kiwi/worker" 7 "github.com/orcaman/concurrent-map/v2" 8 "github.com/panjf2000/ants/v2" 9 ) 10 11 func InitRouter() { 12 s := &router{ 13 pusHandle: make(map[kiwi.TSvcCode]kiwi.FnRcvPus), 14 reqHandle: make(map[kiwi.TSvcCode]kiwi.FnRcvReq), 15 idToRequest: cmap.NewWithCustomShardingFunction[int64, kiwi.ISndRequest](func(key int64) uint32 { 16 return uint32(key) 17 }), 18 watchCodes: make(map[kiwi.TSvc][]kiwi.TCode), 19 notifyHandler: make(map[kiwi.TSvcCode][]kiwi.NotifyHandler), 20 } 21 kiwi.SetRouter(s) 22 } 23 24 type router struct { 25 leaseId int64 26 pusHandle map[kiwi.TSvcCode]kiwi.FnRcvPus 27 reqHandle map[kiwi.TSvcCode]kiwi.FnRcvReq 28 idToRequest cmap.ConcurrentMap[int64, kiwi.ISndRequest] 29 watchCodes map[kiwi.TSvc][]kiwi.TCode 30 notifyHandler map[kiwi.TSvcCode][]kiwi.NotifyHandler 31 } 32 33 func (s *router) OnPush(pkt kiwi.IRcvPush) { 34 fn, ok := s.pusHandle[kiwi.MergeSvcCode(pkt.Svc(), pkt.Code())] 35 if !ok { 36 kiwi.TE(pkt.Tid(), util.NewErr(util.EcNotExist, util.M{ 37 "service": pkt.Svc(), 38 "code": pkt.Code(), 39 })) 40 return 41 } 42 fn(pkt) 43 } 44 45 func (s *router) OnRequest(pkt kiwi.IRcvRequest) { 46 fn, ok := s.reqHandle[kiwi.MergeSvcCode(pkt.Svc(), pkt.Code())] 47 if !ok { 48 kiwi.TE(pkt.Tid(), util.NewErr(util.EcNotExist, util.M{ 49 "service": pkt.Svc(), 50 "code": pkt.Code(), 51 })) 52 return 53 } 54 fn(pkt) 55 } 56 57 func (s *router) BindPus(svc kiwi.TSvc, code kiwi.TCode, fn kiwi.FnRcvPus) { 58 s.pusHandle[kiwi.MergeSvcCode(svc, code)] = fn 59 } 60 61 func (s *router) BindReq(svc kiwi.TSvc, code kiwi.TCode, fn kiwi.FnRcvReq) { 62 s.reqHandle[kiwi.MergeSvcCode(svc, code)] = fn 63 } 64 65 func (s *router) AddRequest(req kiwi.ISndRequest) { 66 s.idToRequest.Set(req.Tid(), req) 67 } 68 69 func (s *router) DelRequest(tid int64) { 70 s.idToRequest.Remove(tid) 71 } 72 73 func (s *router) OnResponseOk(tid int64, head util.M, msg util.IMsg) { 74 req, ok := s.idToRequest.Pop(tid) 75 if !ok { 76 return 77 } 78 req.Ok(head, msg) 79 } 80 81 func (s *router) OnResponseOkBytes(tid int64, head util.M, bytes []byte) { 82 req, ok := s.idToRequest.Pop(tid) 83 if !ok { 84 return 85 } 86 req.OkBytes(head, bytes) 87 } 88 89 func (s *router) OnResponseFail(tid int64, head util.M, code uint16) { 90 req, ok := s.idToRequest.Pop(tid) 91 if !ok { 92 return 93 } 94 req.Fail(head, code) 95 } 96 97 func (s *router) WatchNotice(msg util.IMsg, handler kiwi.NotifyHandler) { 98 svc, code := kiwi.Codec().MsgToSvcCode(msg) 99 slc, ok := s.watchCodes[svc] 100 if ok { 101 s.watchCodes[svc] = append(slc, code) 102 } else { 103 s.watchCodes[svc] = []kiwi.TCode{code} 104 } 105 sc := kiwi.MergeSvcCode(svc, code) 106 handlerSlc, ok := s.notifyHandler[sc] 107 if !ok { 108 s.notifyHandler[sc] = []kiwi.NotifyHandler{handler} 109 } else { 110 s.notifyHandler[sc] = append(handlerSlc, handler) 111 } 112 } 113 114 func (s *router) GetWatchCodes(svc kiwi.TSvc) ([]kiwi.TCode, bool) { 115 slc, ok := s.watchCodes[svc] 116 return slc, ok 117 } 118 119 func (s *router) OnNotice(pkt kiwi.IRcvNotice) { 120 handlerSlc, ok := s.notifyHandler[kiwi.MergeSvcCode(pkt.Svc(), pkt.Code())] 121 if !ok { 122 kiwi.TE2(pkt.Tid(), util.EcNotExist, util.M{ 123 "service": pkt.Svc(), 124 "code": pkt.Code(), 125 }) 126 return 127 } 128 for _, handler := range handlerSlc { 129 handler(pkt) 130 } 131 } 132 133 func ActivePrcPus[Pus util.IMsg](pkt kiwi.IRcvPush, key string, handler func(kiwi.IRcvPush, Pus)) { 134 pkt.SetWorker(kiwi.EWorkerActive, key) 135 worker.Active().Push(key, func(params []any) { 136 pkt, handler := util.SplitSlc2[kiwi.IRcvPush, func(kiwi.IRcvPush, Pus)](params) 137 pus := pkt.Msg().(Pus) 138 kiwi.TI(pkt.Tid(), "push", util.M{ 139 "pus": pus, 140 "name": pus.ProtoReflect().Descriptor().Name(), 141 }) 142 handler(pkt, pus) 143 }, pkt, handler) 144 } 145 146 func SharePrcPus[Pus util.IMsg](pkt kiwi.IRcvPush, key string, handler func(kiwi.IRcvPush, Pus)) { 147 pkt.SetWorker(kiwi.EWorkerShare, key) 148 worker.Share().Push(key, func(params []any) { 149 pkt, handler := util.SplitSlc2[kiwi.IRcvPush, func(kiwi.IRcvPush, Pus)](params) 150 pus := pkt.Msg().(Pus) 151 kiwi.TI(pkt.Tid(), "push", util.M{ 152 "pus": pus, 153 "name": pus.ProtoReflect().Descriptor().Name(), 154 }) 155 handler(pkt, pus) 156 }, pkt, handler) 157 } 158 159 func GoPrcPus[Pus util.IMsg](pkt kiwi.IRcvPush, handler func(kiwi.IRcvPush, Pus)) { 160 pkt.SetWorker(kiwi.EWorkerGo, "") 161 e := ants.Submit(func() { 162 pus := pkt.Msg().(Pus) 163 kiwi.TI(pkt.Tid(), "push", util.M{ 164 "pus": pus, 165 "name": pus.ProtoReflect().Descriptor().Name(), 166 }) 167 handler(pkt, pus) 168 }) 169 if e != nil { 170 kiwi.TE3(pkt.Tid(), util.EcServiceErr, e) 171 } 172 } 173 174 func GlobalPrcPus[Pus util.IMsg](pkt kiwi.IRcvPush, handler func(kiwi.IRcvPush, Pus)) { 175 pkt.SetWorker(kiwi.EWorkerGlobal, "") 176 worker.Global().Push(func(params []any) { 177 pkt, handler := util.SplitSlc2[kiwi.IRcvPush, func(kiwi.IRcvPush, Pus)](params) 178 pus := pkt.Msg().(Pus) 179 kiwi.TI(pkt.Tid(), "push", util.M{ 180 "pus": pus, 181 "name": pus.ProtoReflect().Descriptor().Name(), 182 }) 183 handler(pkt, pus) 184 }, pkt, handler) 185 } 186 187 func SelfPrcPus[Pus util.IMsg](pkt kiwi.IRcvPush, handler func(kiwi.IRcvPush, Pus)) { 188 pkt.SetWorker(kiwi.EWorkerSelf, "") 189 pus := pkt.Msg().(Pus) 190 kiwi.TI(pkt.Tid(), "push", util.M{ 191 "pus": pus, 192 "name": pus.ProtoReflect().Descriptor().Name(), 193 }) 194 handler(pkt, pus) 195 } 196 197 func ActivePrcReq[Req, Res util.IMsg](pkt kiwi.IRcvRequest, key string, handler func(kiwi.IRcvRequest, Req, Res)) { 198 pkt.SetWorker(kiwi.EWorkerActive, key) 199 worker.Active().Push(key, func(params []any) { 200 pkt, handler := util.SplitSlc2[kiwi.IRcvRequest, func(kiwi.IRcvRequest, Req, Res)](params) 201 code := pkt.Code() 202 res, err := kiwi.CodecSpawnRes[Res](pkt.Svc(), code) 203 if err != nil { 204 pkt.Err(err) 205 return 206 } 207 req := pkt.Msg().(Req) 208 handler(pkt, req, res) 209 }, pkt, handler) 210 } 211 212 func SharePrcReq[Req, Res util.IMsg](pkt kiwi.IRcvRequest, key string, handler func(kiwi.IRcvRequest, Req, Res)) { 213 pkt.SetWorker(kiwi.EWorkerShare, key) 214 worker.Share().Push(key, func(params []any) { 215 pkt, handler := util.SplitSlc2[kiwi.IRcvRequest, func(kiwi.IRcvRequest, Req, Res)](params) 216 code := pkt.Code() 217 res, err := kiwi.CodecSpawnRes[Res](pkt.Svc(), code) 218 if err != nil { 219 pkt.Err(err) 220 return 221 } 222 req := pkt.Msg().(Req) 223 handler(pkt, req, res) 224 }, pkt, handler) 225 } 226 227 func GoPrcReq[Req, Res util.IMsg](pkt kiwi.IRcvRequest, handler func(kiwi.IRcvRequest, Req, Res)) { 228 pkt.SetWorker(kiwi.EWorkerGo, "") 229 e := ants.Submit(func() { 230 code := pkt.Code() 231 res, err := kiwi.CodecSpawnRes[Res](pkt.Svc(), code) 232 if err != nil { 233 pkt.Err(err) 234 return 235 } 236 req := pkt.Msg().(Req) 237 handler(pkt, req, res) 238 }) 239 if e != nil { 240 kiwi.TE3(pkt.Tid(), util.EcServiceErr, e) 241 } 242 } 243 244 func GlobalPrcReq[Req, Res util.IMsg](pkt kiwi.IRcvRequest, handler func(kiwi.IRcvRequest, Req, Res)) { 245 pkt.SetWorker(kiwi.EWorkerGlobal, "") 246 worker.Global().Push(func(params []any) { 247 pkt, handler := util.SplitSlc2[kiwi.IRcvRequest, func(kiwi.IRcvRequest, Req, Res)](params) 248 code := pkt.Code() 249 res, err := kiwi.CodecSpawnRes[Res](pkt.Svc(), code) 250 if err != nil { 251 pkt.Err(err) 252 return 253 } 254 req := pkt.Msg().(Req) 255 handler(pkt, req, res) 256 }, pkt, handler) 257 } 258 259 func SelfPrcReq[Req, Res util.IMsg](pkt kiwi.IRcvRequest, handler func(kiwi.IRcvRequest, Req, Res)) { 260 pkt.SetWorker(kiwi.EWorkerSelf, "") 261 code := pkt.Code() 262 res, err := kiwi.CodecSpawnRes[Res](pkt.Svc(), code) 263 if err != nil { 264 pkt.Err(err) 265 return 266 } 267 req := pkt.Msg().(Req) 268 handler(pkt, req, res) 269 } 270 271 func ActivePrcNtc[Ntc util.IMsg](pkt kiwi.IRcvNotice, key string, handler func(kiwi.IRcvNotice, Ntc)) { 272 pkt.SetWorker(kiwi.EWorkerActive, key) 273 worker.Active().Push(key, func(params []any) { 274 pkt, handler := util.SplitSlc2[kiwi.IRcvNotice, func(kiwi.IRcvNotice, Ntc)](params) 275 ntc := pkt.Msg().(Ntc) 276 kiwi.TI(pkt.Tid(), "notice", util.M{ 277 "ntc": ntc, 278 "name": ntc.ProtoReflect().Descriptor().Name(), 279 }) 280 handler(pkt, ntc) 281 }, pkt, handler) 282 } 283 284 func SharePrcNtc[Ntc util.IMsg](pkt kiwi.IRcvNotice, key string, handler func(kiwi.IRcvNotice, Ntc)) { 285 pkt.SetWorker(kiwi.EWorkerShare, key) 286 worker.Share().Push(key, func(params []any) { 287 pkt, handler := util.SplitSlc2[kiwi.IRcvNotice, func(kiwi.IRcvNotice, Ntc)](params) 288 ntc := pkt.Msg().(Ntc) 289 kiwi.TI(pkt.Tid(), "notice", util.M{ 290 "ntc": ntc, 291 "name": ntc.ProtoReflect().Descriptor().Name(), 292 }) 293 handler(pkt, ntc) 294 }, pkt, handler) 295 } 296 297 func GoPrcNtc[Ntc util.IMsg](pkt kiwi.IRcvNotice, handler func(kiwi.IRcvNotice, Ntc)) { 298 pkt.SetWorker(kiwi.EWorkerGo, "") 299 e := ants.Submit(func() { 300 ntc := pkt.Msg().(Ntc) 301 kiwi.TI(pkt.Tid(), "notice", util.M{ 302 "ntc": ntc, 303 "name": ntc.ProtoReflect().Descriptor().Name(), 304 }) 305 handler(pkt, ntc) 306 }) 307 if e != nil { 308 kiwi.TE3(pkt.Tid(), util.EcServiceErr, e) 309 } 310 } 311 312 func GlobalPrcNtc[Ntc util.IMsg](pkt kiwi.IRcvNotice, handler func(kiwi.IRcvNotice, Ntc)) { 313 pkt.SetWorker(kiwi.EWorkerGlobal, "") 314 worker.Global().Push(func(params []any) { 315 pkt, handler := util.SplitSlc2[kiwi.IRcvNotice, func(kiwi.IRcvNotice, Ntc)](params) 316 ntc := pkt.Msg().(Ntc) 317 kiwi.TI(pkt.Tid(), "notice", util.M{ 318 "ntc": ntc, 319 "name": ntc.ProtoReflect().Descriptor().Name(), 320 }) 321 handler(pkt, ntc) 322 }, pkt, handler) 323 } 324 325 func SelfPrcNtc[Ntc util.IMsg](pkt kiwi.IRcvNotice, handler func(kiwi.IRcvNotice, Ntc)) { 326 pkt.SetWorker(kiwi.EWorkerSelf, "") 327 ntc := pkt.Msg().(Ntc) 328 kiwi.TI(pkt.Tid(), "notice", util.M{ 329 "ntc": ntc, 330 "name": ntc.ProtoReflect().Descriptor().Name(), 331 }) 332 handler(pkt, ntc) 333 } 334 335 var ( 336 _MsgNameToSvcCode = map[string]kiwi.TSvcCode{} 337 ) 338 339 func BindMsgToSvcCode(msg util.IMsg, svc kiwi.TSvc, code kiwi.TCode) { 340 fullName := msg.ProtoReflect().Descriptor().Name() 341 _MsgNameToSvcCode[string(fullName)] = kiwi.MergeSvcCode(svc, code) 342 } 343 344 func MsgToSvcCode(msg util.IMsg) (svc kiwi.TSvc, code kiwi.TCode, ok bool) { 345 fullName := msg.ProtoReflect().Descriptor().Name() 346 sm, ok := _MsgNameToSvcCode[string(fullName)] 347 if !ok { 348 return 349 } 350 svc, code = kiwi.SplitSvcCode(sm) 351 return 352 }