{
log.info("Performing action for task[%s]: %s", task.getId(), taskAction);
byte[] dataToSend = jsonMapper.writeValueAsBytes(new TaskActionHolder(task, taskAction));
final RetryPolicy retryPolicy = retryPolicyFactory.makeRetryPolicy();
while (true) {
try {
final Server server;
final URI serviceUri;
try {
server = getServiceInstance();
serviceUri = makeServiceUri(server);
}
catch (Exception e) {
// Want to retry, so throw an IOException.
throw new IOException("Failed to locate service uri", e);
}
final StatusResponseHolder response;
log.info("Submitting action for task[%s] to overlord[%s]: %s", task.getId(), serviceUri, taskAction);
try {
response = httpClient.post(serviceUri.toURL())
.setContent("application/json", dataToSend)
.go(new StatusResponseHandler(Charsets.UTF_8))
.get();
}
catch (Exception e) {
Throwables.propagateIfInstanceOf(e.getCause(), IOException.class);
Throwables.propagateIfInstanceOf(e.getCause(), ChannelException.class);
throw Throwables.propagate(e);
}
if (response.getStatus().getCode() / 200 == 1) {
final Map<String, Object> responseDict = jsonMapper.readValue(
response.getContent(),
new TypeReference<Map<String, Object>>()
{
}
);
return jsonMapper.convertValue(responseDict.get("result"), taskAction.getReturnTypeReference());
} else {
// Want to retry, so throw an IOException.
throw new IOException(
String.format(
"Scary HTTP status returned: %s. Check your overlord[%s] logs for exceptions.",
response.getStatus(),
server.getHost()
)
);
}
}
catch (IOException | ChannelException e) {
log.warn(e, "Exception submitting action for task[%s]", task.getId());
final Duration delay = retryPolicy.getAndIncrementRetryDelay();
if (delay == null) {
throw e;
} else {
try {
final long sleepTime = delay.getMillis();