github.com/nyan233/littlerpc@v0.4.6-0.20230316182519-0c8d5c48abaf/core/server/server.go (about)

     1  package server
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"fmt"
     7  	"github.com/nyan233/littlerpc/core/common/sharedpool"
     8  	"net"
     9  	"reflect"
    10  	"sync"
    11  	"sync/atomic"
    12  	"unsafe"
    13  
    14  	"github.com/nyan233/littlerpc/core/common/inters"
    15  	"github.com/nyan233/littlerpc/core/common/logger"
    16  	"github.com/nyan233/littlerpc/core/common/metadata"
    17  	"github.com/nyan233/littlerpc/core/common/msgparser"
    18  	"github.com/nyan233/littlerpc/core/common/msgwriter"
    19  	"github.com/nyan233/littlerpc/core/common/stream"
    20  	transport2 "github.com/nyan233/littlerpc/core/common/transport"
    21  	"github.com/nyan233/littlerpc/core/common/utils/debug"
    22  	metaDataUtil "github.com/nyan233/littlerpc/core/common/utils/metadata"
    23  	"github.com/nyan233/littlerpc/core/container"
    24  	lerror "github.com/nyan233/littlerpc/core/protocol/error"
    25  	"github.com/nyan233/littlerpc/internal/pool"
    26  	reflect2 "github.com/nyan233/littlerpc/internal/reflect"
    27  )
    28  
    29  const (
    30  	_Stop    int64 = 1 << 3
    31  	_Start   int64 = 1 << 4
    32  	_Restart int64 = 1 << 6
    33  )
    34  
    35  type connSourceDesc struct {
    36  	Parser     msgparser.Parser
    37  	Writer     msgwriter.Writer
    38  	remoteAddr net.Addr
    39  	localAddr  net.Addr
    40  	cacheCtx   context.Context
    41  	ctxManager *contextManager
    42  }
    43  
    44  type Server struct {
    45  	//	Server 提供的所有服务, 一个服务即一个API
    46  	//	比如: /littlerpc/internal/reflection.GetHandler --> func (l *LittleRpcReflection) GetHandler(source string) MethodTable
    47  	services *container.RCUMap[string, *metadata.Process]
    48  	// Server 提供的所有资源, 一个资源即一组服务的集合
    49  	// 主要供reflection使用
    50  	sources *container.RCUMap[string, *metadata.Source]
    51  	// Server Engine
    52  	server transport2.ServerEngine
    53  	// 任务池
    54  	taskPool pool.TaskPool[string]
    55  	// logger
    56  	logger logger.LLogger
    57  	// 注册的插件的管理器
    58  	pManager *pluginManager
    59  	// Error Handler
    60  	eHandle lerror.LErrors
    61  	// Server Global Event
    62  	ev *event
    63  	// 初始信息
    64  	opts []Option
    65  	// 用于原子更新
    66  	config atomic.Pointer[Config]
    67  	pool   *sharedpool.SharedPool
    68  }
    69  
    70  func New(opts ...Option) *Server {
    71  	server := new(Server)
    72  	server.pool = sharedpool.NewSharedPool()
    73  	applyConfig(server, opts)
    74  	server.ev = newEvent()
    75  	server.services = container.NewRCUMap[string, *metadata.Process](128)
    76  	server.sources = container.NewRCUMap[string, *metadata.Source](128)
    77  	// init reflection service
    78  	err := server.RegisterClass(ReflectionSource, &LittleRpcReflection{server}, nil)
    79  	if err != nil {
    80  		panic(err)
    81  	}
    82  	return server
    83  }
    84  
    85  func applyConfig(server *Server, opts []Option) {
    86  	sc := &Config{}
    87  	WithDefaultServer()(sc)
    88  	for _, v := range opts {
    89  		v(sc)
    90  	}
    91  	server.config.Store(sc)
    92  	if sc.Logger != nil {
    93  		server.logger = sc.Logger
    94  	} else {
    95  		server.logger = logger.DefaultLogger
    96  	}
    97  	builder := transport2.Manager.GetServerEngine(sc.NetWork)(transport2.NetworkServerConfig{
    98  		Addrs:     sc.Address,
    99  		KeepAlive: sc.KeepAlive,
   100  		TLSPubPem: nil,
   101  	})
   102  	eventD := builder.EventDriveInter()
   103  	eventD.OnMessage(server.onMessage)
   104  	eventD.OnClose(server.onClose)
   105  	eventD.OnOpen(server.onOpen)
   106  	if sc.RegisterMPOnRead {
   107  		eventD.OnRead(server.onRead)
   108  	}
   109  	// server engine
   110  	server.server = builder.Server()
   111  	// init plugin manager
   112  	server.pManager = newPluginManager(sc.Plugins)
   113  	// init ErrorHandler
   114  	server.eHandle = sc.ErrHandler
   115  	// New TaskPool
   116  	if sc.ExecPoolBuilder != nil {
   117  		server.taskPool = sc.ExecPoolBuilder.Builder(
   118  			sc.PoolBufferSize, sc.PoolMinSize, sc.PoolMaxSize, debug.ServerRecover(server.logger))
   119  	} else {
   120  		server.taskPool = pool.NewTaskPool[string](
   121  			sc.PoolBufferSize, sc.PoolMinSize, sc.PoolMaxSize, debug.ServerRecover(server.logger))
   122  	}
   123  }
   124  
   125  func (s *Server) RegisterClass(source string, i interface{}, custom map[string]metadata.ProcessOption) error {
   126  	type Setup func(ptr unsafe.Pointer)
   127  	type SetupMethod struct {
   128  		typ  unsafe.Pointer
   129  		data Setup
   130  	}
   131  
   132  	if i == nil {
   133  		return errors.New("register elem is nil")
   134  	}
   135  	src := &metadata.Source{}
   136  	src.InstanceType = reflect.TypeOf(i)
   137  	value := reflect.ValueOf(i)
   138  	// 检查类型的名字是否正确
   139  	if name := reflect.Indirect(value).Type().Name(); name == "" {
   140  		return errors.New("the typ name is not defined")
   141  	} else if name != "" && source == "" {
   142  		source = name
   143  	}
   144  	// 检查是否有与该类型绑定的方法
   145  	if value.NumMethod() == 0 {
   146  		return errors.New("no bind receiver method")
   147  	}
   148  	// init map
   149  	src.ProcessSet = make(map[string]*metadata.Process, src.InstanceType.NumMethod())
   150  	rsType, rsIndex := s.scanRpcServer(src.InstanceType)
   151  	var setup Setup
   152  	for i := 0; i < src.InstanceType.NumMethod(); i++ {
   153  		method := src.InstanceType.Method(i)
   154  		if !method.IsExported() {
   155  			continue
   156  		}
   157  		// 检查是否重写了RpcServer.Setup方法
   158  		if rsType != nil {
   159  			switch method.Name {
   160  			case "Setup":
   161  				// setup = value.Method(i).Interface().(func())
   162  				// 如果使用以上方法设置setup func的debug时就看不见真正的执行代码
   163  				// reflect.Value.Interface()在遇到Func类型时会使用makeMethodValue构造一个满足匿名函数定义的函数
   164  				// 返回的函数不包含接收器, 可当成普通函数来使用, 运行时调用methodValueCall
   165  				// debug RegisterClass时就会看不见原始函数的代码
   166  				// 使用以下方式则不会, 因为获得的是原始的函数类型
   167  				setupFun := *(*SetupMethod)(unsafe.Pointer(&method.Func))
   168  				setup = setupFun.data
   169  				continue
   170  			case "HijackProcess":
   171  				continue
   172  			}
   173  		}
   174  		option, ok := custom[method.Name]
   175  		if !ok {
   176  			s.registerProcess(src, method.Name, value.Method(i), nil)
   177  		} else {
   178  			s.registerProcess(src, method.Name, value.Method(i), &option)
   179  		}
   180  	}
   181  	eValue := value
   182  	for eValue.Kind() == reflect.Ptr {
   183  		eValue = eValue.Elem()
   184  	}
   185  	if rsType != nil && eValue.Field(rsIndex).CanSet() {
   186  		eValue.Field(rsIndex).Set(reflect.ValueOf(RpcServer{
   187  			Prefix: source,
   188  			s:      s,
   189  		}))
   190  	}
   191  	s.sources.Store(source, src)
   192  	kvs := make([]container.RCUMapElement[string, *metadata.Process], 0, len(src.ProcessSet))
   193  	for k, v := range src.ProcessSet {
   194  		kvs = append(kvs, container.RCUMapElement[string, *metadata.Process]{
   195  			Key:   fmt.Sprintf("%s.%s", source, k),
   196  			Value: v,
   197  		})
   198  	}
   199  	s.services.StoreMulti(kvs)
   200  	if setup != nil {
   201  		// offset := eValue.Type().Field(rsIndex).Offset
   202  		// setup(unsafe.Pointer(uintptr(value.UnsafePointer()) + offset))
   203  		setup(value.UnsafePointer())
   204  	}
   205  	return nil
   206  }
   207  
   208  func (s *Server) registerProcess(src *metadata.Source, process string, processValue reflect.Value, option *metadata.ProcessOption) {
   209  	processDesc := &metadata.Process{
   210  		Value:  processValue,
   211  		Option: s.config.Load().DefaultProcessOption,
   212  	}
   213  	src.ProcessSet[process] = processDesc
   214  	if option != nil {
   215  		processDesc.Option = *option
   216  	}
   217  	// 一个参数都没有的话则不需要进行那些根据输入参数来调整的选项
   218  	if processValue.Type().NumIn() == 0 {
   219  		return
   220  	}
   221  	for j := 0; j < processValue.Type().NumIn(); j++ {
   222  		processDesc.ArgsType = append(processDesc.ArgsType, processValue.Type().In(j))
   223  	}
   224  	jOffset := metaDataUtil.IFContextOrStream(processDesc, processValue.Type())
   225  	if !processDesc.Option.CompleteReUsage {
   226  		goto asyncCheck
   227  	}
   228  	for j := 0 + jOffset; j < processValue.Type().NumIn(); j++ {
   229  		typ := processValue.Type().In(j)
   230  		if !typ.Implements(reflect.TypeOf((*inters.Reset)(nil)).Elem()) {
   231  			processDesc.Option.CompleteReUsage = false
   232  			goto asyncCheck
   233  		}
   234  	}
   235  	processDesc.Pool = sync.Pool{
   236  		New: func() interface{} {
   237  			inputs := reflect2.FuncInputTypeListReturnValue(processDesc.ArgsType, 0, func(i int) bool {
   238  				return false
   239  			}, true)
   240  			switch {
   241  			case processDesc.SupportContext && processDesc.SupportStream:
   242  				inputs[0] = reflect.ValueOf(context.Background())
   243  				inputs[1] = reflect.ValueOf(stream.LStream(nil))
   244  			}
   245  			return inputs
   246  		},
   247  	}
   248  asyncCheck:
   249  	if processDesc.Option.SyncCall {
   250  		// TODO nop
   251  	}
   252  	return
   253  }
   254  
   255  func (s *Server) scanRpcServer(typ reflect.Type) (reflect.Type, int) {
   256  	for typ.Kind() == reflect.Ptr {
   257  		typ = typ.Elem()
   258  	}
   259  	for i := 0; i < typ.NumField(); i++ {
   260  		field := typ.Field(i)
   261  		if !field.Anonymous {
   262  			continue
   263  		}
   264  		if field.Type.Kind() != reflect.Struct {
   265  			continue
   266  		}
   267  		if field.Type == reflect.TypeOf(RpcServer{}) {
   268  			return field.Type, i
   269  		}
   270  	}
   271  	return nil, -1
   272  }
   273  
   274  func (s *Server) RegisterAnonymousFunc(service string, fn interface{}, option *metadata.ProcessOption) error {
   275  	if service == "" {
   276  		return errors.New("service name is empty")
   277  	}
   278  	if reflect.TypeOf(fn).Kind() != reflect.Func {
   279  		return errors.New("register type not a function")
   280  	}
   281  	source, ok := s.sources.LoadOk(AnonymousSource)
   282  	if !ok {
   283  		return errors.New("source not found")
   284  	}
   285  	s.registerProcess(source, service, reflect.ValueOf(fn), option)
   286  	process := source.ProcessSet[service]
   287  	if process != nil {
   288  		return errors.New("register failed process is empty")
   289  	}
   290  	s.services.Store(fmt.Sprintf("%s.%s", AnonymousSource, service), process)
   291  	return nil
   292  }
   293  
   294  func (s *Server) Service() error {
   295  	s.ev.Entry(int(_Start))
   296  	return s.service()
   297  }
   298  
   299  func (s *Server) service() error {
   300  	err := s.server.Start()
   301  	if err != nil {
   302  		return err
   303  	}
   304  	done, ack, ok := s.ev.Wait()
   305  	if !ok {
   306  		return errors.New("wait event failed")
   307  	}
   308  	select {
   309  	case <-done:
   310  		defer ack()
   311  	}
   312  	err = s.server.Stop()
   313  	if err != nil {
   314  		return err
   315  	}
   316  	err = s.taskPool.Stop()
   317  	if err != nil {
   318  		return err
   319  	}
   320  	return nil
   321  }
   322  
   323  func (s *Server) Stop() error {
   324  	if !(s.ev.Complete(int(_Start)) || s.ev.Complete(int(_Restart))) {
   325  		return errors.New("server in unknown state")
   326  	}
   327  	return nil
   328  }
   329  
   330  // Restart TODO: 实现重启Server
   331  func (s *Server) Restart(override bool, opts ...Option) error {
   332  	if err := s.Stop(); err != nil {
   333  		return err
   334  	}
   335  	s.ev.Entry(int(_Restart))
   336  	if !override {
   337  		s.opts = append(s.opts, opts...)
   338  	} else {
   339  		s.opts = opts
   340  	}
   341  	applyConfig(s, s.opts)
   342  	return s.service()
   343  }