微服务拦截器
类似web服务当中的中间件
image.png

实现思路
将最终执行函数与拦截器通过一个相同的invoker来进行包装,并且通过递归来实现。

代码实现

package main

import (
	"context"
	"fmt"
)


type interceptor func(ctx context.Context, ivk invoker)error
type invoker func(ctx context.Context, interceptors []interceptor) error

func main() {
	var ctx context.Context
	var ceps []interceptor
	
	
	var inter1 = func(ctx context.Context, ivk invoker) error{
		fmt.Println("interceptor.")
		return ivk(ctx, ceps)
	}
	
	var inter2 = func(ctx context.Context, ivk invoker) error{
		fmt.Println("interceptor.")
		return ivk(ctx, ceps)
	}
	
	var ivk = func(ctx context.Context, interceptors []interceptor) error {
		fmt.Println("invoker start")
		return nil
	}
	
	ceps = append(ceps, inter1, inter2)
	cepChain := getCepChain(ctx, ceps, ivk)
	cepChain(ctx, ivk)
}

func getCepChain(ctx context.Context, interceptors []interceptor, ivk invoker) interceptor {
	if len(interceptors) == 0 {
		return nil
	}
	
	if len(interceptors) == 1 {
		return interceptors[0]
	}
	
	return func(ctx context.Context, ivk invoker) error{
		return interceptors[0](ctx, getInvoker(ctx, interceptors, 0, ivk))
	}
}

func getInvoker(ctx context.Context, interceptors []interceptor, cur int, ivk invoker) invoker {
	if cur == len(interceptors) - 1 {
		return ivk
	}
	
	return func(ctx context.Context, interceptors []interceptor) error {
		return interceptors[cur+1](ctx, getInvoker(ctx, interceptors, cur+1, ivk))
	}
}

执行结果

image.png