/// <summary>
 ///		Update this position after reading another data item
 /// </summary>
 /// <param name="lastReadDataItem">
 ///		Last data item that has been read from this folder
 /// </param>
 public void Update(IDataItem lastReadDataItem)
 {
     if (Time == lastReadDataItem.DateTime)
     {
         ++NumberOfItemsWithTheTimestampRead;
     }
     else
     {
         Time = lastReadDataItem.DateTime;
         NumberOfItemsWithTheTimestampRead = 1;
     }
     VerificationLastReadItemHash = lastReadDataItem.GetBusinessHashCode();
 }
Exemplo n.º 2
0
        private void SkipItemsByExactPosition()
        {
            Check.Require(_position.IsExact, "Position must be exact");
            Check.Require(!_listReader.HasItem || _timeComparison.Compare(_listReader.Current.DateTime, _position.Time) >= 0
                          , "Reader must be alredy rolled forward to the position time");

            IDataItem itemFromPosition = null;

            string warningMessage = string.Empty;

            // skipping items with the timestamp equal to the position time which had already been read
            // note that in exact positions (where IsExact equals true) NumberOfItemsWithTheTimestampRead is always greater than zero,
            // otherwise it's not an exact position and versification is not required;
            // this loop will be executed for exact positions only, at least once (thus we either detect position restore issue or move forward
            // until past the last read item as recorded in the position);
            // if the file does not contain item with timestamp equal to the last read item timestamp in the exact position
            // the item from position will not be found
            FolderSeekStatus.PositionStatus status = FolderSeekStatus.PositionStatus.Success;
            for (
                int n = 0;
                status == FolderSeekStatus.PositionStatus.Success && n < _position.NumberOfItemsWithTheTimestampRead;
                ++n)
            {
                if (!_listReader.HasItem || _listReader.Current.DateTime != _position.Time)
                {
                    // using Round-trip date/time pattern: 2009-06-15T13:45:30.0900000
                    _log.WarnFormat("Restoring position for {0} found item by time ({1:O}) and number ({2})"
                                    , TargetFolder.FolderKey
                                    , _position.Time
                                    , _position.NumberOfItemsWithTheTimestampRead);
                    // loop will break
                    status = FolderSeekStatus.PositionStatus.DataItemNotFound;
                }
                else
                {
                    if (_position.NumberOfItemsWithTheTimestampRead - 1 == n)
                    {
                        // last iteration of the loop: found item by time and number
                        itemFromPosition = _listReader.Current;
                    }
                    // moving to the next only if time matches with position time
                    _listReader.MoveNext();
                }
            }

            if (itemFromPosition != null)
            {
                // have item from position; check hashes
                if (itemFromPosition.GetBusinessHashCode() != _position.VerificationLastReadItemHash)
                {
                    warningMessage = string.Format(
                        "Restoring position for {0} found item by time and number, but its verification failed: hash in position: {1:X8}, actual: {2:X8}"
                        , TargetFolder.FolderKey
                        , _position.VerificationLastReadItemHash
                        , itemFromPosition.GetBusinessHashCode());
                    _log.Warn(warningMessage);
                    status = FolderSeekStatus.PositionStatus.DataItemHashMismatch;
                }
                else
                {
                    _log.InfoFormat("Exact position for {0} restored successfully", TargetFolder.FolderKey);
                }
            }
            else
            {
                Check.Ensure(status == FolderSeekStatus.PositionStatus.DataItemNotFound);
            }

            // reporting issues only
            if (status != FolderSeekStatus.PositionStatus.Success)
            {
                MasterReader.SeekStatusCallback(new FolderSeekStatus(TargetFolder.FolderKey, status, warningMessage));
            }
        }