Esempio n. 1
0
        private bool m_disposed;                                        // Object disposed flag

        #endregion

        #region [ Constructors ]

        /// <summary>
        /// Creates a new <see cref="FrameQueue"/>.
        /// </summary>
        internal FrameQueue(CreateNewFrameFunction createNewFrame)
        {
            m_createNewFrame = createNewFrame;
            m_frameList = new LinkedList<TrackingFrame>();
            m_frameHash = new ConcurrentDictionary<long, TrackingFrame>();
            m_queueLock = new SpinLock();
            m_downsamplingMethod = DownsamplingMethod.LastReceived;
        }
Esempio n. 2
0
        private bool m_disposed;                                        // Object disposed flag

        #endregion

        #region [ Constructors ]

        /// <summary>
        /// Creates a new <see cref="FrameQueue"/>.
        /// </summary>
        internal FrameQueue(CreateNewFrameFunction createNewFrame)
        {
            m_createNewFrame     = createNewFrame;
            m_frameList          = new LinkedList <TrackingFrame>();
            m_frameHash          = new ConcurrentDictionary <long, TrackingFrame>();
            m_queueLock          = new SpinLock();
            m_downsamplingMethod = DownsamplingMethod.LastReceived;
        }
Esempio n. 3
0
 private DatapointDatabase(string path, float downsamplingFactor, DownsamplingMethod downsamplingMethod, int maxRetention, IList <Archive> archives, Func <DateTime> currentTimeProvider)
 {
     this.path = path;
     this.downsamplingFactor  = downsamplingFactor;
     this.downsamplingMethod  = downsamplingMethod;
     this.maxRetention        = maxRetention;
     this.archives            = archives;
     this.currentTimeProvider = currentTimeProvider ?? (() => DateTime.UtcNow);
 }
Esempio n. 4
0
        /// <summary>
        /// Constructs a new <see cref="TrackingFrame"/> given the specified parameters.
        /// </summary>
        /// <param name="sourceFrame">Source <see cref="IFrame"/> to track.</param>
        /// <param name="downsamplingMethod"><see cref="DownsamplingMethod"/> to apply.</param>
        public TrackingFrame(IFrame sourceFrame, DownsamplingMethod downsamplingMethod)
        {
            m_sourceFrame = sourceFrame;
            m_timestamp = sourceFrame.Timestamp;
            m_downsamplingMethod = downsamplingMethod;
            m_frameLock = new ReaderWriterSpinLock();

            if (downsamplingMethod != DownsamplingMethod.LastReceived)
                m_measurements = new ConcurrentDictionary<MeasurementKey, List<IMeasurement>>();
        }
Esempio n. 5
0
        /// <summary>
        /// Creates a new instance of the <see cref="SynchronizedSubscriptionInfo"/> class.
        /// </summary>
        /// <param name="remotelySynchronized">Flag that determines whether the subscription defined by this object is remotely synchronized or locally synchronized.</param>
        /// <param name="framesPerSecond">Frame rate of the subscription in frames per second.</param>
        public SynchronizedSubscriptionInfo(bool remotelySynchronized, int framesPerSecond)
        {
            m_remotelySynchronized = remotelySynchronized;

            m_framesPerSecond           = framesPerSecond;
            m_downsamplingMethod        = DownsamplingMethod.LastReceived;
            m_allowPreemptivePublishing = true;

            m_allowSortsByArrival = true;
            m_timeResolution      = Ticks.PerMillisecond;
        }
Esempio n. 6
0
        /// <summary>
        /// Constructs a new <see cref="TrackingFrame"/> given the specified parameters.
        /// </summary>
        /// <param name="sourceFrame">Source <see cref="IFrame"/> to track.</param>
        /// <param name="downsamplingMethod"><see cref="DownsamplingMethod"/> to apply.</param>
        public TrackingFrame(IFrame sourceFrame, DownsamplingMethod downsamplingMethod)
        {
            m_sourceFrame        = sourceFrame;
            m_timestamp          = sourceFrame.Timestamp;
            m_downsamplingMethod = downsamplingMethod;
            m_frameLock          = new ReaderWriterSpinLock();

            if (downsamplingMethod != DownsamplingMethod.LastReceived)
            {
                m_measurements = new ConcurrentDictionary <MeasurementKey, List <IMeasurement> >();
            }
        }
Esempio n. 7
0
        private static double Aggregate(IEnumerable <double> values, DownsamplingMethod downsamplingMethod)
        {
            switch (downsamplingMethod)
            {
            case DownsamplingMethod.Average:
                return(values.Average());

            case DownsamplingMethod.Sum:
                return(values.Sum());

            case DownsamplingMethod.Last:
                return(values.Last());

            case DownsamplingMethod.Max:
                return(values.Max());

            case DownsamplingMethod.Min:
                return(values.Min());

            default:
                throw new ArgumentOutOfRangeException("downsamplingMethod");
            }
        }
Esempio n. 8
0
        private bool m_disposed;                            // Disposed flag detects redundant calls to dispose method

        #endregion

        #region [ Constructors ]

        /// <summary>
        /// Creates a new <see cref="ConcentratorBase"/>.
        /// </summary>
        /// <remarks>
        /// Concentration will not begin until consumer "Starts" concentrator (i.e., calling <see cref="ConcentratorBase.Start"/> method or setting
        /// <c><see cref="ConcentratorBase.Enabled"/> = true</c>).
        /// </remarks>
        protected ConcentratorBase()
        {
            m_usePrecisionTimer = true;
            m_allowSortsByArrival = true;
            m_allowPreemptivePublishing = true;
            m_performTimestampReasonabilityCheck = true;
            m_processingInterval = -1;
            m_downsamplingMethod = DownsamplingMethod.LastReceived;
            m_latestMeasurements = new ImmediateMeasurements(this);
            m_maximumPublicationTimeout = Timeout.Infinite;

            // Create a new queue for managing real-time frames
            m_frameQueue = new FrameQueue(this.CreateNewFrame);

            // Set minimum timer resolution to one millisecond to improve timer accuracy
            PrecisionTimer.SetMinimumTimerResolution(1);

            // Create publication wait handle
            m_publicationWaitHandle = new AutoResetEvent(false);

            // Create publication thread - this may be one of the few times when you can
            // accurately argue that you need high priority thread scheduling...
            m_publicationThread = new Thread(PublishFrames);
            m_publicationThread.Priority = ThreadPriority.Highest;
            m_publicationThread.Start();

            // This timer monitors the total number of unpublished samples every 5 seconds. This is a useful statistic
            // to monitor: if total number of unpublished samples exceed lag time, measurement concentration could
            // be falling behind.
            m_monitorTimer = new System.Timers.Timer();
            m_monitorTimer.Interval = 5000;
            m_monitorTimer.AutoReset = true;
            m_monitorTimer.Elapsed += MonitorUnpublishedSamples;
        }
Esempio n. 9
0
        public virtual bool LocallySynchronizedSubscribe(bool compactFormat, int framesPerSecond, double lagTime, double leadTime, string filterExpression, string dataChannel = null, bool useLocalClockAsRealTime = false, bool ignoreBadTimestamps = false, bool allowSortsByArrival = true, long timeResolution = Ticks.PerMillisecond, bool allowPreemptivePublishing = true, DownsamplingMethod downsamplingMethod = DownsamplingMethod.LastReceived, string startTime = null, string stopTime = null, string constraintParameters = null, int processingInterval = -1, string waitHandleNames = null, int waitHandleTimeout = 0)
        {
            // Dispose of any previously established local concentrator
            DisposeLocalConcentrator();

            // Establish a local concentrator to synchronize received measurements
            m_localConcentrator = new LocalConcentrator(this);
            m_localConcentrator.ProcessException += m_localConcentrator_ProcessException;
            m_localConcentrator.FramesPerSecond = framesPerSecond;
            m_localConcentrator.LagTime = lagTime;
            m_localConcentrator.LeadTime = leadTime;
            m_localConcentrator.UseLocalClockAsRealTime = useLocalClockAsRealTime;
            m_localConcentrator.IgnoreBadTimestamps = ignoreBadTimestamps;
            m_localConcentrator.AllowSortsByArrival = allowSortsByArrival;
            m_localConcentrator.TimeResolution = timeResolution;
            m_localConcentrator.AllowPreemptivePublishing = allowPreemptivePublishing;
            m_localConcentrator.DownsamplingMethod = downsamplingMethod;
            m_localConcentrator.UsePrecisionTimer = false;

            // Parse time constraints, if defined
            DateTime startTimeConstraint = !string.IsNullOrWhiteSpace(startTime) ? ParseTimeTag(startTime) : DateTime.MinValue;
            DateTime stopTimeConstraint = !string.IsNullOrWhiteSpace(stopTime) ? ParseTimeTag(stopTime) : DateTime.MaxValue;

            // When processing historical data, timestamps should not be evaluated for reasonability
            if (startTimeConstraint != DateTime.MinValue || stopTimeConstraint != DateTime.MaxValue)
            {
                m_localConcentrator.PerformTimestampReasonabilityCheck = false;
                m_localConcentrator.LeadTime = double.MaxValue;
            }

            // Assign alternate processing interval, if defined
            if (processingInterval != -1)
                m_localConcentrator.ProcessingInterval = processingInterval;

            // Initiate unsynchronized subscribe
            StringBuilder connectionString = new StringBuilder();
            AssemblyInfo assemblyInfo = AssemblyInfo.ExecutingAssembly;

            connectionString.AppendFormat("trackLatestMeasurements={0}; ", false);
            connectionString.AppendFormat("inputMeasurementKeys={{{0}}}; ", filterExpression.ToNonNullString());
            connectionString.AppendFormat("dataChannel={{{0}}}; ", dataChannel.ToNonNullString());
            connectionString.AppendFormat("includeTime={0}; ", true);
            connectionString.AppendFormat("lagTime={0}; ", 10.0D);
            connectionString.AppendFormat("leadTime={0}; ", 5.0D);
            connectionString.AppendFormat("useLocalClockAsRealTime={0}; ", false);
            connectionString.AppendFormat("startTimeConstraint={0}; ", startTime.ToNonNullString());
            connectionString.AppendFormat("stopTimeConstraint={0}; ", stopTime.ToNonNullString());
            connectionString.AppendFormat("timeConstraintParameters={0}; ", constraintParameters.ToNonNullString());
            connectionString.AppendFormat("processingInterval={0}; ", processingInterval);
            connectionString.AppendFormat("useMillisecondResolution={0}; ", m_useMillisecondResolution);
            connectionString.AppendFormat("assemblyInfo={{source={0}; version={1}.{2}.{3}; buildDate={4}}}", assemblyInfo.Name, assemblyInfo.Version.Major, assemblyInfo.Version.Minor, assemblyInfo.Version.Build, assemblyInfo.BuildDate.ToString("yyyy-MM-dd HH:mm:ss"));

            if (!string.IsNullOrWhiteSpace(waitHandleNames))
            {
                connectionString.AppendFormat("; waitHandleNames={0}", waitHandleNames);
                connectionString.AppendFormat("; waitHandleTimeout={0}", waitHandleTimeout);
            }

            // Start subscription process
            if (Subscribe(false, compactFormat, connectionString.ToString()))
            {
                // If subscription succeeds, start local concentrator
                m_localConcentrator.Start();
                return true;
            }

            return false;
        }
