Exemplo n.º 1
0
        /// <summary>
        /// Saves the specified value to tag's archive candidate hash in the Redis database.
        /// </summary>
        /// <param name="value">The new archive candidate value.</param>
        /// <param name="cancellationToken">The cancellation token for the request.</param>
        /// <returns>
        /// A task that will save the archive candidate value.
        /// </returns>
        private async Task SaveArchiveCandidateValueInternal(ArchiveCandidateValue value, CancellationToken cancellationToken)
        {
            if (_archiveCandidateValue?.Value == null || (value?.Value != null && value.Value.UtcSampleTime > _archiveCandidateValue.Value.UtcSampleTime))
            {
                _archiveCandidateValue = value;
                await Task.WhenAny(_historian.Connection.GetDatabase().HashSetAsync(_archiveCandidateKey, GetHashEntriesForArchiveCandidateValue(value)),
                                   Task.Delay(-1, cancellationToken)).ConfigureAwait(false);

                cancellationToken.ThrowIfCancellationRequested();
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Creates a new <see cref="RedisTagDefinition"/> object.
        /// </summary>
        /// <param name="historian">The owning historian.</param>
        /// <param name="id">The tag ID.</param>
        /// <param name="settings">The tag settings.</param>
        /// <param name="metadata">The metadata for the tag.</param>
        /// <param name="initialTagValues">The initial tag values, used to prime the exception and compression filters for the tag.</param>
        /// <param name="changeHistory">The change history for the tag.</param>
        private RedisTagDefinition(RedisHistorian historian, string id, TagSettings settings, TagMetadata metadata, InitialTagValues initialTagValues, IEnumerable <TagChangeHistoryEntry> changeHistory) : base(historian, id, settings, metadata, CreateTagSecurity(), initialTagValues, changeHistory)
        {
            _historian           = historian ?? throw new ArgumentNullException(nameof(historian));
            _tagDefinitionKey    = _historian.GetKeyForTagDefinition(Id);
            _snapshotKey         = _historian.GetKeyForSnapshotData(Id);
            _archiveKey          = _historian.GetKeyForRawData(Id);
            _archiveCandidateKey = _historian.GetKeyForArchiveCandidateData(Id);

            _archiveCandidateValue = new ArchiveCandidateValue(initialTagValues?.LastExceptionValue, initialTagValues?.CompressionAngleMinimum ?? Double.NaN, initialTagValues?.CompressionAngleMaximum ?? Double.NaN);

            Updated += TagUpdated;
        }
Exemplo n.º 3
0
        /// <summary>
        /// Converts an <see cref="ArchiveCandidateValue"/> into a set of <see cref="HashEntry"/> objects to write to Redis.
        /// </summary>
        /// <param name="value">The archive candidate tag value.</param>
        /// <returns>
        /// The equivalent Redis hash entries.
        /// </returns>
        private HashEntry[] GetHashEntriesForArchiveCandidateValue(ArchiveCandidateValue value)
        {
            if (value == null)
            {
                return(new HashEntry[0]);
            }

            var tagValueHashEntries = GetHashEntriesForTagValue(value.Value);

            return(tagValueHashEntries.Concat(new[] {
                new HashEntry("MI", value.CompressionAngleMinimum),
                new HashEntry("MA", value.CompressionAngleMaximum)
            }).ToArray());
        }
Exemplo n.º 4
0
        /// <summary>
        /// Converts an Aika <see cref="ArchiveCandidateValue"/> into an Elasticsearch <see cref="TagValueDocument"/>.
        /// </summary>
        /// <param name="value">The Aika archive candidate value.</param>
        /// <param name="tag">The tag that the value is for.</param>
        /// <param name="documentId">
        ///   The optional document ID to assign to the <see cref="TagValueDocument"/>.  Specify
        ///   <see langword="null"/> for archive values, and the tag ID for snapshot and archive
        ///   candidate values (so that the existing snapshot or archive candidate document for
        ///   the tag will be replaced).
        /// </param>
        /// <returns>
        /// An equivalent <see cref="TagValueDocument"/>.
        /// </returns>
        /// <exception cref="ArgumentNullException"><paramref name="value"/> is <see langword="null"/>.</exception>
        /// <exception cref="ArgumentNullException"><paramref name="tag"/> is <see langword="null"/>.</exception>
        public static TagValueDocument ToTagValueDocument(this ArchiveCandidateValue value, ElasticsearchTagDefinition tag, Guid?documentId)
        {
            if (value == null)
            {
                throw new ArgumentNullException(nameof(value));
            }
            if (tag == null)
            {
                throw new ArgumentNullException(nameof(tag));
            }

            var val = value?.Value.ToTagValueDocument(tag, documentId);

            val.Properties = new Dictionary <string, object>()
            {
                { "CompressionAngleMinimum", value.CompressionAngleMinimum },
                { "CompressionAngleMaximum", value.CompressionAngleMaximum }
            };

            return(val);
        }
Exemplo n.º 5
0
 /// <summary>
 /// Saves an updated <see cref="ArchiveCandidateValue"/> for a tag.
 /// </summary>
 /// <param name="tagId">The tag ID.</param>
 /// <param name="value">The archive candidate value.</param>
 internal void SaveArchiveCandidateValue(string tagId, ArchiveCandidateValue value)
 {
     _archiveCandidates[tagId] = value;
 }
Exemplo n.º 6
0
 /// <summary>
 /// Inserts tag values into the Elasticsearch archive.
 /// </summary>
 /// <param name="values">The values to write.</param>
 /// <param name="nextArchiveCandidate">The updated archive candidate value.</param>
 /// <param name="cancellationToken">The cancellation token for the request.</param>
 /// <returns>
 /// A task that will return a <see cref="WriteTagValuesResult"/> for the operation.  Due to
 /// the way that Elasticsearch writesare batched and delegated to a background class to be
 /// written in bulk, it is possible that write operations can fail after this method has
 /// returned.
 /// </returns>
 protected override Task <WriteTagValuesResult> InsertArchiveValues(IEnumerable <TagValue> values, ArchiveCandidateValue nextArchiveCandidate, CancellationToken cancellationToken)
 {
     return(_historian.InsertArchiveValues(this, values, nextArchiveCandidate, cancellationToken));
 }
Exemplo n.º 7
0
        /// <summary>
        /// Writes archive values to Redis.
        /// </summary>
        /// <param name="values">The values to write.</param>
        /// <param name="nextArchiveCandidate">The next archive candiate value.</param>
        /// <param name="cancellationToken">The cancellation token for the request.</param>
        /// <returns>
        /// A task that will return the write result.
        /// </returns>
        protected override async Task <WriteTagValuesResult> InsertArchiveValues(IEnumerable <TagValue> values, ArchiveCandidateValue nextArchiveCandidate, CancellationToken cancellationToken)
        {
            await SaveArchiveCandidateValueInternal(nextArchiveCandidate, cancellationToken).ConfigureAwait(false);
            await SaveArchiveValues(values, cancellationToken).ConfigureAwait(false);

            return(new WriteTagValuesResult(true, values?.Count() ?? 0, values?.FirstOrDefault()?.UtcSampleTime, values?.LastOrDefault()?.UtcSampleTime, null));
        }
Exemplo n.º 8
0
        /// <summary>
        /// Inserts values into the historian archive for the tag.
        /// </summary>
        /// <param name="values">The values to archive.</param>
        /// <param name="nextArchiveCandidate">
        ///   The current archive candidate value for the tag (i.e. the next value that might
        ///   potentially be written to the archive).
        /// </param>
        /// <param name="cancellationToken">The cancellation token for the request.</param>
        /// <returns>
        /// The result of the write.
        /// </returns>
        protected override Task <WriteTagValuesResult> InsertArchiveValues(IEnumerable <TagValue> values, ArchiveCandidateValue nextArchiveCandidate, CancellationToken cancellationToken)
        {
            _historian.SaveArchiveCandidateValue(Id, nextArchiveCandidate);
            var result = !(values?.Any() ?? false)
                ? WriteTagValuesResult.CreateEmptyResult()
                : _historian.InsertArchiveValues(Id, values);

            return(Task.FromResult(result));
        }
Exemplo n.º 9
0
 /// <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();
     }
 }