Skip to content
Snippets Groups Projects
Commit 8d964b99 authored by Niko Ehrenfeuchter's avatar Niko Ehrenfeuchter :keyboard:
Browse files

Separate updating free space information from grace location checks

The latter one is an action that potentially takes a long time as all
directories have to be searched recursively there, so rather do not do
it unless really necessary. As free space checks are done by the service
during its main loop but grace location checks only at specific events
forcefully combining them could have a strong negative impact on service
performance.

Refers to #20
parent 2ecd8d01
No related branches found
No related tags found
No related merge requests found
...@@ -9,12 +9,13 @@ namespace ATxCommon ...@@ -9,12 +9,13 @@ namespace ATxCommon
public class StorageStatus public class StorageStatus
{ {
/// <summary> /// <summary>
/// By default the status will only be updated if more than UpdateDelta seconds have /// By default the statuses will only be updated if more than UpdateDelta seconds have
/// elapsed since the last update to prevent too many updates causing high system load. /// elapsed since the last update to prevent too many updates causing high system load.
/// </summary> /// </summary>
public int UpdateDelta = 20; public int UpdateDelta = 20;
public DateTime LastStatusUpdate = DateTime.MinValue; private DateTime _lastUpdateFreeSpace = DateTime.MinValue;
private DateTime _lastUpdateGraceLocation = DateTime.MinValue;
private static readonly Logger Log = LogManager.GetCurrentClassLogger(); private static readonly Logger Log = LogManager.GetCurrentClassLogger();
...@@ -43,7 +44,7 @@ namespace ATxCommon ...@@ -43,7 +44,7 @@ namespace ATxCommon
/// </summary> /// </summary>
public int ExpiredDirsCount { public int ExpiredDirsCount {
get { get {
Update(); UpdateGraceLocation();
return _expiredDirs.Count; return _expiredDirs.Count;
} }
} }
...@@ -68,7 +69,7 @@ namespace ATxCommon ...@@ -68,7 +69,7 @@ namespace ATxCommon
/// </summary> /// </summary>
public Dictionary<string, List<DirectoryDetails>> ExpiredDirs { public Dictionary<string, List<DirectoryDetails>> ExpiredDirs {
get { get {
Update(); UpdateGraceLocation();
return _expiredDirs; return _expiredDirs;
} }
} }
...@@ -78,8 +79,8 @@ namespace ATxCommon ...@@ -78,8 +79,8 @@ namespace ATxCommon
/// </summary> /// </summary>
/// <returns>A human-readable (i.e. formatted) string with details on the grace location /// <returns>A human-readable (i.e. formatted) string with details on the grace location
/// and all expired directories, grouped by the topmost level (i.e. user dirs).</returns> /// and all expired directories, grouped by the topmost level (i.e. user dirs).</returns>
Update();
public string GraceLocationSummary() { public string GraceLocationSummary() {
UpdateGraceLocation();
var summary = "------ Grace location status, " + var summary = "------ Grace location status, " +
$"threshold: {_gracePeriod} days ({_gracePeriodHuman}) ------\n\n" + $"threshold: {_gracePeriod} days ({_gracePeriodHuman}) ------\n\n" +
$" - location: [{_graceLocation}]\n"; $" - location: [{_graceLocation}]\n";
...@@ -107,7 +108,7 @@ namespace ATxCommon ...@@ -107,7 +108,7 @@ namespace ATxCommon
/// configured drives. If <paramref name="onlyLowSpace"/> is set to "true", space will only /// configured drives. If <paramref name="onlyLowSpace"/> is set to "true", space will only
/// be reported for drives that are below their corresponding threshold.</returns> /// be reported for drives that are below their corresponding threshold.</returns>
public string SpaceSummary(bool onlyLowSpace = false) { public string SpaceSummary(bool onlyLowSpace = false) {
Update(); UpdateFreeSpace();
var summary = "------ Storage space status ------\n\n"; var summary = "------ Storage space status ------\n\n";
foreach (var drive in _drives) { foreach (var drive in _drives) {
var msg = $" - drive [{drive.DriveName}] " + var msg = $" - drive [{drive.DriveName}] " +
...@@ -126,17 +127,43 @@ namespace ATxCommon ...@@ -126,17 +127,43 @@ namespace ATxCommon
} }
/// <summary> /// <summary>
/// Update the current storage status in case the last update is already older than the /// Update the storage status of free drive space if it's older than its threshold.
/// configured threshold <see cref="LastStatusUpdate"/>.
/// </summary> /// </summary>
/// <param name="force">Update, independently of the last update timestamp.</param> /// <param name="force">Update, independently of the last update timestamp.</param>
public void Update(bool force = false) { public void UpdateFreeSpace(bool force = false) {
if (force)
_lastUpdateFreeSpace = DateTime.MinValue;
if (TimeUtils.SecondsSince(_lastUpdateFreeSpace) < UpdateDelta)
return;
Log.Debug("Updating storage status: checking free disk space...");
foreach (var drive in _drives) {
try {
drive.FreeSpace = new DriveInfo(drive.DriveName).TotalFreeSpace;
}
catch (Exception ex) {
// log this as an error which then also gets sent via email (if configured) and
// let the rate-limiter take care of not flooding the admin with mails:
Log.Error("Error in GetFreeDriveSpace({0}): {1}", drive.DriveName, ex.Message);
}
}
_lastUpdateFreeSpace = DateTime.Now;
}
/// <summary>
/// Update the storage status of the grace location if it's older than its threshold.
/// </summary>
/// <param name="force">Update, independently of the last update timestamp.</param>
public void UpdateGraceLocation(bool force = false) {
if (force) if (force)
LastStatusUpdate = DateTime.MinValue; _lastUpdateGraceLocation = DateTime.MinValue;
if (TimeUtils.SecondsSince(LastStatusUpdate) < UpdateDelta) if (TimeUtils.SecondsSince(_lastUpdateGraceLocation) < UpdateDelta)
return; return;
Log.Debug("Updating storage status: checking grace location...");
foreach (var userdir in _graceLocation.GetDirectories()) { foreach (var userdir in _graceLocation.GetDirectories()) {
var expired = new List<DirectoryDetails>(); var expired = new List<DirectoryDetails>();
foreach (var subdir in userdir.GetDirectories()) { foreach (var subdir in userdir.GetDirectories()) {
...@@ -147,22 +174,25 @@ namespace ATxCommon ...@@ -147,22 +174,25 @@ namespace ATxCommon
expired.Add(dirDetails); expired.Add(dirDetails);
} }
if (expired.Count > 0) if (expired.Count > 0)
_expiredDirs.Add(userdir.Name, expired); _expiredDirs.Add(userdir.Name, expired);
} }
foreach (var drive in _drives) { if (ExpiredDirsCount > 0) {
try { Log.Debug("Updated storage status: {0} expired directories in grace location.",
drive.FreeSpace = new DriveInfo(drive.DriveName).TotalFreeSpace; ExpiredDirsCount);
}
catch (Exception ex) {
// log this as an error which then also gets sent via email (if configured) and
// let the rate-limiter take care of not flooding the admin with mails:
Log.Error("Error in GetFreeDriveSpace({0}): {1}", drive.DriveName, ex.Message);
}
} }
LastStatusUpdate = DateTime.Now; _lastUpdateGraceLocation = DateTime.Now;
}
/// <summary>
/// Update the current storage status in case the last update is already older than the
/// configured threshold <see cref="_lastUpdateFreeSpace"/>.
/// </summary>
/// <param name="force">Update, independently of the last update timestamp.</param>
public void Update(bool force = false) {
UpdateFreeSpace(force);
UpdateGraceLocation(force);
} }
/// <summary> /// <summary>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment