kitc执行流程分析

最近阅读了RPC框架kitc的部分源码,kitc是kite框架的客户端实现,kite框架是公司内部基于开源的thrift封装二次开发的,与开源的kite框架并不一样。kitc 的执行过程也是中间件调用链的执行过程。

对目标接口方法进行封装
// client端调用目标接口的方法,由工具根据接口定义自动生成
func (p *ExampleServiceClient) Method1(req *ExampleRequest) (r *ExampleResponse, err error) {
  if err = p.sendMethod1(req); err != nil { return }
   return p.recvMethod1()
 }
 
 // EndPoint represent one method for calling from remote.
 // EndPoint 代表一个远端方法的调用过程
type EndPoint func(ctx context.Context, req interface{}) (resp interface{}, err error)

// 对目标接口方法进行封装,封装为endpoint.EndPoint类型
func mkMethod1(client *example.ExampleServiceClient) endpoint.EndPoint {
     return func(ctx context.Context, request interface{}) (interface{}, error) {
         transport := client.Transport.(kitc.Transport)
         err := transport.OpenWithContext(ctx)
         if err != nil {...}
         defer transport.Close()
         // Method1为proto文件中定义的服务接口 
         resp, err := client.Method1(request.(endpoint.KitcCallRequest).RealRequest().(*example.ExampleRequest))
         addr := transport.RemoteAddr()
         return &KitcExampleResponse{resp, addr}, err
     }
 }
kitc中间件的定义
// Middleware deal with input EndPoint and output EndPoint
// 输入为EndPoint类型,输出为EndPoint类型
type Middleware func(EndPoint) EndPoint

// client端执行目标接口方法调用
func (c *Client) Method1(ctx context.Context, r *example.ExampleRequest) (*KitcExampleResponse, error) {
     kc := c.client
     if kc == nil {...}
     // 中间件的初始化
     **ctx, err := kc.MethodInit("Method1", ctx, r)**  @1
     if err != nil {...}
     client := GetExampleServiceClient(kc)
     **next := mkMethod1(client)**
     request := &KiteExampleRequest{r}
     **resp, err := kc.MethodCall(next, ctx, request)** @2
     kitcResp, ok := resp.(*KitcExampleResponse)
     if !ok {...}
     return kitcResp, err
 }

// @1 处的代码
func (kc *KitcClient) MethodInit(method string, ctx context.Context, request interface{}) (context.Context, error) {
     metricsClient.EmitCounter("kite.request.throughput", 1)
     // 初始化中间件调用链,包含服务发现中间件,负载均衡中间件, 连接池中间件等等
     kc.once.Do(kc.initMWChain)
     // 因为request会被生成代码包裹,
     // 如果用户使用了自定义的LB, 需要保证直接把最原始的req传递给用户
     ctx = context.WithValue(ctx, KITC_RAW_REQUEST_KEY, request)
     return kc.initRPCInfo(method, ctx)
 }

