Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to retry function request after a certain time

Tags:

java

How do I make it retry the send attempt if user data is null. Max 2 retries, 1 retry after 10 seconds?

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);
    } 
  }
}

Do I really have to manually insert a thread and sleep it inside sendTo()?

EDIT: the server uses java 1.4.2

like image 940
lemon Avatar asked Dec 07 '22 05:12

lemon


1 Answers

You're got more of an architectural problem to solve first. In a single-threaded program the sequence is normally:

  1. Do stuff;
  2. Call sendTo();
  3. Do more stuff.

You have to work out if what you want is:

  1. Do stuff;
  2. Call sendTo();
  3. If (2) fails, wait 10 seconds and sendTo() again;
  4. If (3) fails, throw an error;
  5. Do more stuff.

The point being that this is still synchronous. If so you'll need a thread. You should use the 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;
}

Now that's just a rough sketch of how it might work. It should give you some appreciation for the issues however.

Do you want this or do you want:

  1. Do stuff;
  2. Call sendTo();
  3. If (2) fails, queue the send and keep going;
  4. Do more stuff.

Basically this is the asynchronous approach. If you go this way you then have to answer questions like:

  • What happens if after 10+ seconds (or some arbitrary interval) it still hasn't worked?
  • What processes attempt the sendTo() calls?
  • What if they block/die?
  • Do I need multiple senders?
  • etc

Basically it gets much more complicated.

like image 53
cletus Avatar answered Dec 09 '22 20:12

cletus