Как повторить запрос функции через определенное время - PullRequest
3 голосов
/ 22 октября 2009

Как мне повторить попытку отправки, если пользовательские данные равны нулю. Максимум 2 попытки, 1 попытка через 10 секунд?

public class UserHandler {
  private List users = new ArrayList();

  public void addUser(username) {} //adds user
  public Userdata findUser(username) {} //finds user

  public void sendTo(String username, String message) {
    Userdata user = findUser(username);
    if(user != null) {
        Out out = new Out(user.getClientSocket());
        out.println(message);
    } 
  }
}

Неужели мне нужно вручную вставить поток и перевести его в спящий режим внутри sendTo ()?

РЕДАКТИРОВАТЬ: сервер использует Java 1.4.2

Ответы [ 3 ]

5 голосов
/ 25 июля 2015

Ваш точный сценарий, используя Failsafe :

RetryPolicy retryPolicy = new RetryPolicy()
  .retryWhen(null)
  .withMaxRetries(2)
  .withDelay(10, TimeUnit.SECONDS);

Userdata user = Failsafe.with(retryPolicy).get(() -> findUser(username));

Это не становится проще. Расскажи друзьям:)

5 голосов
/ 22 октября 2009

Сначала нужно решить еще одну архитектурную проблему. В однопоточной программе последовательность обычно:

  1. Делай вещи;
  2. Call sendTo ();
  3. Делай больше вещей.

Вы должны потренироваться, если хотите:

  1. Делать вещи;
  2. Call sendTo ();
  3. Если (2) не удается, подождите 10 секунд и снова отправьте ();
  4. Если (3) не удается, выведите ошибку;
  5. Делай больше вещей.

Дело в том, что это все еще синхронно. Если так, вам понадобится нить. Вы должны использовать Java 5 Executors.

public void sendTo(final String username, final String message) {
  if (!internalSendTo(username, message)) {
    // attempt resend
    ExecutorService exec = Executors.newSingleThreadExecutor();
    final AtomicBoolean result = new AtomicBoolean(false);
    exec.submit(new Runnable() {
      boolean b = internalSendto(username, message);
      result.set(b);
    });
    try {
      exec.awaitTermination(10, TimeUnit.SECONDS);
    } catch (InterruptedException e) {
      // still didn't work
    } finally {
      exec.shutdownNow();
    }
  }
}

private boolean internalSendTo(String username, String message) {
  Userdata user = findUser(username);
  boolean success = false;
  if (user != null) {
    Out out = new Out(user.getClientSocket());
    // do the communication here
    success = true;
  }
  return success;
}

Теперь это просто набросок того, как это может работать. Это должно дать вам некоторую признательность за проблемы, однако.

Вы хотите этого или хотите:

  1. Делай вещи;
  2. Call sendTo ();
  3. Если (2) не удается, поставьте в очередь отправку и продолжайте;
  4. Делай больше вещей.

По сути, это асинхронный подход. Если вы пойдете этим путем, то вам придется отвечать на такие вопросы, как:

  • Что произойдет, если через 10 с лишним секунд (или через некоторый произвольный интервал) он все еще не сработает?
  • Какие процессы пытаются выполнить вызовы sendTo ()?
  • Что если они заблокируют / умрут?
  • Нужно ли несколько отправителей?
  • и т.д.

В основном все становится намного сложнее.

0 голосов
/ 03 февраля 2013

Я бы рекомендовал использовать аннотации AOP и Java. Попробуйте готовый механизм из jcabi-aspect :

@RetryOnFailure(attempts = 3)
public void sendTo(String username, String message) {
  // try to do it
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...