Cómo lanzar una excepción en una función de otro hilo?

baal_imago:

Me he encontrado con un problema muy extraño: Básicamente, estoy poniendo en práctica un servidor de streaming cliente GRPC en Java y estoy usando microprofiles como biblioteca / estructura. Microprofiles tiene interceptores muy útil cuando se trata de reintentos automáticos y de repliegue, pero es dependiente de excepciones que son lanzadas en la función de intercepción anotado, de lo contrario los reintentos no se activan.

Para las llamadas GRPC unnary, esto funciona muy bien, funciona de manera muy similar a una llamada REST ordinaria. Sin embargo, al hacer un cliente de flujo del lado del servidor GRPC, protobuf creará su propio hilo y pedir una devolución de llamada para manejar onNext, onError y OnCompleted. Así que cuando onError se denomina en el ámbito corriente, cualquier excepción lanzada no será enviado de nuevo a cualquier función se utiliza para iniciar la corriente, por lo que no hay excepciones lanzadas a desencadenar la @Retry.

No es posible cambiar la forma en que se gestiona el flujo asíncrono y no es posible cambiar cómo se desencadenó la @Retry. GRPC se genera el código, y el gatillo @Retry se basa en la biblioteca microprofile.

Ejemplo:

  @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
      }
    };
  }

He tratado de encontrar una solución a este durante más tiempo que me gustaría admitir, pero todavía estoy en una pérdida. ¿Hay una manera de lanzar una excepción en un ámbito que termina en otro? ¿Hay alguna otra solución?

udalmik:

Se mezclan las operaciones síncronas y asíncronas aquí, por lo que es necesario definir claramente lo que es el "éxito" para usted y usted no necesita un nuevo intento levantó. Puede depender de la lógica, con pocas opciones de transmisión:

  • Al menos una actualización a onNext recibido, a continuación, la terminación o error
  • OnCompleted recibida con o sin las actualizaciones
  • etc.

Una vez definida la regla de "éxito", se puede envolver en suscripción futuro y esperar a que se resuelva con el tiempo de espera previsto. Si no se resuelve, luego tirar Excepción de la invocación inicial.

Supongo que te gusta

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