Esempio n. 10
0
        public virtual bool RemotelySynchronizedSubscribe(bool compactFormat, int framesPerSecond, double lagTime, double leadTime, string filterExpression, string dataChannel = null, bool useLocalClockAsRealTime = false, bool ignoreBadTimestamps = false, bool allowSortsByArrival = true, long timeResolution = Ticks.PerMillisecond, bool allowPreemptivePublishing = true, DownsamplingMethod downsamplingMethod = DownsamplingMethod.LastReceived, string startTime = null, string stopTime = null, string constraintParameters = null, int processingInterval = -1, string waitHandleNames = null, int waitHandleTimeout = 0)
        {
            // Dispose of any previously established local concentrator
            DisposeLocalConcentrator();

            StringBuilder connectionString = new StringBuilder();
            AssemblyInfo assemblyInfo = AssemblyInfo.ExecutingAssembly;

            connectionString.AppendFormat("framesPerSecond={0}; ", framesPerSecond);
            connectionString.AppendFormat("lagTime={0}; ", lagTime);
            connectionString.AppendFormat("leadTime={0}; ", leadTime);
            connectionString.AppendFormat("inputMeasurementKeys={{{0}}}; ", filterExpression.ToNonNullString());
            connectionString.AppendFormat("dataChannel={{{0}}}; ", dataChannel.ToNonNullString());
            connectionString.AppendFormat("includeTime=false; ");
            connectionString.AppendFormat("useLocalClockAsRealTime={0}; ", useLocalClockAsRealTime);
            connectionString.AppendFormat("ignoreBadTimestamps={0}; ", ignoreBadTimestamps);
            connectionString.AppendFormat("allowSortsByArrival={0}; ", allowSortsByArrival);
            connectionString.AppendFormat("timeResolution={0}; ", (long)timeResolution);
            connectionString.AppendFormat("allowPreemptivePublishing={0}; ", allowPreemptivePublishing);
            connectionString.AppendFormat("downsamplingMethod={0}; ", downsamplingMethod.ToString());
            connectionString.AppendFormat("startTimeConstraint={0}; ", startTime.ToNonNullString());
            connectionString.AppendFormat("stopTimeConstraint={0}; ", stopTime.ToNonNullString());
            connectionString.AppendFormat("timeConstraintParameters={0}; ", constraintParameters.ToNonNullString());
            connectionString.AppendFormat("processingInterval={0}; ", processingInterval);
            connectionString.AppendFormat("assemblyInfo={{source={0}; version={1}.{2}.{3}; buildDate={4}}}", assemblyInfo.Name, assemblyInfo.Version.Major, assemblyInfo.Version.Minor, assemblyInfo.Version.Build, assemblyInfo.BuildDate.ToString("yyyy-MM-dd HH:mm:ss"));

            if (!string.IsNullOrWhiteSpace(waitHandleNames))
            {
                connectionString.AppendFormat("; waitHandleNames={0}", waitHandleNames);
                connectionString.AppendFormat("; waitHandleTimeout={0}", waitHandleTimeout);
            }

            return Subscribe(true, compactFormat, connectionString.ToString());
        }
Esempio n. 11
0
        /// <summary>
        /// Creates a new instance of the <see cref="SynchronizedSubscriptionInfo"/> class.
        /// </summary>
        /// <param name="remotelySynchronized">Flag that determines whether the subscription defined by this object is remotely synchronized or locally synchronized.</param>
        /// <param name="framesPerSecond">Frame rate of the subscription in frames per second.</param>
        public SynchronizedSubscriptionInfo(bool remotelySynchronized, int framesPerSecond)
        {
            m_remotelySynchronized = remotelySynchronized;

            m_framesPerSecond = framesPerSecond;
            m_downsamplingMethod = DownsamplingMethod.LastReceived;
            m_allowPreemptivePublishing = true;

            m_allowSortsByArrival = true;
            m_timeResolution = Ticks.PerMillisecond;
        }
