Установите порядок выполнения для gRP C ServerInterceptors - PullRequest
2 голосов
/ 26 мая 2020

В io.grp c .internal.AbstractServerImplBuilder вы можете добавить реализации ServerInterceptor в окончательный список

final List<ServerInterceptor> interceptors = new ArrayList<>();

, затем в реализации сервера по умолчанию для построителя - io.grp c. internal.ServerImpl он вызывает их в foreach l oop

/** Never returns {@code null}. */
private <ReqT, RespT> ServerStreamListener startCall(ServerStream stream, String fullMethodName,
    ServerMethodDefinition<ReqT, RespT> methodDef, Metadata headers,
    Context.CancellableContext context, StatsTraceContext statsTraceCtx, Tag tag) {
  // TODO(ejona86): should we update fullMethodName to have the canonical path of the method?
  statsTraceCtx.serverCallStarted(
      new ServerCallInfoImpl<>(
          methodDef.getMethodDescriptor(), // notify with original method descriptor
          stream.getAttributes(),
          stream.getAuthority()));
  ServerCallHandler<ReqT, RespT> handler = methodDef.getServerCallHandler();
  for (ServerInterceptor interceptor : interceptors) {
    handler = InternalServerInterceptors.interceptCallHandler(interceptor, handler);
  }
  ServerMethodDefinition<ReqT, RespT> interceptedDef = methodDef.withServerCallHandler(handler);
  ServerMethodDefinition<?, ?> wMethodDef = binlog == null
      ? interceptedDef : binlog.wrapMethodDefinition(interceptedDef);
  return startWrappedCall(fullMethodName, wMethodDef, stream, headers, context, tag);
}

, поэтому он выполняет цепочку перехватчиков от последнего зарегистрированного до первого при получении запроса. Такой же порядок соблюдается при ответе обработчика.

Что я удивляюсь и ожидаю, так это то, что он будет следовать шаблону промежуточного программного обеспечения лука, и вы можете явно установить порядок выполнения (аналогично фильтрам сервлетов). Я что-то упускаю?

1 Ответ

0 голосов
/ 11 июня 2020

Нет возможности выставить заказ. ServerBuilder.intercept() - это удобная версия ServerInterceptors.intercept(), которая следует той же семантике. Существует ServerInterceptors.interceptForward(), который запускает их в противоположном направлении, но у вас не может быть API, который добавляет перехватчики по отдельности и поддерживает обе формы одновременно.

API перехвата немного сбивает с толку, потому что он делает следовать принципу лука, но лук находится около службы . Перехватчики обертывают сервис , и поэтому последний примененный перехватчик выполняется первым.

serviceDef = ServerInterceptors.intercept(serviceDef,
    interceptor1,
    interceptor2,
    interceptor3);

// is equivalent to

serviceDef = ServerInterceptors.intercept(serviceDef, interceptor1);
serviceDef = ServerInterceptors.intercept(serviceDef, interceptor2);
serviceDef = ServerInterceptors.intercept(serviceDef, interceptor3);
// the gRPC server sees the last 'serviceDef', so interceptor3 is
// called first
...