github.com/cloudwego/kitex@v0.9.0/pkg/serviceinfo/serviceinfo.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 serviceinfo
    18  
    19  import (
    20  	"context"
    21  )
    22  
    23  // PayloadCodec alias type
    24  type PayloadCodec int
    25  
    26  // PayloadCodec supported by kitex.
    27  const (
    28  	Thrift PayloadCodec = iota
    29  	Protobuf
    30  	Hessian2
    31  )
    32  
    33  const (
    34  	// GenericService name
    35  	GenericService = "$GenericService" // private as "$"
    36  	// GenericMethod name
    37  	GenericMethod = "$GenericCall"
    38  )
    39  
    40  // ServiceInfo to record meta info of service
    41  type ServiceInfo struct {
    42  	// deprecated, for compatibility
    43  	PackageName string
    44  
    45  	// The name of the service. For generic services, it is always the constant `GenericService`.
    46  	ServiceName string
    47  
    48  	// HandlerType is the type value of a request handler from the generated code.
    49  	HandlerType interface{}
    50  
    51  	// Methods contains the meta information of methods supported by the service.
    52  	// For generic service, there is only one method named by the constant `GenericMethod`.
    53  	Methods map[string]MethodInfo
    54  
    55  	// PayloadCodec is the codec of payload.
    56  	PayloadCodec PayloadCodec
    57  
    58  	// KiteXGenVersion is the version of command line tool 'kitex'.
    59  	KiteXGenVersion string
    60  
    61  	// Extra is for future feature info, to avoid compatibility issue
    62  	// as otherwise we need to add a new field in the struct
    63  	Extra map[string]interface{}
    64  
    65  	// GenericMethod returns a MethodInfo for the given name.
    66  	// It is used by generic calls only.
    67  	GenericMethod func(name string) MethodInfo
    68  }
    69  
    70  // GetPackageName returns the PackageName.
    71  // The return value is generally taken from the Extra field of ServiceInfo with a key
    72  // `PackageName`. For some legacy generated code, it may come from the PackageName field.
    73  func (i *ServiceInfo) GetPackageName() (pkg string) {
    74  	if i.PackageName != "" {
    75  		return i.PackageName
    76  	}
    77  	pkg, _ = i.Extra["PackageName"].(string)
    78  	return
    79  }
    80  
    81  // MethodInfo gets MethodInfo.
    82  func (i *ServiceInfo) MethodInfo(name string) MethodInfo {
    83  	if i == nil {
    84  		return nil
    85  	}
    86  	if i.ServiceName == GenericService {
    87  		if i.GenericMethod != nil {
    88  			return i.GenericMethod(name)
    89  		}
    90  		return i.Methods[GenericMethod]
    91  	}
    92  	return i.Methods[name]
    93  }
    94  
    95  type StreamingMode int
    96  
    97  const (
    98  	StreamingNone          StreamingMode = 0b0000 // KitexPB/KitexThrift
    99  	StreamingUnary         StreamingMode = 0b0001 // underlying protocol for streaming, like HTTP2
   100  	StreamingClient        StreamingMode = 0b0010
   101  	StreamingServer        StreamingMode = 0b0100
   102  	StreamingBidirectional StreamingMode = 0b0110
   103  )
   104  
   105  // MethodInfo to record meta info of unary method
   106  type MethodInfo interface {
   107  	Handler() MethodHandler
   108  	NewArgs() interface{}
   109  	NewResult() interface{}
   110  	OneWay() bool
   111  	IsStreaming() bool
   112  	StreamingMode() StreamingMode
   113  }
   114  
   115  // MethodHandler is corresponding to the handler wrapper func that in generated code
   116  type MethodHandler func(ctx context.Context, handler, args, result interface{}) error
   117  
   118  // MethodInfoOption modifies the given MethodInfo
   119  type MethodInfoOption func(*methodInfo)
   120  
   121  // WithStreamingMode sets the streaming mode and update the streaming flag accordingly
   122  func WithStreamingMode(mode StreamingMode) MethodInfoOption {
   123  	return func(m *methodInfo) {
   124  		m.streamingMode = mode
   125  		m.isStreaming = mode != StreamingNone
   126  	}
   127  }
   128  
   129  // NewMethodInfo is called in generated code to build method info
   130  func NewMethodInfo(methodHandler MethodHandler, newArgsFunc, newResultFunc func() interface{}, oneWay bool, opts ...MethodInfoOption) MethodInfo {
   131  	mi := methodInfo{
   132  		handler:       methodHandler,
   133  		newArgsFunc:   newArgsFunc,
   134  		newResultFunc: newResultFunc,
   135  		oneWay:        oneWay,
   136  		isStreaming:   false,
   137  		streamingMode: StreamingNone,
   138  	}
   139  	for _, opt := range opts {
   140  		opt(&mi)
   141  	}
   142  	return &mi
   143  }
   144  
   145  type methodInfo struct {
   146  	handler       MethodHandler
   147  	newArgsFunc   func() interface{}
   148  	newResultFunc func() interface{}
   149  	oneWay        bool
   150  	isStreaming   bool
   151  	streamingMode StreamingMode
   152  }
   153  
   154  // Handler implements the MethodInfo interface.
   155  func (m methodInfo) Handler() MethodHandler {
   156  	return m.handler
   157  }
   158  
   159  // NewArgs implements the MethodInfo interface.
   160  func (m methodInfo) NewArgs() interface{} {
   161  	return m.newArgsFunc()
   162  }
   163  
   164  // NewResult implements the MethodInfo interface.
   165  func (m methodInfo) NewResult() interface{} {
   166  	return m.newResultFunc()
   167  }
   168  
   169  // OneWay implements the MethodInfo interface.
   170  func (m methodInfo) OneWay() bool {
   171  	return m.oneWay
   172  }
   173  
   174  func (m methodInfo) IsStreaming() bool {
   175  	return m.isStreaming
   176  }
   177  
   178  func (m methodInfo) StreamingMode() StreamingMode {
   179  	return m.streamingMode
   180  }
   181  
   182  // String prints human-readable information.
   183  func (p PayloadCodec) String() string {
   184  	switch p {
   185  	case Thrift:
   186  		return "Thrift"
   187  	case Protobuf:
   188  		return "Protobuf"
   189  	case Hessian2:
   190  		return "Hessian2"
   191  	}
   192  	panic("unknown payload type")
   193  }