AirScout/AirScout.AircraftPositions/AircraftPositionDatabaseMai...

144 wiersze
5.6 KiB
C#

using System;
using System.ComponentModel;
using System.Windows.Forms;
using System.Net;
using System.IO;
using System.Threading;
using System.Diagnostics;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Globalization;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using ScoutBase;
using ScoutBase.Core;
using System.Data.SQLite;
using System.Text;
namespace AirScout.AircraftPositions
{
#region AircraftPositionDatabaseMaintainer
public class AircraftPositionDatabaseMaintainerStartOptions
{
public string Name;
public double Database_MaxSize;
public long Database_MaxCount;
public int Database_MaxDaysLifetime;
}
// Background worker for aircraft position database maintainance
[DefaultPropertyAttribute("Name")]
public class AircraftPositionDatabaseMaintainer : BackgroundWorker
{
AircraftPositionDatabaseMaintainerStartOptions StartOptions;
double DBLastSize = 0;
public AircraftPositionDatabaseMaintainer() : base()
{
this.WorkerReportsProgress = true;
this.WorkerSupportsCancellation = true;
}
protected override void OnDoWork(DoWorkEventArgs e)
{
StartOptions = (AircraftPositionDatabaseMaintainerStartOptions)e.Argument;
this.ReportProgress(0, StartOptions.Name + "started.");
// name the thread for debugging
if (String.IsNullOrEmpty(Thread.CurrentThread.Name))
Thread.CurrentThread.Name = nameof(AircraftPositionDatabaseMaintainer);
// get maintenance interval
int interval = (int)Properties.Settings.Default.Database_BackgroundMaintenance_Period * 60;
do
{
try
{
this.ReportProgress(0, "Maintaining database...");
try
{
// check database entry count and remove oldest entries
long count = AircraftPositionData.Database.AircraftPositionCount();
if (this.CancellationPending)
break;
// check against limit
if (count > StartOptions.Database_MaxCount)
{
// remove oldest entries from database
this.ReportProgress(0, "Exceeding database entries count limit, removing entries...");
AircraftPositionData.Database.AircraftPositionBulkDeleteFirst(1000);
}
}
catch (Exception ex)
{
this.ReportProgress(-1, ex.ToString());
}
try
{
// check and reduce database size
// tricky, because deleting entries not necessarily reduces database size
// neeeds pragma auto_vacuum to be set to full
// delete an amount of entries from AircraftPositions table and let auto_vacuum do the rest
// keep last reported size in memory trigger deletion only if size is increasing again
double size = AircraftPositionData.Database.GetDBSize();
// check against last reported size
if (size > DBLastSize)
{
// keep last reported size
DBLastSize = size;
if (DBLastSize > StartOptions.Database_MaxSize)
{
// remove first 1000 entries from database
this.ReportProgress(0, "Exceeding database size limit, removing entries...");
AircraftPositionData.Database.AircraftPositionBulkDeleteFirst(1000);
}
}
}
catch (Exception ex)
{
this.ReportProgress(-1, ex.ToString());
}
try
{
// check and remove oldest entries
DateTime olderthan = DateTime.UtcNow - new TimeSpan(StartOptions.Database_MaxDaysLifetime, 0, 0, 0);
// remove oldest entries from database
this.ReportProgress(0, "Cleaning up aircraft positions...");
AircraftPositionData.Database.AircraftPositionBulkDeleteOlderThan(olderthan);
}
catch (Exception ex)
{
this.ReportProgress(-1, ex.ToString());
}
this.ReportProgress(0, "");
// sleep
int i = 0;
while (!this.CancellationPending && (i < interval))
{
Thread.Sleep(1000);
i++;
}
}
catch (Exception ex)
{
this.ReportProgress(-1, ex.ToString());
}
}
while (!this.CancellationPending);
if (this.CancellationPending)
this.ReportProgress(0, StartOptions.Name + "cancelled.");
else
this.ReportProgress(0, StartOptions.Name + " finished.");
}
#endregion
}
}