Repository: cloudwego/kitex
File: server/server.go (Go)

Code before:
		if s.opt.StatsLevel != nil {
			rpcStats.SetLevel(*s.opt.StatsLevel)
		}

		// Export read-only views to external users and keep a mapping for internal users.
		ri = rpcinfo.NewRPCInfo(
			rpcinfo.EmptyEndpointInfo(),
			rpcinfo.FromBasicInfo(s.opt.Svr),
			rpcinfo.NewServerInvocation(),
			rpcinfo.AsMutableRPCConfig(s.opt.Configs).Clone().ImmutableView(),
			rpcStats.ImmutableView(),
		)
		rpcinfo.AsMutableEndpointInfo(ri.From()).SetAddress(rAddr)
		return ri
	}
}

func (s *server) buildInvokeChain() {
	innerHandlerEp := s.invokeHandleEndpoint()
	s.eps = endpoint.Chain(s.mws...)(innerHandlerEp)
}

// RegisterService should not be called by users directly.
func (s *server) RegisterService(svcInfo *serviceinfo.ServiceInfo, handler interface{}) error {
	if svcInfo == nil {
		return errors.New("svcInfo is nil. please specify non-nil svcInfo")
	}
	if handler == nil || reflect.ValueOf(handler).IsNil() {
		return errors.New("handler is nil. please specify non-nil handler")
	}
	if s.svcMap[svcInfo.ServiceName] != nil {
		panic(fmt.Sprintf("Service[%s] is already defined", svcInfo.ServiceName))
	}
	s.Lock()
	svc := serviceinfo.NewService(svcInfo, handler)
	s.svcMap[svcInfo.ServiceName] = &svc
	s.Unlock()
	diagnosis.RegisterProbeFunc(s.opt.DebugService, diagnosis.ServiceInfoKey, diagnosis.WrapAsProbeFunc(s.svcMap[svcInfo.ServiceName].GetServiceInfo()))
	return nil
}

func (s *server) GetServices() map[string]*serviceinfo.Service {
	return s.svcMap
}

// Run runs the server.
func (s *server) Run() (err error) {
	if err = s.check(); err != nil {
		return err
	}
	svrCfg := s.opt.RemoteOpt

Review comment (suggestion):
I think no need to judge whether svcInfo or handler is nil, just panic if user pass a nil svcInfo or handler.

Code after:
		rpcStats := rpcinfo.AsMutableRPCStats(rpcinfo.NewRPCStats())
		if s.opt.StatsLevel != nil {
			rpcStats.SetLevel(*s.opt.StatsLevel)
		}

		// Export read-only views to external users and keep a mapping for internal users.
		ri = rpcinfo.NewRPCInfo(
			rpcinfo.EmptyEndpointInfo(),
			rpcinfo.FromBasicInfo(s.opt.Svr),
			rpcinfo.NewServerInvocation(),
			rpcinfo.AsMutableRPCConfig(s.opt.Configs).Clone().ImmutableView(),
			rpcStats.ImmutableView(),
		)
		rpcinfo.AsMutableEndpointInfo(ri.From()).SetAddress(rAddr)
		return ri
	}
}

func (s *server) buildInvokeChain() {
	innerHandlerEp := s.invokeHandleEndpoint()
	s.eps = endpoint.Chain(s.mws...)(innerHandlerEp)
}

// RegisterService should not be called by users directly.
func (s *server) RegisterService(svcInfo *serviceinfo.ServiceInfo, handler interface{}) error {
	s.Lock()
	defer s.Unlock()
	if s.isRun {
		panic("service cannot be registered while server is running")
	}
	if svcInfo == nil {
		panic("svcInfo is nil. please specify non-nil svcInfo")
	}
	if handler == nil || reflect.ValueOf(handler).IsNil() {
		panic("handler is nil. please specify non-nil handler")
	}
	if s.svcs.getService(svcInfo.ServiceName) != nil {
		panic(fmt.Sprintf("Service[%s] is already defined", svcInfo.ServiceName))
	}

	s.svcs.addService(svcInfo, handler)
	return nil
}

func (s *server) GetServiceInfos() map[string]*serviceinfo.ServiceInfo {
	return s.svcs.getSvcInfoMap()
}

// Run runs the server.
func (s *server) Run() (err error) {
	s.Lock()