123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- package mhayaActor
- import (
- "reflect"
- "google.golang.org/protobuf/proto"
- ccode "github.com/mhaya/code"
- cerror "github.com/mhaya/error"
- creflect "github.com/mhaya/extend/reflect"
- cutils "github.com/mhaya/extend/utils"
- cfacade "github.com/mhaya/facade"
- clog "github.com/mhaya/logger"
- cproto "github.com/mhaya/net/proto"
- )
- func InvokeLocalFunc(app cfacade.IApplication, fi *creflect.FuncInfo, m *cfacade.Message) {
- if app == nil {
- clog.Errorf("[InvokeLocalFunc] app is nil. [message = %+v]", m)
- return
- }
- EncodeLocalArgs(app, fi, m)
- values := make([]reflect.Value, 2)
- values[0] = reflect.ValueOf(m.Session) // session
- values[1] = reflect.ValueOf(m.Args) // args
- fi.Value.Call(values)
- }
- func InvokeRemoteFunc(app cfacade.IApplication, fi *creflect.FuncInfo, m *cfacade.Message) {
- if app == nil {
- clog.Errorf("[InvokeRemoteFunc] app is nil. [message = %+v]", m)
- return
- }
- EncodeRemoteArgs(app, fi, m)
- values := make([]reflect.Value, fi.InArgsLen)
- if fi.InArgsLen > 0 {
- values[0] = reflect.ValueOf(m.Args) // args
- }
- if m.IsCluster {
- cutils.Try(func() {
- rets := fi.Value.Call(values)
- rspCode, rspData := retValue(app.Serializer(), rets)
- retResponse(m.ClusterReply, &cproto.Response{
- Code: rspCode,
- Data: rspData,
- })
- }, func(errString string) {
- retResponse(m.ClusterReply, &cproto.Response{
- Code: ccode.RPCRemoteExecuteError,
- })
- clog.Errorf("[InvokeRemoteFunc] invoke error. [message = %+v, err = %s]", m, errString)
- })
- } else {
- cutils.Try(func() {
- if m.ChanResult == nil {
- fi.Value.Call(values)
- } else {
- rets := fi.Value.Call(values)
- rspCode, rspData := retValue(app.Serializer(), rets)
- m.ChanResult <- &cproto.Response{
- Code: rspCode,
- Data: rspData,
- }
- }
- }, func(errString string) {
- if m.ChanResult != nil {
- m.ChanResult <- nil
- }
- clog.Errorf("[remote] invoke error.[source = %s, target = %s -> %s, funcType = %v, err = %+v]",
- m.Source,
- m.Target,
- m.FuncName,
- fi.InArgs,
- errString,
- )
- })
- }
- }
- func EncodeRemoteArgs(app cfacade.IApplication, fi *creflect.FuncInfo, m *cfacade.Message) error {
- if m.IsCluster {
- if fi.InArgsLen == 0 {
- return nil
- }
- return EncodeArgs(app, fi, 0, m)
- }
- return nil
- }
- func EncodeLocalArgs(app cfacade.IApplication, fi *creflect.FuncInfo, m *cfacade.Message) error {
- return EncodeArgs(app, fi, 1, m)
- }
- func EncodeArgs(app cfacade.IApplication, fi *creflect.FuncInfo, index int, m *cfacade.Message) error {
- argBytes, ok := m.Args.([]byte)
- if !ok {
- return cerror.Errorf("Encode args error.[source = %s, target = %s -> %s, funcType = %v]",
- m.Source,
- m.Target,
- m.FuncName,
- fi.InArgs,
- )
- }
- argValue := reflect.New(fi.InArgs[index].Elem()).Interface()
- err := app.Serializer().Unmarshal(argBytes, argValue)
- if err != nil {
- return cerror.Errorf("Encode args unmarshal error.[source = %s, target = %s -> %s, funcType = %v]",
- m.Source,
- m.Target,
- m.FuncName,
- fi.InArgs,
- )
- }
- m.Args = argValue
- return nil
- }
- func retValue(serializer cfacade.ISerializer, rets []reflect.Value) (int32, []byte) {
- var (
- retsLen = len(rets)
- rspCode = ccode.OK
- rspData []byte
- )
- if retsLen == 1 {
- if val := rets[0].Interface(); val != nil {
- if c, ok := val.(int32); ok {
- rspCode = c
- }
- }
- } else if retsLen == 2 {
- if !rets[0].IsNil() {
- data, err := serializer.Marshal(rets[0].Interface())
- if err != nil {
- rspCode = ccode.RPCRemoteExecuteError
- clog.Warn(err)
- } else {
- rspData = data
- }
- }
- if val := rets[1].Interface(); val != nil {
- if c, ok := val.(int32); ok {
- rspCode = c
- }
- }
- }
- return rspCode, rspData
- }
- func retResponse(reply cfacade.IRespond, rsp *cproto.Response) {
- if reply != nil {
- rspData, _ := proto.Marshal(rsp)
- err := reply.Respond(rspData)
- if err != nil {
- clog.Warn(err)
- }
- }
- }
|