Sto calcolando un futuro per avere un timeout in attesa di un evento di serie per accadere:Come fermare timeout di un futuro
Future<Response> future = executor.submit(new CommunicationTask(this, request));
response = new Response("timeout");
try {
response = future.get(timeoutMilliseconds, TimeUnit.MILLISECONDS);
} catch (InterruptedException | TimeoutException e) {
future.cancel(true);
log.info("Execution time out." + e);
} catch (ExecutionException e) {
future.cancel(true);
log.error("Encountered problem communicating with device: " + e);
}
La classe CommunicationTask
ha implementato l'interfaccia Observer
per ascoltare un cambiamento da la porta seriale
Il problema è che la lettura dalla porta seriale è relativamente lenta e anche quando si verifica un evento seriale il tempo scade e viene lanciato un TimeoutException
. Cosa posso fare per fermare il timeout del mio futuro quando si verifica un evento seriale?
ho provato con un AtomicReference
ma questo non cambia nulla:
public class CommunicationTask implements Callable<Response>, Observer {
private AtomicReference atomicResponse = new AtomicReference(new Response("timeout"));
private CountDownLatch latch = new CountDownLatch(1);
private SerialPort port;
CommunicationTask(SerialCommunicator communicator, Request request) {
this.communicator = communicator;
this.message = request.serialize();
this.port = communicator.getPort();
}
@Override
public Response call() throws Exception {
return query(message);
}
public Response query(String message) {
communicator.getListener().addObserver(this);
message = message + "\r\n";
try {
port.writeString(message);
} catch (Exception e) {
log.warn("Could not write to port: " + e);
communicator.disconnect();
}
try {
latch.await();
} catch (InterruptedException e) {
log.info("Execution time out.");
}
communicator.getListener().deleteObserver(this);
return (Response)atomicResponse.get();
}
@Override
public void update(Observable o, Object arg) {
atomicResponse.set((Response)arg);
latch.countDown();
}
}
Cosa posso fare per risolvere questo problema?
MODIFICA:
Ok, ho avuto un errore. Stavo eseguendo il conto alla rovescia prima di impostare atomicResponse
nella mia funzione update
. Ora sembra funzionare, ma c'è ancora la domanda se questo approccio è il modo giusto per farlo?
Si potrebbe aggiungere un metodo 'isCommunicationStarted' al tuo CommunicationTask - quando rilevi 'TimeoutException', controlla' isCommunicationStarted' - se restituisce false => cancel, altrimenti prova 'future.get()' di nuovo (magari con un nuovo timeout). – assylias
Puoi dividere la tua classe di attività in due: in primo luogo attenderò fino all'avvio dell'evento con timeout e invierà l'attività di 2 ° tipo all'avvio dell'evento. La seconda attività elaborerà l'evento di conseguenza. –
Non è abbastanza chiaro cosa si vuole raggiungere. L'impostazione di un timeout implica che gli eventi arrivati dopo il timeout possano essere ignorati. In tal caso, perché è importante il caso in questione? – axtavt