use of com.twitter.util.FutureTransformer in project linden by XiaoMi.
the class CoreLindenCluster method delete.
@Override
public Response delete(LindenDeleteRequest request) throws IOException {
List<Future<BoxedUnit>> futures = new ArrayList<>();
List<String> hosts = new ArrayList<>();
final StringBuilder errorInfo = new StringBuilder();
Set<Integer> routeIds = null;
if (request.isSetRouteParam()) {
routeIds = new HashSet<>();
for (final ShardRouteParam routeParam : request.getRouteParam().getShardParams()) {
routeIds.add(routeParam.getShardId());
}
}
for (final Map.Entry<Integer, ShardClient> entry : clients.entrySet()) {
if (routeIds != null && !routeIds.contains(entry.getKey())) {
continue;
}
if (entry.getValue().isAvailable()) {
List<Map.Entry<String, Future<Response>>> hostFuturePairs = entry.getValue().delete(request);
for (final Map.Entry<String, Future<Response>> hostFuturePair : hostFuturePairs) {
hosts.add(hostFuturePair.getKey());
futures.add(hostFuturePair.getValue().transformedBy(new FutureTransformer<Response, BoxedUnit>() {
@Override
public BoxedUnit map(Response response) {
if (!response.isSuccess()) {
synchronized (errorInfo) {
LOGGER.error("Shard [{}] host [{}] failed to get delete response : {}", entry.getKey(), hostFuturePair.getKey(), response.getError());
errorInfo.append("Shard " + entry.getKey() + " host " + hostFuturePair.getKey() + ":" + response.getError() + ";");
}
}
return BoxedUnit.UNIT;
}
@Override
public BoxedUnit handle(Throwable t) {
LOGGER.error("Shard [{}] host [{}] failed to get delete response : {}", entry.getKey(), hostFuturePair.getKey(), Throwables.getStackTraceAsString(t));
errorInfo.append("Shard " + entry.getKey() + " host " + hostFuturePair.getKey() + ":" + Throwables.getStackTraceAsString(t) + ";");
return BoxedUnit.UNIT;
}
}));
}
}
}
Future<List<BoxedUnit>> collected = Future.collect(futures);
try {
if (clusterFutureAwaitTimeout == 0) {
Await.result(collected);
} else {
Await.result(collected, Duration.apply(clusterFutureAwaitTimeout, TimeUnit.MILLISECONDS));
}
if (errorInfo.length() > 0) {
return ResponseUtils.buildFailedResponse("Delete failed: " + errorInfo.toString());
}
return ResponseUtils.SUCCESS;
} catch (Exception e) {
LOGGER.error("Failed to get all delete responses, exception: {}", Throwables.getStackTraceAsString(e));
LOGGER.error(getHostFutureInfo(hosts, futures));
return ResponseUtils.buildFailedResponse(e);
}
}
use of com.twitter.util.FutureTransformer in project linden by XiaoMi.
the class CoreLindenCluster method executeCommand.
@Override
public Response executeCommand(final String command) throws IOException {
LOGGER.info("Receive cluster command {}", command);
List<Future<BoxedUnit>> futures = new ArrayList<>();
List<String> hosts = new ArrayList<>();
final StringBuilder errorInfo = new StringBuilder();
JSONObject jsonCmd = JSONObject.parseObject(command);
Integer shardId = jsonCmd.getInteger(SHARD);
for (final Map.Entry<Integer, ShardClient> entry : clients.entrySet()) {
ShardClient shardClient = entry.getValue();
if (shardId != null && shardId != shardClient.getShardId()) {
continue;
}
if (shardClient.isAvailable()) {
final List<Map.Entry<String, Future<Response>>> hostFuturePairs = shardClient.executeCommand(jsonCmd);
for (final Map.Entry<String, Future<Response>> hostFuturePair : hostFuturePairs) {
hosts.add(hostFuturePair.getKey());
futures.add(hostFuturePair.getValue().transformedBy(new FutureTransformer<Response, BoxedUnit>() {
@Override
public BoxedUnit map(Response response) {
if (!response.isSuccess()) {
LOGGER.error("Shard [{}] host [{}] failed to execute command {} error: {}", entry.getKey(), hostFuturePair.getKey(), command, response.getError());
synchronized (errorInfo) {
errorInfo.append("Shard " + entry.getKey() + " host " + hostFuturePair.getKey() + ":" + response.getError() + ";");
}
}
return BoxedUnit.UNIT;
}
@Override
public BoxedUnit handle(Throwable t) {
LOGGER.error("Shard [{}] host [{}] failed to execute command {} throwable: {}\"", entry.getKey(), hostFuturePair.getKey(), command, Throwables.getStackTraceAsString(t));
synchronized (errorInfo) {
errorInfo.append("Shard " + entry.getKey() + " host " + hostFuturePair.getKey() + ":" + Throwables.getStackTraceAsString(t) + ";");
}
return BoxedUnit.UNIT;
}
}));
}
}
}
try {
Future<List<BoxedUnit>> collected = Future.collect(futures);
if (clusterFutureAwaitTimeout == 0) {
Await.result(collected);
} else {
// executeCommand may take a very long time, so set timeout to 30min specially
Await.result(collected, Duration.apply(30, TimeUnit.MINUTES));
}
if (errorInfo.length() > 0) {
return ResponseUtils.buildFailedResponse("command " + command + " failed: " + errorInfo.toString());
}
LOGGER.error("Cluster command {} succeeded", command);
return ResponseUtils.SUCCESS;
} catch (Exception e) {
LOGGER.error("Cluster command {} failed {}", command, Throwables.getStackTraceAsString(e));
LOGGER.error(getHostFutureInfo(hosts, futures));
return ResponseUtils.buildFailedResponse(e);
}
}
use of com.twitter.util.FutureTransformer in project linden by XiaoMi.
the class CoreLindenCluster method index.
@Override
public Response index(String content) throws IOException {
List<Future<BoxedUnit>> futures = new ArrayList<>();
List<String> hosts = new ArrayList<>();
final StringBuilder errorInfo = new StringBuilder();
LindenIndexRequest indexRequest = LindenIndexRequestParser.parse(lindenConfig.getSchema(), content);
for (final Map.Entry<Integer, ShardClient> entry : clients.entrySet()) {
ShardClient shardClient = entry.getValue();
if (shardClient.isAvailable()) {
if (shardingStrategy.accept(indexRequest.getId(), indexRequest.getRouteParam(), shardClient.getShardId())) {
final List<Map.Entry<String, Future<Response>>> hostFuturePairs = shardClient.index(content);
for (final Map.Entry<String, Future<Response>> hostFuturePair : hostFuturePairs) {
hosts.add(hostFuturePair.getKey());
futures.add(hostFuturePair.getValue().transformedBy(new FutureTransformer<Response, BoxedUnit>() {
@Override
public BoxedUnit map(Response response) {
if (!response.isSuccess()) {
LOGGER.error("Shard [{}] host [{}] failed to get index response : {}", entry.getKey(), hostFuturePair.getKey(), response.getError());
synchronized (errorInfo) {
errorInfo.append("Shard " + entry.getKey() + " host " + hostFuturePair.getKey() + ":" + response.getError() + ";");
}
}
return BoxedUnit.UNIT;
}
@Override
public BoxedUnit handle(Throwable t) {
LOGGER.error("Shard [{}] host [{}] failed to get index response : {}", entry.getKey(), hostFuturePair.getKey(), Throwables.getStackTraceAsString(t));
synchronized (errorInfo) {
errorInfo.append("Shard " + entry.getKey() + " host " + hostFuturePair.getKey() + ":" + Throwables.getStackTraceAsString(t) + ";");
}
return BoxedUnit.UNIT;
}
}));
}
}
}
}
try {
Future<List<BoxedUnit>> collected = Future.collect(futures);
if (clusterFutureAwaitTimeout == 0) {
Await.result(collected);
} else {
Await.result(collected, Duration.apply(clusterFutureAwaitTimeout, TimeUnit.MILLISECONDS));
}
if (errorInfo.length() > 0) {
return ResponseUtils.buildFailedResponse("Index failed: " + errorInfo.toString());
}
return ResponseUtils.SUCCESS;
} catch (Exception e) {
LOGGER.error("Handle request failed, content : {} - {}", content, Throwables.getStackTraceAsString(e));
LOGGER.error(getHostFutureInfo(hosts, futures));
return ResponseUtils.buildFailedResponse(e);
}
}
use of com.twitter.util.FutureTransformer in project linden by XiaoMi.
the class CoreLindenCluster method coreSearch.
public LindenResult coreSearch(final LindenSearchRequest request) throws IOException {
List<Future<BoxedUnit>> futures = new ArrayList<>();
List<String> hosts = new ArrayList<>();
final List<LindenResult> resultList = new ArrayList<>();
if (request.isSetRouteParam() && request.getRouteParam().isSetShardParams()) {
for (final ShardRouteParam routeParam : request.getRouteParam().getShardParams()) {
ShardClient client = clients.get(routeParam.getShardId());
if (client != null && client.isAvailable()) {
LindenSearchRequest subRequest = request;
if (routeParam.isSetEarlyParam()) {
subRequest = new LindenSearchRequest(request);
subRequest.setEarlyParam(routeParam.getEarlyParam());
}
final Map.Entry<String, Future<LindenResult>> hostFuturePair = client.search(subRequest);
hosts.add(hostFuturePair.getKey());
futures.add(hostFuturePair.getValue().transformedBy(new FutureTransformer<LindenResult, BoxedUnit>() {
@Override
public BoxedUnit map(LindenResult lindenResult) {
synchronized (resultList) {
resultList.add(lindenResult);
if (!lindenResult.isSuccess()) {
LOGGER.error("Shard [{}] host [{}] failed to get search result : {}", routeParam.getShardId(), hostFuturePair.getKey(), lindenResult.getError());
}
}
return BoxedUnit.UNIT;
}
@Override
public BoxedUnit handle(Throwable t) {
LOGGER.error("Shard [{}] host [{}] failed to get search result : {}", routeParam.getShardId(), hostFuturePair.getKey(), Throwables.getStackTraceAsString(t));
return BoxedUnit.UNIT;
}
}));
} else {
LOGGER.warn("Route to Shard [{}] failed.", routeParam.getShardId());
}
}
} else {
LindenSearchRequest subRequest = request;
for (final Map.Entry<Integer, ShardClient> entry : clients.entrySet()) {
if (entry.getValue().isAvailable()) {
final Map.Entry<String, Future<LindenResult>> hostFuturePair = entry.getValue().search(subRequest);
hosts.add(hostFuturePair.getKey());
futures.add(hostFuturePair.getValue().transformedBy(new FutureTransformer<LindenResult, BoxedUnit>() {
@Override
public BoxedUnit map(LindenResult lindenResult) {
synchronized (resultList) {
resultList.add(lindenResult);
if (!lindenResult.isSuccess()) {
LOGGER.error("Shard [{}] host [{}] failed to get search result : {}", entry.getKey(), hostFuturePair.getKey(), lindenResult.getError());
}
return BoxedUnit.UNIT;
}
}
@Override
public BoxedUnit handle(Throwable t) {
LOGGER.error("Shard [{}] host [{}] failed to get search result : {}", entry.getKey(), hostFuturePair.getKey(), Throwables.getStackTraceAsString(t));
return BoxedUnit.UNIT;
}
}));
}
}
}
Future<List<BoxedUnit>> collected = Future.collect(futures);
try {
if (clusterFutureAwaitTimeout == 0) {
Await.result(collected);
} else {
Await.result(collected, Duration.apply(clusterFutureAwaitTimeout, TimeUnit.MILLISECONDS));
}
} catch (Exception e) {
LOGGER.error("Failed to get all results, exception: {}", Throwables.getStackTraceAsString(e));
LOGGER.error(getHostFutureInfo(hosts, futures));
if (resultList.size() == 0) {
return new LindenResult().setSuccess(false).setError("Failed to get any shard result, " + Throwables.getStackTraceAsString(e));
}
}
return ResultMerger.merge(request, resultList);
}
Aggregations