1
resposta

Como fazer para o JuntaResultadosFutureWSFutureBanco disparar unm TimeoutException se apenas um dos future Get disparar timeoutException?

Quando fui explorar um cenario onde um comando deveria dar timeoutException e outro não ele não deu timeoutException no JuntaResultadosFutureWSFutureBanco. Como fazer para o JuntaResultadosFutureWSFutureBanco disparar unm TimeoutException se apenas um dos future Get disparar timeoutException?

try {
    String numeroMagico = this.futureWS.get(20, TimeUnit.SECONDS);
    String numeroMagico2 = this.futureBanco.get(20, TimeUnit.SECONDS);

    this.saidaCliente.println("Resultado comando c2 : " + numeroMagico + ", " + numeroMagico2);
} catch (InterruptedException | ExecutionException | TimeoutException e) {
    System.out.println("Timeout : Cancelando execucao do comando c2");

    this.saidaCliente.println("Timeout do comando c2");
    this.futureWS.cancel(true);
    this.futureBanco.cancel(true);
}

System.out.println("Finalizou JuntaResultadosFutureWSFutureBanco");
package br.com.alura.servidor;

import java.io.PrintStream;
import java.util.Random;
import java.util.concurrent.Callable;

public class ComandoC2ChamaWS implements Callable<String> {

private PrintStream saida;

public ComandoC2ChamaWS(PrintStream saida) {
this.saida = saida;
}

@Override
public String call() throws Exception {
System.out.println("Servidor recebeu comando c2");

saida.println("Processando Comando c2");

Thread.sleep(15000);

int numero = new Random().nextInt(100) + 1;

saida.println("Srvidor finalizou comando c2 - WS");

return Integer.toString(numero);

}

}
package br.com.alura.servidor;

import java.io.PrintStream;
import java.util.Random;
import java.util.concurrent.Callable;

public class ComandoC2AcessaBanco implements Callable<String> {
    
    private PrintStream saida;

    public ComandoC2AcessaBanco(PrintStream saida) {
        this.saida = saida;
    }

    @Override
    public String call() throws Exception {
        System.out.println("Servidor recebeu comando c2 - banco");

        saida.println("Processando Comando c2 - banco");

        Thread.sleep(30000);
        
        int numero = new Random().nextInt(100) + 1;
        
        saida.println("Servidor finalizou comando c2 - banco");
        
        return Integer.toString(numero);
        
    }

}
1 resposta

Olá Marcelo,

Pelo que entendi, você deseja que o JuntaResultadosFutureWSFutureBanco dispare uma TimeoutException caso apenas um dos future get dispare o mesmo tipo de exceção. Uma forma de fazer isso é utilizar um CountDownLatch para aguardar a finalização dos dois future get e, caso um deles dispare a exceção, setar uma variável booleana para indicar que ocorreu um timeout. Em seguida, você pode verificar o valor dessa variável e lançar a exceção TimeoutException caso ela seja verdadeira.

Segue um exemplo de como implementar essa solução:

CountDownLatch latch = new CountDownLatch(2);
boolean timeout = false;

try {
    String numeroMagico = this.futureWS.get(20, TimeUnit.SECONDS);
    latch.countDown();

    String numeroMagico2 = this.futureBanco.get(20, TimeUnit.SECONDS);
    latch.countDown();

    if (latch.await(0, TimeUnit.SECONDS) && timeout) {
        throw new TimeoutException("Timeout : Cancelando execucao do comando c2");
    }

    this.saidaCliente.println("Resultado comando c2 : " + numeroMagico + ", " + numeroMagico2);
} catch (InterruptedException | ExecutionException | TimeoutException e) {
    System.out.println("Timeout : Cancelando execucao do comando c2");

    this.saidaCliente.println("Timeout do comando c2");
    this.futureWS.cancel(true);
    this.futureBanco.cancel(true);
    timeout = true;
}

if (timeout) {
    throw new TimeoutException("Timeout : Cancelando execucao do comando c2");
}

System.out.println("Finalizou JuntaResultadosFutureWSFutureBanco");

Espero ter ajudado e bons estudos!