private bool IsBoring( TrackerStateHolder holder ) { long boringThreshold = TimeService.Now.AddMinutes( -Properties.Settings.Default.TrackerLifetimeWithoutAccess ).ToFileTime( ); long accessTimestamp = Interlocked.Read( ref holder.ThreadDesynchronizedAccessTimestamp ); return accessTimestamp < boringThreshold; }
internal bool AddMissingTrackers( List<TrackerName> trackerIds ) { // TODO: test with Thread.Sleep(x000) in the beginning bool newTrackersAdded = false; try { if ( Log.IsDebugEnabled ) Log.DebugFormat( "Adding {0} new tracker(s)...", trackerIds.Count ); HolderRwLock.AttemptEnterWriteLock( ); try { foreach ( TrackerName trackerId in trackerIds ) { if ( Trackers.ContainsKey( trackerId.ForeignId ) ) { if ( Log.IsDebugEnabled ) Log.DebugFormat( "Already added: '{0}' / {1}", trackerId.Name, trackerId.ForeignId ); } else { if ( Log.IsDebugEnabled ) Log.DebugFormat( "Adding '{0}' / {1}...", trackerId.Name, trackerId.ForeignId ); // no data yet, so leave its Snapshot field null for the moment: TrackerStateHolder trackerStateHolder = new TrackerStateHolder( trackerId.ForeignId ); Trackers.Add( trackerId.ForeignId, trackerStateHolder ); newTrackersAdded = true; } } } finally { HolderRwLock.ExitWriteLock( ); } if ( Log.IsDebugEnabled ) Log.Debug( "New tracker(s) added" ); } catch ( Exception exc ) { Log.Error( "Error when adding trackers", exc ); } return newTrackersAdded; }
private static TrackerStateHolder GetMoreStaleTracker( TrackerStateHolder h1, TrackerStateHolder h2 ) { // for the main application it doesn't matter which tracker to take if times are equal, // so do not use out parameter: bool unused; return GetMoreStaleTracker( h1, h2, out unused ); }
private DateTime prevTimeAbortsChecked; // on construction set to default DateTime which is quite long time ago. #endregion Fields #region Methods /// <summary> /// Methid is made public for the unit tests only. See Remarks section for details. /// </summary> /// <remarks> /// - Holders with ScheduledTime set are always less stale than others, because it's trackers /// which were scheduled but for some reasons (error?) didn't started requests. So avoid /// scheduling those trackers on and on again (failing to request due to the same error) /// while there are others waiting. /// - Holder without RefreshTime is always more stale than a holder with a RefreshTime. I.e. /// trackers that just requested by clients should be refreshed first. /// /// * From two holders without ScheduledTime and without RefreshTime, more stale is one with /// earlier <see cref="TrackerStateHolder.AddedTime"/>. /// * From two holders without ScheduledTime and with RefreshTime, more stale is one with /// earlier <see cref="TrackerStateHolder.RefreshTime"/>. /// * From two holders with ScheduledTime, more stale is one with earlier ScheduledTime. /// /// Parameter <paramref name="areEqual"/> is needed for sorting only. When both trackers are /// equal then it's not allowed to return any as "most stale" - because if any of the equal /// is returned as "lesser", then it becomes important which of the pair goes as the 1st parameter /// and which goes as the 2nd. In other words, transitivity and conversing rules will be broken, /// which are absolutely critical for sorting which needed in the unit tests. Notice that it's /// not important for the main app where just any of the trackers with equal times can be picked /// up. But for the unit tests equality needs to be recognised as well. /// </remarks> public static TrackerStateHolder GetMoreStaleTracker( TrackerStateHolder x, TrackerStateHolder y, out bool areEqual ) { // The logic in this method is quite fragile, so always run the unit test after making just // any change here. DateTime t1, t2; if ( x.ScheduledTime != null && y.ScheduledTime != null ) { t1 = x.ScheduledTime.Value; t2 = y.ScheduledTime.Value; } else if ( x.ScheduledTime != null ) // means "and y.ScheduledTime == null" { areEqual = false; return y; } else if ( y.ScheduledTime != null ) // means "and x.ScheduledTime == null" { areEqual = false; return x; } // at this point x.ScheduledTime == null && y.ScheduledTime == null ) else if ( x.RefreshTime != null && y.RefreshTime != null ) { t1 = x.RefreshTime.Value; t2 = y.RefreshTime.Value; } else if ( x.RefreshTime != null ) // means "and y.RefreshTime == null" { areEqual = false; return y; } else if ( y.RefreshTime != null ) // means "and x.RefreshTime == null" { areEqual = false; return x; } else { // at this point x.ScheduledTime == null && y.ScheduledTime == null // && x.RefreshTime == null && y.RefreshTime == null t1 = x.AddedTime; t2 = y.AddedTime; } areEqual = t1 == t2; return t1 < t2 ? x : y; }