【问题标题】:How to retry function request after a certain time如何在一定时间后重试功能请求
【发布时间】:2009-10-22 02:52:19
【问题描述】:

如果用户数据为空,我如何让它重试发送尝试。最多重试 2 次,10 秒后重试 1 次?

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

【问题讨论】:

    标签: java


    【解决方案1】:

    您的确切场景,使用Failsafe

    RetryPolicy retryPolicy = new RetryPolicy()
      .retryWhen(null)
      .withMaxRetries(2)
      .withDelay(10, TimeUnit.SECONDS);
    
    Userdata user = Failsafe.with(retryPolicy).get(() -> findUser(username));
    

    它并没有变得更简单。告诉你的朋友:)

    【讨论】:

      【解决方案2】:

      您首先要解决更多架构问题。在单线程程序中,顺序通常是:

      1. 做事;
      2. 调用 sendTo();
      3. 做更多的事情。

      你必须弄清楚你想要的是:

      1. 做事;
      2. 调用 sendTo();
      3. 如果 (2) 失败,请等待 10 秒,然后再次 sendTo();
      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. 调用 sendTo();
      3. 如果 (2) 失败,排队发送并继续;
      4. 做更多的事情。

      基本上这是异步方法。如果您这样做,则必须回答以下问题:

      • 如果在 10 多秒(或某个任意时间间隔)后仍然没有工作,会发生什么情况?
      • 哪些进程尝试调用 sendTo()?
      • 如果他们阻塞/死亡怎么办?
      • 我需要多个发件人吗?

      基本上它变得更加复杂。

      【讨论】:

      【解决方案3】:

      我建议使用 AOP 和 Java 注释。尝试从jcabi-aspects 读取的机制:

      @RetryOnFailure(attempts = 3)
      public void sendTo(String username, String message) {
        // try to do it
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-06-29
        • 1970-01-01
        • 2019-03-25
        • 2014-09-21
        • 2015-08-29
        • 1970-01-01
        • 2017-04-22
        相关资源
        最近更新 更多