4

In official https://spring.io/guides/gs/circuit-breaker/ manual there are

  1. business method (readingList)
  2. fallback method (reliable)
@HystrixCommand(fallbackMethod = "reliable")
  public String readingList() {
    URI uri = URI.create("http://localhost:8090/recommended");

    return this.restTemplate.getForObject(uri, String.class);
  }

  public String reliable() {
    return "Cloud Native Java (O'Reilly)";
  }

How to pass data from business method to fallback method? Use ThreadLocal, immutable collections, concurrent collections, any ideas/best practice?

Joris Schellekens
  • 8,483
  • 2
  • 23
  • 54
arminvanbuuren
  • 957
  • 1
  • 9
  • 16

1 Answers1

2

Use ThreadLocal?

@HystrixCommand and the corresponding fallbackMethod are normally executed (together) in a separate thread because of the default execution.isolation.strategy which is ExecutionIsolationStrategy.THREAD.

So that means that if you use ThreadLocal to set any variables before @HystrixCommand is executed, they won't be available to the @HystrixCommand because the thread will be different.

If the above is necessary you can use a different isolation strategy - ExecutionIsolationStrategy.SEMAPHORE.

To override the default isolation strategy you can do it on the hystrix command definition (or in properties files):

@HystrixCommand(fallbackMethod = "reliable",
    commandProperties = {
        @HystrixProperty(name="execution.isolation.strategy", value="SEMAPHORE")
    }
)

Passing input parameters data

Methods annotated with @HystrixCommand and the corresponding fallbackMethod need to have the same method signature (plus optional param in the fallback for exceptions thrown), so naturally the fallback method will have access to all input parameters to the @HystrixCommand.

Passing exceptions data

Adding Throwable in the fallback method signature will include the exception produced from the @HystrixCommand:

   public String reliable(Throwable t) {
     return "Cloud Native Java (O'Reilly)";
   }

Passing execution data

It's not practical to expect any execution data to be passed from main method to the fallback method. You don't know when the main method will fail. A key thing is to try and define better input parameters, which will be shared with the fallback anyway.

For example in the code that you've given the URL can become input parameter, so it will be available to the fallback method as well:

@HystrixCommand(fallbackMethod = "reliable")
  public String readingList(String url) {
    URI uri = URI.create(url);

    return this.restTemplate.getForObject(uri, String.class);
  }

   public String reliable(String url, Throwable t) {
     return "Cloud Native Java (O'Reilly)";
   }
hovanessyan
  • 30,580
  • 6
  • 55
  • 83
  • can you please see more descriptive question here https://stackoverflow.com/questions/55862601/not-able-to-access-inheritablethreadlocal-object-from-parent-thread-in-fall-back – Devratna Apr 26 '19 at 11:55