/// <summary> /// Enqueues the specified values for writing. /// </summary> /// <param name="tag">The tag that the values are being written for.</param> /// <param name="values">The values to write to the archive.</param> /// <param name="archiveCandidate">The current archive candidate value for the tag.</param> internal void WriteValues(ElasticsearchTagDefinition tag, IEnumerable <TagValue> values, ArchiveCandidateValue archiveCandidate) { _valuesLock.EnterReadLock(); try { foreach (var value in values ?? new TagValue[0]) { var op = new BulkIndexOperation <TagValueDocument>(value.ToTagValueDocument(tag, null)) { Index = IndexUtility.GetIndexNameForArchiveTagValue(_historian.ArchiveIndexNamePrefix, tag, value.UtcSampleTime, _historian.ArchiveIndexSuffixGenerator) }; _nextInsert.AddOperation(op); } if (archiveCandidate != null) { _archiveCandidateValues[tag.IdAsGuid] = archiveCandidate; } } finally { _valuesLock.ExitReadLock(); } }
/// <summary> /// Creates documents on to the given index /// </summary> public async Task CreateDocumentsAsync <TDocument>(string index, params CreateDocumentRequest <TDocument>[] requests) where TDocument : class, new() { if (string.IsNullOrEmpty(index)) { throw new ArgumentNullException(nameof(index)); } if (requests.Length < 1) { throw new ArgumentException( "At least one document request is needed to create something"); } IEnumerable <BulkCreateDescriptor <TDocument> > createDescriptors = requests .Select(request => new BulkCreateDescriptor <TDocument>() .Document(request.Document) .Id(request.Id)); BulkDescriptor bulkDescriptor = new BulkDescriptor() .Index(index); foreach (BulkCreateDescriptor <TDocument> bulkCreateDescriptor in createDescriptors) { bulkDescriptor.AddOperation(bulkCreateDescriptor); } BulkResponse bulkResponse = await Client.LowLevel.BulkPutAsync <BulkResponse>( index, typeof(TDocument).Name.ToLowerInvariant(), PostData.Serializable(bulkDescriptor)); if (!bulkResponse.IsValid) { throw new InvalidOperationException( $"Could not create the documents: {bulkResponse.DebugInformation}", bulkResponse.OriginalException); } await Client.RefreshAsync(Indices.All); }
/// <summary> /// 批量删除索引 /// </summary> /// <typeparam name="TPrimaryKeyType"></typeparam> /// <param name="ids"></param> /// <param name="routing"></param> /// <returns></returns> public async Task <HttpResponseResultModel <bool> > DeleteBatchAsync <TPrimaryKeyType>(DeleteBatchModel <TPrimaryKeyType> deleteBatchModel) { HttpResponseResultModel <bool> httpResponseResultModel = new HttpResponseResultModel <bool>(); string indexName = deleteBatchModel.IndexName?.ToLower(); if (string.IsNullOrEmpty(indexName)) { indexName = PocoIndexName; } BulkDescriptor bulkDescriptor = new BulkDescriptor(); foreach (var id in deleteBatchModel.IdList) { bulkDescriptor.AddOperation(new BulkDeleteOperation <TEntity>(id.ToString())); } bulkDescriptor.Index(indexName); if (!string.IsNullOrEmpty(deleteBatchModel.Routing)) { bulkDescriptor.Routing(new Routing(deleteBatchModel.Routing)); } var result = await client.BulkAsync(bulkDescriptor).ConfigureAwait(false); GetDebugInfo(result); var isSuccess = result.ItemsWithErrors.IsListNullOrEmpty(); httpResponseResultModel.IsSuccess = isSuccess; string errorMessage = ""; if (!isSuccess) { var errorIdList = result.ItemsWithErrors.Select(t => t.Id); errorMessage = string.Join(",", errorIdList); } httpResponseResultModel.ErrorMessage = errorMessage; return(httpResponseResultModel); }
/// <summary> /// Runs the writer operation. /// </summary> /// <param name="cancellationToken">The cancellation token that will signal when the writer is to stop.</param> /// <returns> /// A task that will complete when cancellation is requested. /// </returns> /// <exception cref="ObjectDisposedException">The object has already been disposed.</exception> internal async Task Execute(CancellationToken cancellationToken) { if (_ctSource.Token.IsCancellationRequested) { throw new ObjectDisposedException(GetType().FullName); } cancellationToken.Register(() => _ctSource.Cancel()); while (!_ctSource.Token.IsCancellationRequested) { await Task.Delay(_interval, _ctSource.Token).ConfigureAwait(false); if (Interlocked.CompareExchange(ref _taskLock, 1, 0) != 0) { continue; } IDictionary <Guid, TagValue> values; _valuesLock.EnterWriteLock(); try { if (_values.Count == 0) { _taskLock = 0; continue; } values = _values.ToDictionary(x => x.Key, x => x.Value); _values.Clear(); } finally { _valuesLock.ExitWriteLock(); } _historian.TaskRunner.RunBackgroundTask(async ct => { try { var descriptor = new BulkDescriptor(); var send = false; foreach (var item in values) { var tag = _historian.GetTagById(item.Key); if (tag == null) { continue; } var op = new BulkIndexOperation <TagValueDocument>(item.Value.ToTagValueDocument(tag, tag.IdAsGuid)) { Index = _historian.SnapshotValuesIndexName }; descriptor.AddOperation(op); send = true; } if (send) { await _historian.Client.BulkAsync(descriptor, ct).ConfigureAwait(false); } } catch (Exception e) { _logger?.LogError("An error occurred while writing a bulk snapshot update.", e); } finally { _taskLock = 0; } }, _ctSource.Token); } }