Откат к methodB, если выполнение метода A занимает более X секунд в Spring Boot - PullRequest
0 голосов
/ 20 декабря 2018

У меня есть приложение Spring Boot, и у меня есть одно @Service, которое довольно тяжелое и может выполняться от 0,5 до 5 секунд.Я хотел бы, чтобы он прекратил выполнение, если время выполнения превышает 1 секунду, и откат к резервному методу.

/// entry point
public String longLatingMethod(Payload payload) {
    /// long lasting operation that can take up to 5 seconds
    return value; 
}

// I want this method to be executed if `longLatingMethod` takes more than 1 second to execute.
public String fallbackMethod(Payload payload) {
    return defaultValue;
}

Прямо сейчас я реализовал его с помощью Hystrix framework, но поскольку Hystrix больше не поддерживается,Я хотел бы знать, какие другие библиотеки для этой цели?

Ответы [ 3 ]

0 голосов
/ 20 декабря 2018

Не уверен, что это лучшее решение, но проверьте этот вопрос: Java: установить тайм-аут для определенного блока кода?

А в блоке тайм-аута добавить запасной вариант

final Runnable stuffToDo = new Thread() {
  @Override 
  public void run() { 
    /* Do stuff here. */ 
  }
};

final ExecutorService executor = Executors.newSingleThreadExecutor();
final Future future = executor.submit(stuffToDo);
executor.shutdown(); // This does not cancel the already-scheduled task.

try { 
  future.get(1, TimeUnit.Seconds); 
}
catch (InterruptedException ie) { 
  /* Handle the interruption. Or ignore it. */ 
}
catch (ExecutionException ee) { 
  /* Handle the error. Or ignore it. */ 
}
catch (TimeoutException te) { 
    return fallbackMethod(payload);
}
0 голосов
/ 20 декабря 2018

Вы можете использовать метод Future, в частности, метод V get(long timeout, TimeUnit unit):

При необходимости ожидает не более заданного времени для завершения вычисления, а затем извлекает егорезультат, если доступен.

И используйте его следующим образом:

  Callable<String> task = () -> {
    ...
  };

   public Future<String> myMethod() {
     return Executors.submit(task);
   }

   public String fallBackMethod() {
      ...
   }

   String value = null;
   try {
      Future<String> result = myMethod.get(1, TimeUnit.SECONDS);
      value = result.get();
   } catch (TimeoutException e) {
      value = fallBackMethod();
   }

Обратите внимание, что вы не можете остановить выполнение метода после его запуска, если вы не изменилиэтот метод периодически проверяет, завершился он или нет, но часто вы не можете, например, если вы запрашиваете запрос к базе данных, и запрос занимает 5 секунд, которые вы не можете проверить раньше, чем через 5 секунд.

0 голосов
/ 20 декабря 2018

Вы должны запустить свою задачу в каком-то потоке, чтобы вы могли продолжить выполнение и подождать (определенное количество миллисекунд), пока этот процесс не завершится.Если он не завершится в отведенное время, прервите основную задачу и запустите задачу резервного копирования.Обратите внимание, что ваша основная задача должна будет проверить, прервана ли она, операции блокировки часто проверяют это уже и прекратят блокировку при прерывании.

public static void main(String[] args){
    Thread t = new Thread(() -> {
        // your long running task here...
        System.out.println("running primary task");

        // simulate it taking too long...
        // will need to check if it is interrupted if you want to terminate it sooner
        try {
            Thread.sleep(60000);
        } catch (InterruptedException e) {
            System.out.println("primary task interrupted");
        }
    });
    t.start();

    // one second threshold
    try { t.join(1000); } catch (Exception e) {}

    if (t.isAlive()) {
        // if the primary task is still running interrupt it
        t.interrupt();

        // run your backup task
        System.out.println("running backup task");
        // ...
        System.out.println("backup task completed");
    } else {
        System.out.println("primary task completed");
    }
}

Выходы:

running primary task
running backup task
primary task interrupted
backup task completed
...