私はversion_conflict_engine_exception
と再試行の更新処理を担当Retry
方法Update
public class SampleElasticClient
{
private const string VERSION_CONFLICT_ERROR = "version_conflict_engine_exception";
protected readonly string IndexName;
protected readonly ElasticClient Client;
public SampleElasticClient(Uri uri, string indexName)
{
Client = new ElasticClient(new ConnectionSettings(uri).DefaultIndex(indexName));
IndexName = indexName;
}
public IGetResponse<T> Get<T>(Id id) where T : class
{
var request = new GetRequest<T>(IndexName, typeof(T), id);
var response = Client.Get<T>(request);
EnsureSuccessResponse(response);
return response;
}
public void Update<T>(Id id, Func<T, T> update, int retriesCount = 10) where T : class
{
Retry(() =>
{
var getResponse = Get<T>(id);
var item = update(getResponse.Source);
return Client.Index(item, index => getResponse.Found
? index.Version(getResponse.Version)
: index.OpType(OpType.Create));
}, retriesCount);
}
protected void EnsureSuccessResponse(IResponse response)
{
if (!response.IsValid && response.ApiCall.HttpStatusCode != 404)
{
var errorMessage = response.ServerError != null
? $"ElasticSearch error: {response.ServerError.Error}\r\n" +
$"Http status: {response.ServerError.Status}"
: $"ElasticSearch error. {response.DebugInformation}";
throw new Exception(errorMessage);
}
}
protected void Retry(Func<IResponse> execute, int retriesCount)
{
var numberOfRetry = 0;
do
{
var response = execute();
if (response.ServerError?.Error.Type != VERSION_CONFLICT_ERROR || ++numberOfRetry == retriesCount)
{
EnsureSuccessResponse(response);
return;
}
} while (true);
}
}
をバージョニング含ん以下のクラスを使用します。 Update
メソッドentherは、インデックスから取得したエンティティを処理するためにラムダを使用してエンティティを挿入または更新します。ここで私は、ESとNESTとの楽観的同時実行制御について数年前にブログ記事を書いた、このクラスに
var client = new SampleElasticClient(new Uri("http://localhost:9200"), indexName);
var id = 123;
client.Update<Sample>(id, entity =>
{
if (entity == null)
entity = new Sample { Id = id }; // Or any other action for new entity
entity.MyField = "new value";
return entity;
});
を使用しての例です。http://forloop.co.uk/blog/optimistic-concurrency-with -elasticsearch-and-nestはElasticsearch 1.xとNEST 1.xを使用していますが、基本的には2.xと5.xと同じです。 –
これは機能の実装方法に関する明確なコンテキストを示しています。ありがとう、トン! –
こんにちは@RussCam、あなたの記事では、ElasticsearchServerExceptionオブジェクトを使用して、再試行を捕まえて処理することに気付きました。何らかの理由で私は自分のコードでこのオブジェクトにアクセスできません。私はElasticsearchClientExceptionを参照してください。サーバー例外にアクセスする方法を指摘できますか? –