func SentinelClientMiddleware()

in pkg/adapters/kitex/client.go [23:68]


func SentinelClientMiddleware(opts ...Option) func(endpoint.Endpoint) endpoint.Endpoint {
	options := newOptions(opts)
	return func(next endpoint.Endpoint) endpoint.Endpoint {
		return func(ctx context.Context, req, resp interface{}) error {
			if !options.EnableOutlier(ctx) {
				resourceName := options.ResourceExtract(ctx, req, resp)
				entry, blockErr := sentinel.Entry(
					resourceName,
					sentinel.WithResourceType(base.ResTypeRPC),
					sentinel.WithTrafficType(base.Outbound),
				)
				if blockErr != nil {
					return options.BlockFallback(ctx, req, resp, blockErr)
				}
				defer entry.Exit()
				err := next(ctx, req, resp)
				if err != nil {
					sentinel.TraceError(entry, err)
				}
				return err
			} else { // returns new client middleware specifically for outlier ejection.
				slotChain := sentinel.BuildDefaultSlotChain()
				slotChain.AddRuleCheckSlot(outlier.DefaultSlot)
				slotChain.AddStatSlot(outlier.DefaultMetricStatSlot)
				resourceName := ServiceNameExtract(ctx)
				entry, _ := sentinel.Entry(
					resourceName,
					sentinel.WithResourceType(base.ResTypeRPC),
					sentinel.WithTrafficType(base.Outbound),
					sentinel.WithSlotChain(slotChain),
				)
				defer entry.Exit()
				filterNodes = entry.Context().FilterNodes()
				halfNodes = entry.Context().HalfOpenNodes()
				err := next(ctx, req, resp)
				if callee := CalleeAddressExtract(ctx); callee != "" {
					sentinel.TraceCallee(entry, callee)
					if err != nil {
						sentinel.TraceError(entry, err)
					}
				}
				return err
			}
		}
	}
}