Hystrix refuses Completable Future return Type

Viewed 305

I am trying to right a @Hystrix method which returns a CompltetableFuture<String>.

@HystrixCommand(fallbackMethod = "myMethodFallback")
public CompletableFuture<String> myMethod(){
  CompletableFuture<String> future = getFuture();
  return future;
}

public CompletableFuture<String> myMethodFallback(Throwable t){
  return CompletableFuture.completedFuture("");
}

However, when the method is invoked, I get this error:

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is com.netflix.hystrix.contrib.javanica.exception.FallbackDefinitionException: Incompatible return types. 
...
Hint: fallback cannot return Future if the fallback isn't command when the command is async.

I read somewhere that I might try altering the return type of the FallbackMethod so that it doesn't return the future, but the generic value. So I tried this:

public String myMethodFallback(Throwable t){
  return "";
}

and got this error:

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.ClassCastException: com.netflix.hystrix.HystrixCommand$4 cannot be cast to java.util.concurrent.CompletableFuture

I played around and tried add @HystrixCommand to the fallback method as well

@HystrixCommand
public CompletableFuture<String> myMethodFallback(Throwable t){
  return CompletableFuture.completedFuture("");
}

but got this error:

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.ClassCastException: com.netflix.hystrix.contrib.javanica.utils.FutureDecorator cannot be cast to java.util.concurrent.CompletableFuture
  1. Does anyone have a good resource on the restrictions of a Hystrix Fallback method?
  2. Is there something I can do here to make this work? Or is it just not possible to return a Future from a Hystrix method?
1 Answers

Here is an alternative approach using Spring Web reactive with HystrixCommand.

@Autowired
HystrixImpl hystrixImpl;

public Mono<String> getResponse() {

    return HystrixCommands.from(hystrixImpl.myMethod())
            .fallback(throwable -> {
                return hystrixImpl.myMethodFallback(throwable);
            })
            .commandName("MyCommand")
            .toFlux()
            .single();
}

HystrixImpl.Java

@Service 
public class HystrixImpl {
    public Mono<String> myMethod() {
        return Mono.just("From main method");
    }

    public Mono<String> myMethodFallback(Throwable t) {
        return Mono.just("From fallback method");
    }

}

We just need to use getResponse().block() to get the String value of Mono.

Related