Use bulk action interally for update action (#22915)
Currently, update action internally uses deprecated index and delete transport actions. As of #21964, these tranport actions were deprecated in favour of using single item bulk request. In this commit, update action uses single item bulk action.
This commit is contained in:
parent
7520a107be
commit
ba8ad397a1
|
@ -107,7 +107,8 @@ public abstract class TransportSingleItemBulkWriteAction<
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private ActionListener<BulkResponse> wrapBulkResponse(ActionListener<Response> listener) {
|
public static <Response extends ReplicationResponse & WriteResponse>
|
||||||
|
ActionListener<BulkResponse> wrapBulkResponse(ActionListener<Response> listener) {
|
||||||
return ActionListener.wrap(bulkItemResponses -> {
|
return ActionListener.wrap(bulkItemResponses -> {
|
||||||
assert bulkItemResponses.getItems().length == 1 : "expected only one item in bulk request";
|
assert bulkItemResponses.getItems().length == 1 : "expected only one item in bulk request";
|
||||||
BulkItemResponse bulkItemResponse = bulkItemResponses.getItems()[0];
|
BulkItemResponse bulkItemResponse = bulkItemResponses.getItems()[0];
|
||||||
|
|
|
@ -19,19 +19,17 @@
|
||||||
|
|
||||||
package org.elasticsearch.action.update;
|
package org.elasticsearch.action.update;
|
||||||
|
|
||||||
import org.elasticsearch.ExceptionsHelper;
|
|
||||||
import org.elasticsearch.action.ActionListener;
|
import org.elasticsearch.action.ActionListener;
|
||||||
import org.elasticsearch.action.ActionRunnable;
|
import org.elasticsearch.action.ActionRunnable;
|
||||||
import org.elasticsearch.action.RoutingMissingException;
|
import org.elasticsearch.action.RoutingMissingException;
|
||||||
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
|
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
|
||||||
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
|
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
|
||||||
import org.elasticsearch.action.admin.indices.create.TransportCreateIndexAction;
|
import org.elasticsearch.action.admin.indices.create.TransportCreateIndexAction;
|
||||||
|
import org.elasticsearch.action.bulk.TransportBulkAction;
|
||||||
import org.elasticsearch.action.delete.DeleteRequest;
|
import org.elasticsearch.action.delete.DeleteRequest;
|
||||||
import org.elasticsearch.action.delete.DeleteResponse;
|
import org.elasticsearch.action.delete.DeleteResponse;
|
||||||
import org.elasticsearch.action.delete.TransportDeleteAction;
|
|
||||||
import org.elasticsearch.action.index.IndexRequest;
|
import org.elasticsearch.action.index.IndexRequest;
|
||||||
import org.elasticsearch.action.index.IndexResponse;
|
import org.elasticsearch.action.index.IndexResponse;
|
||||||
import org.elasticsearch.action.index.TransportIndexAction;
|
|
||||||
import org.elasticsearch.action.support.ActionFilters;
|
import org.elasticsearch.action.support.ActionFilters;
|
||||||
import org.elasticsearch.action.support.AutoCreateIndex;
|
import org.elasticsearch.action.support.AutoCreateIndex;
|
||||||
import org.elasticsearch.action.support.TransportActions;
|
import org.elasticsearch.action.support.TransportActions;
|
||||||
|
@ -63,11 +61,12 @@ import java.util.Collections;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static org.elasticsearch.ExceptionsHelper.unwrapCause;
|
import static org.elasticsearch.ExceptionsHelper.unwrapCause;
|
||||||
|
import static org.elasticsearch.action.bulk.TransportSingleItemBulkWriteAction.toSingleItemBulkRequest;
|
||||||
|
import static org.elasticsearch.action.bulk.TransportSingleItemBulkWriteAction.wrapBulkResponse;
|
||||||
|
|
||||||
public class TransportUpdateAction extends TransportInstanceSingleOperationAction<UpdateRequest, UpdateResponse> {
|
public class TransportUpdateAction extends TransportInstanceSingleOperationAction<UpdateRequest, UpdateResponse> {
|
||||||
|
|
||||||
private final TransportDeleteAction deleteAction;
|
private final TransportBulkAction bulkAction;
|
||||||
private final TransportIndexAction indexAction;
|
|
||||||
private final AutoCreateIndex autoCreateIndex;
|
private final AutoCreateIndex autoCreateIndex;
|
||||||
private final TransportCreateIndexAction createIndexAction;
|
private final TransportCreateIndexAction createIndexAction;
|
||||||
private final UpdateHelper updateHelper;
|
private final UpdateHelper updateHelper;
|
||||||
|
@ -75,12 +74,10 @@ public class TransportUpdateAction extends TransportInstanceSingleOperationActio
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public TransportUpdateAction(Settings settings, ThreadPool threadPool, ClusterService clusterService, TransportService transportService,
|
public TransportUpdateAction(Settings settings, ThreadPool threadPool, ClusterService clusterService, TransportService transportService,
|
||||||
TransportIndexAction indexAction, TransportDeleteAction deleteAction, TransportCreateIndexAction createIndexAction,
|
TransportBulkAction bulkAction, TransportCreateIndexAction createIndexAction, UpdateHelper updateHelper, ActionFilters actionFilters,
|
||||||
UpdateHelper updateHelper, ActionFilters actionFilters, IndexNameExpressionResolver indexNameExpressionResolver,
|
IndexNameExpressionResolver indexNameExpressionResolver, IndicesService indicesService, AutoCreateIndex autoCreateIndex) {
|
||||||
IndicesService indicesService, AutoCreateIndex autoCreateIndex) {
|
|
||||||
super(settings, UpdateAction.NAME, threadPool, clusterService, transportService, actionFilters, indexNameExpressionResolver, UpdateRequest::new);
|
super(settings, UpdateAction.NAME, threadPool, clusterService, transportService, actionFilters, indexNameExpressionResolver, UpdateRequest::new);
|
||||||
this.indexAction = indexAction;
|
this.bulkAction = bulkAction;
|
||||||
this.deleteAction = deleteAction;
|
|
||||||
this.createIndexAction = createIndexAction;
|
this.createIndexAction = createIndexAction;
|
||||||
this.updateHelper = updateHelper;
|
this.updateHelper = updateHelper;
|
||||||
this.indicesService = indicesService;
|
this.indicesService = indicesService;
|
||||||
|
@ -162,7 +159,7 @@ public class TransportUpdateAction extends TransportInstanceSingleOperationActio
|
||||||
return new PlainShardIterator(shardIterator.shardId(), Collections.singletonList(shard));
|
return new PlainShardIterator(shardIterator.shardId(), Collections.singletonList(shard));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new PlainShardIterator(shardIterator.shardId(), Collections.<ShardRouting>emptyList());
|
return new PlainShardIterator(shardIterator.shardId(), Collections.emptyList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -180,101 +177,46 @@ public class TransportUpdateAction extends TransportInstanceSingleOperationActio
|
||||||
IndexRequest upsertRequest = result.action();
|
IndexRequest upsertRequest = result.action();
|
||||||
// we fetch it from the index request so we don't generate the bytes twice, its already done in the index request
|
// we fetch it from the index request so we don't generate the bytes twice, its already done in the index request
|
||||||
final BytesReference upsertSourceBytes = upsertRequest.source();
|
final BytesReference upsertSourceBytes = upsertRequest.source();
|
||||||
indexAction.execute(upsertRequest, new ActionListener<IndexResponse>() {
|
bulkAction.execute(toSingleItemBulkRequest(upsertRequest), wrapBulkResponse(
|
||||||
@Override
|
ActionListener.<IndexResponse>wrap(response -> {
|
||||||
public void onResponse(IndexResponse response) {
|
UpdateResponse update = new UpdateResponse(response.getShardInfo(), response.getShardId(), response.getType(), response.getId(), response.getSeqNo(), response.getVersion(), response.getResult());
|
||||||
UpdateResponse update = new UpdateResponse(response.getShardInfo(), response.getShardId(), response.getType(), response.getId(), response.getSeqNo(), response.getVersion(), response.getResult());
|
if ((request.fetchSource() != null && request.fetchSource().fetchSource()) ||
|
||||||
if ((request.fetchSource() != null && request.fetchSource().fetchSource()) ||
|
(request.fields() != null && request.fields().length > 0)) {
|
||||||
(request.fields() != null && request.fields().length > 0)) {
|
Tuple<XContentType, Map<String, Object>> sourceAndContent =
|
||||||
Tuple<XContentType, Map<String, Object>> sourceAndContent =
|
XContentHelper.convertToMap(upsertSourceBytes, true, upsertRequest.getContentType());
|
||||||
XContentHelper.convertToMap(upsertSourceBytes, true, upsertRequest.getContentType());
|
update.setGetResult(updateHelper.extractGetResult(request, request.concreteIndex(), response.getVersion(), sourceAndContent.v2(), sourceAndContent.v1(), upsertSourceBytes));
|
||||||
update.setGetResult(updateHelper.extractGetResult(request, request.concreteIndex(), response.getVersion(), sourceAndContent.v2(), sourceAndContent.v1(), upsertSourceBytes));
|
} else {
|
||||||
} else {
|
update.setGetResult(null);
|
||||||
update.setGetResult(null);
|
|
||||||
}
|
|
||||||
update.setForcedRefresh(response.forcedRefresh());
|
|
||||||
listener.onResponse(update);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(Exception e) {
|
|
||||||
final Throwable cause = ExceptionsHelper.unwrapCause(e);
|
|
||||||
if (cause instanceof VersionConflictEngineException) {
|
|
||||||
if (retryCount < request.retryOnConflict()) {
|
|
||||||
logger.trace("Retry attempt [{}] of [{}] on version conflict on [{}][{}][{}]",
|
|
||||||
retryCount + 1, request.retryOnConflict(), request.index(), request.getShardId(), request.id());
|
|
||||||
threadPool.executor(executor()).execute(new ActionRunnable<UpdateResponse>(listener) {
|
|
||||||
@Override
|
|
||||||
protected void doRun() {
|
|
||||||
shardOperation(request, listener, retryCount + 1);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
update.setForcedRefresh(response.forcedRefresh());
|
||||||
listener.onFailure(cause instanceof Exception ? (Exception) cause : new NotSerializableExceptionWrapper(cause));
|
listener.onResponse(update);
|
||||||
}
|
}, exception -> handleUpdateFailureWithRetry(listener, request, exception, retryCount)))
|
||||||
});
|
);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case UPDATED:
|
case UPDATED:
|
||||||
IndexRequest indexRequest = result.action();
|
IndexRequest indexRequest = result.action();
|
||||||
// we fetch it from the index request so we don't generate the bytes twice, its already done in the index request
|
// we fetch it from the index request so we don't generate the bytes twice, its already done in the index request
|
||||||
final BytesReference indexSourceBytes = indexRequest.source();
|
final BytesReference indexSourceBytes = indexRequest.source();
|
||||||
indexAction.execute(indexRequest, new ActionListener<IndexResponse>() {
|
bulkAction.execute(toSingleItemBulkRequest(indexRequest), wrapBulkResponse(
|
||||||
@Override
|
ActionListener.<IndexResponse>wrap(response -> {
|
||||||
public void onResponse(IndexResponse response) {
|
UpdateResponse update = new UpdateResponse(response.getShardInfo(), response.getShardId(), response.getType(), response.getId(), response.getSeqNo(), response.getVersion(), response.getResult());
|
||||||
UpdateResponse update = new UpdateResponse(response.getShardInfo(), response.getShardId(), response.getType(), response.getId(), response.getSeqNo(), response.getVersion(), response.getResult());
|
update.setGetResult(updateHelper.extractGetResult(request, request.concreteIndex(), response.getVersion(), result.updatedSourceAsMap(), result.updateSourceContentType(), indexSourceBytes));
|
||||||
update.setGetResult(updateHelper.extractGetResult(request, request.concreteIndex(), response.getVersion(), result.updatedSourceAsMap(), result.updateSourceContentType(), indexSourceBytes));
|
update.setForcedRefresh(response.forcedRefresh());
|
||||||
update.setForcedRefresh(response.forcedRefresh());
|
listener.onResponse(update);
|
||||||
listener.onResponse(update);
|
}, exception -> handleUpdateFailureWithRetry(listener, request, exception, retryCount)))
|
||||||
}
|
);
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(Exception e) {
|
|
||||||
final Throwable cause = unwrapCause(e);
|
|
||||||
if (cause instanceof VersionConflictEngineException) {
|
|
||||||
if (retryCount < request.retryOnConflict()) {
|
|
||||||
threadPool.executor(executor()).execute(new ActionRunnable<UpdateResponse>(listener) {
|
|
||||||
@Override
|
|
||||||
protected void doRun() {
|
|
||||||
shardOperation(request, listener, retryCount + 1);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
listener.onFailure(cause instanceof Exception ? (Exception) cause : new NotSerializableExceptionWrapper(cause));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
case DELETED:
|
case DELETED:
|
||||||
DeleteRequest deleteRequest = result.action();
|
DeleteRequest deleteRequest = result.action();
|
||||||
deleteAction.execute(deleteRequest, new ActionListener<DeleteResponse>() {
|
bulkAction.execute(toSingleItemBulkRequest(deleteRequest), wrapBulkResponse(
|
||||||
@Override
|
ActionListener.<DeleteResponse>wrap(response -> {
|
||||||
public void onResponse(DeleteResponse response) {
|
UpdateResponse update = new UpdateResponse(response.getShardInfo(), response.getShardId(), response.getType(), response.getId(), response.getSeqNo(), response.getVersion(), response.getResult());
|
||||||
UpdateResponse update = new UpdateResponse(response.getShardInfo(), response.getShardId(), response.getType(), response.getId(), response.getSeqNo(), response.getVersion(), response.getResult());
|
update.setGetResult(updateHelper.extractGetResult(request, request.concreteIndex(), response.getVersion(), result.updatedSourceAsMap(), result.updateSourceContentType(), null));
|
||||||
update.setGetResult(updateHelper.extractGetResult(request, request.concreteIndex(), response.getVersion(), result.updatedSourceAsMap(), result.updateSourceContentType(), null));
|
update.setForcedRefresh(response.forcedRefresh());
|
||||||
update.setForcedRefresh(response.forcedRefresh());
|
listener.onResponse(update);
|
||||||
listener.onResponse(update);
|
}, exception -> handleUpdateFailureWithRetry(listener, request, exception, retryCount)))
|
||||||
}
|
);
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(Exception e) {
|
|
||||||
final Throwable cause = unwrapCause(e);
|
|
||||||
if (cause instanceof VersionConflictEngineException) {
|
|
||||||
if (retryCount < request.retryOnConflict()) {
|
|
||||||
threadPool.executor(executor()).execute(new ActionRunnable<UpdateResponse>(listener) {
|
|
||||||
@Override
|
|
||||||
protected void doRun() {
|
|
||||||
shardOperation(request, listener, retryCount + 1);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
listener.onFailure(cause instanceof Exception ? (Exception) cause : new NotSerializableExceptionWrapper(cause));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
case NOOP:
|
case NOOP:
|
||||||
UpdateResponse update = result.action();
|
UpdateResponse update = result.action();
|
||||||
|
@ -291,4 +233,23 @@ public class TransportUpdateAction extends TransportInstanceSingleOperationActio
|
||||||
throw new IllegalStateException("Illegal result " + result.getResponseResult());
|
throw new IllegalStateException("Illegal result " + result.getResponseResult());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void handleUpdateFailureWithRetry(final ActionListener<UpdateResponse> listener, final UpdateRequest request,
|
||||||
|
final Exception failure, int retryCount) {
|
||||||
|
final Throwable cause = unwrapCause(failure);
|
||||||
|
if (cause instanceof VersionConflictEngineException) {
|
||||||
|
if (retryCount < request.retryOnConflict()) {
|
||||||
|
logger.trace("Retry attempt [{}] of [{}] on version conflict on [{}][{}][{}]",
|
||||||
|
retryCount + 1, request.retryOnConflict(), request.index(), request.getShardId(), request.id());
|
||||||
|
threadPool.executor(executor()).execute(new ActionRunnable<UpdateResponse>(listener) {
|
||||||
|
@Override
|
||||||
|
protected void doRun() {
|
||||||
|
shardOperation(request, listener, retryCount + 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
listener.onFailure(cause instanceof Exception ? (Exception) cause : new NotSerializableExceptionWrapper(cause));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue