Sto usando spring-cloud-starter (ovvero .. avvio a molla con tutte le funzionalità dei microservizi). Quando creo il metodo hystrix in un componente annotato utilizzando javanica @HystrixCommand, segui le istruzioni sul sito javanica github (https://github.com/Netflix/Hystrix/tree/master/hystrix-contrib/hystrix-javanica) per fare in modo che quel metodo esegua async, indipendentemente dal fatto che io usi il "futuro <>" o l'esecuzione reattiva "Osservabile < > ', niente esegue/esegue e ottengo
java.lang.ClassCastException: springbootdemo.EricComponent$1 cannot be cast to springbootdemo.Eric
ogni volta che tento di estrarre il risultato (nel caso di Future <>) o ottenere una richiamata (in caso di Esecuzione reattiva .. e non si innesca println così non è stato eseguito correttamente).I metodi asstrix di Hystrix all'interno di javanica non sono in esecuzione nell'applicazione java spring-boot
public class Application { ...
}
@RestController
@RequestMapping(value = "/makebunchofcalls/{num}")
class EricController { ..
@RequestMapping(method={RequestMethod.POST})
ArrayList<Eric> doCalls(@PathVariable Integer num) throws IOException {
ArrayList<Eric> ale = new ArrayList<Eric>(num);
for (int i =0; i<num; i++) {
rx.Observable<Eric> oe = this.ericComponent.doRestTemplateCallAsync(i);
oe.subscribe(new Action1<Eric>() {
@Override
public void call(Eric e) { // AT RUNTIME, ClassCastException
ale.add(e);
}
});
}
return ale;
}
@Component
class EricComponent { ...
// async version =========== using reactive execution via rx library from netflix ==============
@HystrixCommand(fallbackMethod = "defaultRestTemplateCallAsync", commandKey = "dogeAsync")
public rx.Observable<Eric> doRestTemplateCallAsync(int callNum) {
return new ObservableResult<Eric>() {
@Override
public Eric invoke() { // NEVER CALLED
try {
ResponseEntity<String> result = restTemplate.getForEntity("http://doges/doges/24232/photos", String.class); // actually make a call
System.out.println("*************** call successfull: " + new Integer(callNum).toString() + " *************");
} catch (Exception ex) {
System.out.println("=============== call " + new Integer(callNum).toString() + " not successfull: " + ex.getMessage() + " =============");
}
return new Eric(new Integer(callNum).toString(), "ok");
}
};
}
public rx.Observable<Eric> defaultRestTemplateCallAsync(int callNum) {
return new ObservableResult<Eric>() {
@Override
public Eric invoke() {
System.out.println("!!!!!!!!!!!!! call bombed " + new Integer(callNum).toString() + "!!!!!!!!!!!!!");
return new Eric(new Integer(callNum).toString(), "bomb");
}
};
}
}
Perché dovrei essere sempre di nuovo un EricComponent$1
invece di un Eric
? btw, Eric
è solo una semplice classe con 2 stringhe ... il suo omesso.
Sto calcolando che devo eseguire esplicitamente, ma che mi allude perché: 1) Farlo con Future <> il metodo queue() non è disponibile come afferma la documentazione e 2) farlo con Observable <> non c'è davvero un modo per eseguirlo che ottengo.
Grazie a @spencergibb per il tempo che ci hai dedicato. Ho avuto @EnableHystrix .. ed è stato in grado di evitare ClassCastException in base al tuo suggerimento per sostituire 'Observable' in 'Eric' dal valore predefinito. Qualcuno dovrebbe aggiornare la documentazione Javanica per dichiararlo. Tuttavia, quando eseguo questo, ottengo tutte le stampe "call bombardate". Inoltre il metodo 'richiamare()' 'sulla ObservableResult ' tornato ancora non viene mai eseguito. –
RubesMN
Per l'aggiornamento n. 3, risulta che la separazione di EricComponent nel proprio file ha funzionato perfettamente. Tutto funziona ora. Inoltre, il passaggio al blocco tramite BlockingObservables e non-blocking tramite normali Observables funziona anch'esso e mi fornisce ciò di cui avevo bisogno per il mio POC. Grazie ancora a @spencergibb. – RubesMN