Esempio n. 12
0
        public static DatapointDatabase Create(string path, float downsamplingFactor, DownsamplingMethod downsamplingMethod, RetentionPolicy retentionPolicy, Func <DateTime> currentTimeProvider = null)
        {
            EnsureValidRetentionPolicy(retentionPolicy);

            using (var fileStream = new FileStream(path, FileMode.Create, FileAccess.ReadWrite, FileShare.Read, 8192, FileOptions.WriteThrough))
                return(Create(path, fileStream, downsamplingFactor, downsamplingMethod, retentionPolicy, currentTimeProvider));
        }
Esempio n. 13
0
        private static DatapointDatabase Create(string path, FileStream stream, float downsamplingFactor, DownsamplingMethod downsamplingMethod, RetentionPolicy retentionPolicy, Func <DateTime> currentTimeProvider = null)
        {
            var maxRetention = retentionPolicy.Select(h => h.Precision * h.History).Max();

            var headerSize =
                sizeof(byte) * Signature.Length +
                sizeof(byte) * Version.Length +
                sizeof(int) +
                sizeof(float) +
                sizeof(int) +
                sizeof(int) +
                ArchiveHeaderSize * retentionPolicy.Count;

            var archives = new List <Archive>();

            using (var binaryWriter = new BinaryWriter(stream))
            {
                binaryWriter.Write(Signature);
                binaryWriter.Write(Version);

                // ReSharper disable RedundantCast
                binaryWriter.Write((int)downsamplingMethod);
                binaryWriter.Write((float)downsamplingFactor);
                binaryWriter.Write((int)maxRetention);
                binaryWriter.Write((int)retentionPolicy.Count);
                // ReSharper restore RedundantCast

                var offset = headerSize;

                foreach (var retention in retentionPolicy)
                {
                    // ReSharper disable RedundantCast
                    binaryWriter.Write((int)offset);
                    binaryWriter.Write((int)retention.Precision);
                    binaryWriter.Write((int)retention.History);
                    // ReSharper restore RedundantCast

                    archives.Add(new Archive(offset, retention.History * DatapointSize, retention));

                    offset += retention.History * DatapointSize;
                } // foreach

                stream.SetLength(offset);
            } // using

            return(new DatapointDatabase(path, downsamplingFactor, downsamplingMethod, maxRetention, archives, currentTimeProvider));
        }
        private bool m_disposed;                            // Disposed flag detects redundant calls to dispose method

        #endregion

        #region [ Constructors ]

        /// <summary>
        /// Creates a new <see cref="ConcentratorBase"/>.
        /// </summary>
        /// <remarks>
        /// Concentration will not begin until consumer "Starts" concentrator (i.e., calling <see cref="ConcentratorBase.Start"/> method or setting
        /// <c><see cref="ConcentratorBase.Enabled"/> = true</c>).
        /// </remarks>
        protected ConcentratorBase()
        {
            Log = Logger.CreatePublisher(GetType(), MessageClass.Framework);
            m_usePrecisionTimer = true;
            m_allowSortsByArrival = true;
            m_allowPreemptivePublishing = true;
            m_performTimestampReasonabilityCheck = true;
            m_processingInterval = -1;
            m_downsamplingMethod = DownsamplingMethod.LastReceived;
            m_latestMeasurements = new ImmediateMeasurements(this);
            m_maximumPublicationTimeout = Timeout.Infinite;

            // Create a new queue for managing real-time frames
            m_frameQueue = new FrameQueue(this.CreateNewFrame);

            // Set minimum timer resolution to one millisecond to improve timer accuracy
            PrecisionTimer.SetMinimumTimerResolution(1);

            // Create publication wait handle
            m_publicationWaitHandle = new AutoResetEvent(false);

            // Create publication thread
            m_publicationThread = new Thread(PublishFrames);
            m_publicationThread.Start();

            // This timer monitors the total number of unpublished samples every 5 seconds. This is a useful statistic
            // to monitor: if total number of unpublished samples exceed lag time, measurement concentration could
            // be falling behind.
            m_monitorTimer = Common.TimerScheduler.CreateTimer(5000);
            m_monitorTimer.AutoReset = true;
            m_monitorTimer.Elapsed += MonitorUnpublishedSamples;
        }