Como lançar uma exceção em uma função de outro segmento?

baal_imago:

Eu encontrei um problema muito estranho: Basicamente, eu estou implementando um servidor de streaming de cliente grpc em java e estou usando microprofiles como biblioteca / estrutura. Microprofiles tem interceptores muito útil quando se trata de tentativas automáticas e fallback, mas é dependente de exceções sendo lançadas na função anotada intercepção, caso contrário, as tentativas não estão sendo acionados.

Para chamadas grpc unnary, isso funciona muito bem, ele funciona de forma muito semelhante a uma chamada RESTO comum. Mas ao fazer um cliente para fluxo lado do servidor grpc, protobuf irá criar a sua própria linha e pedir um retorno de chamada para lidar com OnNext, onError e OnCompleted. Então, quando onError é chamado no âmbito fluxo, qualquer exceção lançada não será enviado de volta para qualquer função foi utilizada para iniciar o fluxo, então não há exceções lançadas para acionar o @Retry.

Não é possível alterar a forma como o fluxo assíncrono é tratada e não é possível alterar a forma como o @Retry está sendo acionado. Grpc é gerado código, e o gatilho @Retry é baseado na biblioteca microprofile.

Exemplo:

  @Retry(
          retryOn = {IOException.class, TimeoutException.class, StatusRuntimeException.class},
          maxDuration = 10,
          durationUnit =  ChronoUnit.SECONDS,
          maxRetries = 1,
          delay = 10,
          delayUnit = ChronoUnit.SECONDS
  )
  public void subscribeToLocations() {
    // --> Throwing an exception here triggers the @Retry <--
    SubscribeRequest locSubscribeRequest = SubscribeRequest.newBuilder().build();
    streamObserver = grpcStreamHandler();
    grpcBlockingstub.subscribeServerStreaming(locSubscribeRequest, streamObserver); // Can't change this.
  }

  private StreamObserver<SubscribeResponse> grpcStreamHandler() {
    return new StreamObserver<SubscribeResponse>() {
      @Override
      public void onNext(SubscribeResponse value) {
        // Handle grpc response
      }

      @Override
      public void onError(Throwable t) {
        // --> ERROR: Here, it should trigger the @Retry somehow. <--
      }

      @Override
      public void onCompleted() {
        // Handle oncomplete
      }
    };
  }

Eu tentei encontrar uma solução para isso por mais tempo do que gostaria de admitir, mas ainda estou em uma perda. Existe uma maneira para lançar uma exceção em um escopo que acaba em outro? Existe alguma outra solução?

udalmik:

Você misturar operações de sincronização e assíncronos aqui, então você precisa definir claramente o que é "sucesso" para você e você não precisa de uma nova tentativa levantada. Ele pode depender de sua lógica, poucas opções com fluxo contínuo:

  • Pelo menos uma atualização para OnNext recebeu, conclusão, em seguida, ou erro
  • OnCompleted recebido com ou sem nenhuma atualização
  • etc

Uma vez que você definir a regra de "sucesso", você pode envolver inscrição em futuro e esperar por ele para ser resolvido com limite de tempo fornecido. Se não for resolvido, então jogue Exceção de invocação originais.

Acho que você gosta

Origin http://43.154.161.224:23101/article/api/json?id=373367&siteId=1
Recomendado
Clasificación