// @2 处的代码
func (kc *KitcClient) MethodCall(next endpoint.EndPoint, ctx context.Context, request interface{}) (endpoint.KitcCallResponse, error) {
    ......
    // kc.chain(next)执行中间件调用链,生成一个EndPoint类型,然后执行EndPoint方法
    // 如此就完成了目标接口方法的调用
     resp, err := kc.chain(next)(ctx, request)
     if _, ok := resp.(endpoint.KitcCallResponse); !ok {...}
     return resp.(endpoint.KitcCallResponse), err
}
怎么改{ "extensions.ignoreRecommendations": true, "explorer.confirmDragAndDrop": false, "explorer.confirmDelete": false, "security.workspace.trust.untrustedFiles": "open", "workbench.editor.enablePreview": false, "files.autoSave": "afterDelay", "editor.fontSize": 22, "workbench.commandPalette.experimental.suggestCommands": true, "code-runner.executorMap": { "javascript": "node", "java": "cd $dir && javac $fileName && java $fileNameWithoutExt", "c": "cd $dir && gcc $fileName -o $fileNameWithoutExt && $dir$fileNameWithoutExt", "zig": "zig run", "cpp": "cd $dir && g++ $fileName -o $fileNameWithoutExt && $dir$fileNameWithoutExt", "objective-c": "cd $dir && gcc -framework Cocoa $fileName -o $fileNameWithoutExt && $dir$fileNameWithoutExt", "php": "php", "python": "python -u", "perl": "perl", "perl6": "perl6", "ruby": "ruby", "go": "go run", "lua": "lua", "groovy": "groovy", "powershell": "powershell -ExecutionPolicy ByPass -File", "bat": "cmd /c", "shellscript": "bash", "fsharp": "fsi", "csharp": "scriptcs", "vbscript": "cscript //Nologo", "typescript": "ts-node", "coffeescript": "coffee", "scala": "scala", "swift": "swift", "julia": "julia", "crystal": "crystal", "ocaml": "ocaml", "r": "Rscript", "applescript": "osascript", "clojure": "lein exec", "haxe": "haxe --cwd $dirWithoutTrailingSlash --run $fileNameWithoutExt", "rust": "cd $dir && rustc $fileName && $dir$fileNameWithoutExt", "racket": "racket", "scheme": "csi -script", "ahk": "autohotkey", "autoit": "autoit3", "dart": "dart", "pascal": "cd $dir && fpc $fileName && $dir$fileNameWithoutExt", "d": "cd $dir && dmd $fileName && $dir$fileNameWithoutExt", "haskell": "runghc", "nim": "nim compile --verbosity:0 --hints:off --run", "lisp": "sbcl --script", "kit": "kitc --run", "v": "v run", "sass": "sass --style expanded", "scss": "scss --style expanded", "less": "cd $dir && lessc $fileName $fileNameWithoutExt.css", "FortranFreeForm": "cd $dir && gfortran $fileName -o $fileNameWithoutExt && $dir$fileNameWithoutExt", "fortran-modern": "cd $dir && gfortran $fileName -o $fileNameWithoutExt && $dir$fileNameWithoutExt", "fortran_fixed-form": "cd $dir && gfortran $fileName -o $fileNameWithoutExt && $dir$fileNameWithoutExt", "fortran": "cd $dir && gfortran $fileName -o $fileNameWithoutExt && $dir$fileNameWithoutExt", "sml": "cd $dir && sml $fileName", "mojo": "mojo run", "erlang": "escript", "spwn": "spwn build", "pkl": "cd $dir && pkl eval -f yaml $fileName -o $fileNameWithoutExt.yaml", "gleam": "gleam run -m $fileNameWithoutExt" } }
03-21
资源下载链接为: https://pan.quark.cn/s/fe886b97b3d0 “CSDN-中文IT社区-600万.rar” 这个文件名称表明它与CSDN(中国软件开发者网络)有关,且包含600万份资源。CSDN作为中国最大的IT技术交流平台,覆盖了编程语言、软件开发、网络安全、大数据、云计算等多个领域的知识和资讯。该压缩包可能包含用户数据、文章、讨论话题或学习资料等。其内容可能极为丰富,涵盖大量用户生成内容,如博客文章、论坛帖子、问答记录等,对于研究IT行业趋势、开发者行为和技术热点等具有重要价值。尽管目前没有具体内容,但推测可能涉及“编程”“开发”“社区数据”“技术文章”“学习资源”等标签。 从文件名称来看,压缩包的内容可能包括以下几类:一是用户数据,如注册信息、活动记录、帖子和评论等,可用于分析用户行为和社区活跃度;二是技术文章和博客,涵盖众多技术专家分享的教程、解决方案和经验;三是源代码和项目,供其他开发者学习参考;四是论坛讨论,反映开发者关注的技术问题和热点;五是资源下载,如教程素材、工具软件、开发库等;六是会议和活动记录,包括报告、演讲稿和视频;七是学习路径和课程,帮助开发者提升技能;八是排行榜和奖项,体现社区的认可度和影响力。 “CSDN-中文IT社区-600万.rar” 压缩包可能是一个极具价值的IT知识宝库,涵盖从基础编程到高级技术实践的广泛主题,反映了中国IT社区的发展动态。对于IT从业者、研究人员以及编程爱好者来说,它是一个极具价值的学习和研究资源,能够帮助人们洞察开发者需求、技术趋势和社区变化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值