github.com/cloudwego/kitex@v0.9.0/server/invoke.go (about)

     1  /*
     2   * Copyright 2021 CloudWeGo Authors
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  package server
    18  
    19  // Invoker is for calling handler function wrapped by Kitex suites without connection.
    20  
    21  import (
    22  	"errors"
    23  
    24  	internal_server "github.com/cloudwego/kitex/internal/server"
    25  	"github.com/cloudwego/kitex/pkg/remote"
    26  	"github.com/cloudwego/kitex/pkg/remote/bound"
    27  	"github.com/cloudwego/kitex/pkg/remote/trans/invoke"
    28  	"github.com/cloudwego/kitex/pkg/serviceinfo"
    29  )
    30  
    31  // InvokeCaller is the abstraction for invoker call.
    32  type InvokeCaller interface {
    33  	Call(invoke.Message) error
    34  }
    35  
    36  // Invoker is the abstraction for invoker.
    37  type Invoker interface {
    38  	RegisterService(svcInfo *serviceinfo.ServiceInfo, handler interface{}, opts ...RegisterOption) error
    39  	Init() (err error)
    40  	InvokeCaller
    41  }
    42  
    43  type tInvoker struct {
    44  	invoke.Handler
    45  	*server
    46  }
    47  
    48  // NewInvoker creates new Invoker.
    49  func NewInvoker(opts ...Option) Invoker {
    50  	s := &server{
    51  		opt:  internal_server.NewOptions(opts),
    52  		svcs: newServices(),
    53  	}
    54  	s.init()
    55  	return &tInvoker{
    56  		server: s,
    57  	}
    58  }
    59  
    60  // Init does initialization job for invoker.
    61  func (s *tInvoker) Init() (err error) {
    62  	if len(s.server.svcs.svcMap) == 0 {
    63  		return errors.New("run: no service. Use RegisterService to set one")
    64  	}
    65  	s.initBasicRemoteOption()
    66  	// for server trans info handler
    67  	if len(s.server.opt.MetaHandlers) > 0 {
    68  		transInfoHdlr := bound.NewTransMetaHandler(s.server.opt.MetaHandlers)
    69  		doAddBoundHandler(transInfoHdlr, s.server.opt.RemoteOpt)
    70  	}
    71  	s.Lock()
    72  	s.Handler, err = s.newInvokeHandler()
    73  	s.Unlock()
    74  	if err != nil {
    75  		return err
    76  	}
    77  	for i := range onServerStart {
    78  		go onServerStart[i]()
    79  	}
    80  	return nil
    81  }
    82  
    83  // Call implements the InvokeCaller interface.
    84  func (s *tInvoker) Call(msg invoke.Message) error {
    85  	return s.Handler.Call(msg)
    86  }
    87  
    88  func (s *tInvoker) newInvokeHandler() (handler invoke.Handler, err error) {
    89  	opt := s.server.opt.RemoteOpt
    90  	tf := invoke.NewIvkTransHandlerFactory()
    91  	hdlr, err := tf.NewTransHandler(opt)
    92  	if err != nil {
    93  		return nil, err
    94  	}
    95  	hdlr.(remote.InvokeHandleFuncSetter).SetInvokeHandleFunc(s.eps)
    96  	pl := remote.NewTransPipeline(hdlr)
    97  	hdlr.SetPipeline(pl)
    98  	for _, ib := range opt.Inbounds {
    99  		pl.AddInboundHandler(ib)
   100  	}
   101  	for _, ob := range opt.Outbounds {
   102  		pl.AddOutboundHandler(ob)
   103  	}
   104  	return invoke.NewIvkHandler(opt, pl)
   105  }