use of com.xiaomi.linden.thrift.common.Response 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.xiaomi.linden.thrift.common.Response 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.xiaomi.linden.thrift.common.Response 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.xiaomi.linden.thrift.common.Response in project linden by XiaoMi.
the class HotSwapLindenCoreImpl method index.
@Override
public Response index(LindenIndexRequest request) throws IOException {
if (request.getType().equals(IndexRequestType.SWAP_INDEX)) {
Response response;
try {
response = swapIndex(request.getIndexName());
} catch (Exception e) {
LOGGER.error("Swapping index " + request.getIndexName() + " failed, " + e);
throw new IOException("Swapping index " + request.getIndexName() + " failed!", e);
}
return response;
}
String indexName = request.getIndexName();
LindenCore core = currentLindenCore;
if (indexName != null && !indexName.equals(currentIndexName)) {
if (indexName.startsWith(NEXT_INDEX_NAME_PREFIX)) {
// that swap command is executed before bootstrap is done
if (!indexName.substring(NEXT_INDEX_NAME_PREFIX.length()).equals(currentIndexVersion)) {
core = getLindenCore(indexName);
}
} else {
throw new IOException("Bad index name " + indexName + " in HotSwapLindenCoreImpl.");
}
}
return core.index(request);
}
use of com.xiaomi.linden.thrift.common.Response in project linden by XiaoMi.
the class MultiLindenCoreImpl method delete.
private Response delete(LindenIndexRequest request) throws IOException {
StringBuilder errorInfo = new StringBuilder();
for (Map.Entry<String, LindenCore> entry : lindenCoreMap.entrySet()) {
try {
Response response = entry.getValue().index(request);
if (!response.isSuccess()) {
errorInfo.append(entry.getKey() + ":" + response.getError() + ";");
LOGGER.error("Multi Linden core index {} delete error: {}", entry.getKey(), response.error);
}
} catch (Exception e) {
errorInfo.append(entry.getKey() + ":" + Throwables.getStackTraceAsString(e) + ";");
LOGGER.error("Multi index delete index {} error: {}.", entry.getKey(), Throwables.getStackTraceAsString(e));
}
}
if (errorInfo.length() > 0) {
return ResponseUtils.buildFailedResponse("Multi index delete index error: " + errorInfo.toString());
}
return ResponseUtils.SUCCESS;
}
Aggregations