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  }