private Callable<IterableXMLEventReader> callable(final Request request, final Request journalInstance) {
return new Callable<IterableXMLEventReader>() {
C2ServiceException optionalStackTrace = showDeepStacks ?
new C2ServiceException("Originating Call Stack",false) :
null;
@Override
public IterableXMLEventReader call() throws Exception {
try {
if (!journalInstance.isApprovalKnown() && journalInstance.command().approvalRequired()) {
//must get approval for these!
assert(journal.pending().next().equals(journalInstance));
approvalRequestable.waitForApproval(journal.pending());
}
if (!journalInstance.isApproved()) {
journal.markRejected(journalInstance);
return new IterableXMLEventReader("<rejected>not approved</rejected>");
};
//was validated upon construction but assert it was not changed in the meantime
assert(request.validate());
//all down stream requests must see the same halting exception until its reset.
if (haltingException != null ) {
throw haltingException;
}
boolean tryAgain = false;
do {
try {
//exceptions thrown here are because
// * the network is down and we should try later
// * the response was not readable - must stop all
//transmit to the adapter
IterableXMLEventReader eventReader = adapter.transmit(request);
synchronized (ResponseManager.this) {
//exceptions thrown here are because
// * database was unable to change flag on request to sent - must stop all
journal.markSent(journalInstance);
}
return eventReader;
} catch (C2ServiceException e) {
tryAgain = e.tryAgain();//if true wait for configured delay and try again.
if (tryAgain) {
if (null != request.get(Parameter.CancelsAtRelative)) {
//cant try again or delay because the request is time dependent relative to submission time
haltingException = new C2ServiceException("Can not retry request which makes use of CancelsAtRelative feature",false);
throw haltingException;
}
try {
Thread.sleep(networkDownRetryDelay);
} catch (InterruptedException ie) {
throw e; //this is not a halting exception
}
} else {
haltingException = e;
throw haltingException;
}
} catch (Exception ex) {
haltingException = new C2ServiceException(request.toString(),ex,false);
throw haltingException;
}
} while (tryAgain);
throw new C2ServiceException("Unable to execute.",true);
} catch (RuntimeException e) {
if (optionalStackTrace!=null) {
optionalStackTrace.overrideCause(e);
throw optionalStackTrace;