check point
This commit is contained in:
182
framework/Inspectron.Ringbuffer/RingbufferPath.cs
Normal file
182
framework/Inspectron.Ringbuffer/RingbufferPath.cs
Normal file
@@ -0,0 +1,182 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using Inspectron.Ringbuffer.Interfaces;
|
||||
|
||||
namespace Inspectron.Ringbuffer
|
||||
{
|
||||
public class RingbufferPath : IFolderWritter,IDisposable
|
||||
{
|
||||
private readonly string _pathFormat;
|
||||
private readonly RingbufferPathConfiguration _configuration;
|
||||
private readonly IFileVerifier _fileVerifier;
|
||||
|
||||
public const string PRODUCT = "$PRODUCT$";
|
||||
public const string GOODBAD = "$GOODBAD$";
|
||||
public const string DATE = "$date$";
|
||||
public const string MONTH = "$month$";
|
||||
public const string YEAR = "$year$";
|
||||
|
||||
private IIndex _index;
|
||||
ConcurrentQueue<SaveCandidate> _saveQueue = new ConcurrentQueue<SaveCandidate>();
|
||||
object _lock = new object();
|
||||
|
||||
private string _ringbufferFolder;
|
||||
private int _productPartId;
|
||||
private int _goodBadPartId;
|
||||
private int _subPartId;
|
||||
|
||||
public RingbufferPath(RingbufferPathConfiguration configuration, IFileVerifier fileVerifier)
|
||||
{
|
||||
_pathFormat = configuration.PathFormat;
|
||||
_configuration = configuration;
|
||||
_fileVerifier = fileVerifier;
|
||||
|
||||
var pathFormat = configuration.PathFormat;
|
||||
|
||||
var pathParts = Path.Combine(configuration.RootDirectory,pathFormat).Split(new char[]{ Path.DirectorySeparatorChar },StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
_ringbufferFolder = configuration.RootDirectory;
|
||||
|
||||
_productPartId = -1;
|
||||
_goodBadPartId = -1;
|
||||
|
||||
for (int i = 1; i < pathParts.Length; i++)
|
||||
{
|
||||
if (pathParts[i] == PRODUCT) _productPartId = i;
|
||||
if (pathParts[i] == GOODBAD) _goodBadPartId = i;
|
||||
|
||||
}
|
||||
|
||||
//if(_productPartId==-1||_goodBadPartId==-1)throw new Exception("one of the markers is missing");
|
||||
|
||||
EnsureDirectory(_ringbufferFolder);
|
||||
InitIndex();
|
||||
|
||||
|
||||
var th1 = new Thread(RemoveLoop);
|
||||
th1.IsBackground = true;
|
||||
th1.Priority = ThreadPriority.Normal;
|
||||
th1.Start();
|
||||
|
||||
var th2 = new Thread(SaveLoop);
|
||||
th2.IsBackground = true;
|
||||
th2.Priority = ThreadPriority.Normal;
|
||||
th2.Start();
|
||||
}
|
||||
|
||||
private void InitIndex()
|
||||
{
|
||||
_index = new GroupIndex(_configuration.GroupPartId,_goodBadPartId);
|
||||
IndexFiles();
|
||||
}
|
||||
private void IndexFiles()
|
||||
{
|
||||
|
||||
|
||||
var allFiles = Directory.GetFiles(_ringbufferFolder, "*.*", SearchOption.AllDirectories);
|
||||
var verifiedFiles = allFiles.Where(x => _fileVerifier.IsMainFile(x)).ToList();
|
||||
var orderedFiles = verifiedFiles.OrderByDescending(x => new FileInfo(x).CreationTimeUtc).ToList();
|
||||
orderedFiles.ForEach(_index.Track);
|
||||
}
|
||||
|
||||
private void RemoveLoop()
|
||||
{
|
||||
while (!_stop)
|
||||
{
|
||||
var filesToDelete = _index.GetFilesToDelete(_configuration.MaxAmountOfGoodImages, _configuration.MaxAmountOfBadImages);
|
||||
|
||||
filesToDelete.ForEach(x =>
|
||||
{
|
||||
DeleteFile(x);
|
||||
_fileVerifier.LinkedFiles(x).ForEach(DeleteFile);
|
||||
});
|
||||
|
||||
Thread.Sleep(1000);
|
||||
}
|
||||
}
|
||||
public void DeleteFile(string fileToDelete)
|
||||
{
|
||||
var fi = new System.IO.FileInfo(fileToDelete);
|
||||
if (fi.Exists)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
fi.Delete();
|
||||
}
|
||||
|
||||
fi.Refresh();
|
||||
while (fi.Exists)
|
||||
{
|
||||
System.Threading.Thread.Sleep(10);
|
||||
fi.Refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool _stop = false;
|
||||
private void SaveLoop()
|
||||
{
|
||||
while (!_stop)
|
||||
{
|
||||
if (_saveQueue.TryDequeue(out var candidate))
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
EnsureDirectory(candidate.TargetDirectory);
|
||||
var written = candidate.FileIdentity.WriteTo(candidate.TargetDirectory);
|
||||
_index.Track(written);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Thread.Sleep(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
private void EnsureDirectory(string directory)
|
||||
{
|
||||
if (!Directory.Exists(directory))
|
||||
{
|
||||
Directory.CreateDirectory(directory);
|
||||
}
|
||||
}
|
||||
public static string GOOD_DIR = "Good";
|
||||
public static string BAD_DIR = "Bad";
|
||||
|
||||
string TransformPath(string originalPath,bool isGood,string product)
|
||||
{
|
||||
var time = DateTime.Now;
|
||||
|
||||
var res= originalPath.Replace(PRODUCT, product)
|
||||
.Replace(GOODBAD, isGood ? GOOD_DIR : BAD_DIR)
|
||||
.Replace(MONTH,time.ToString("MMMM"))
|
||||
.Replace(YEAR,time.Year.ToString())
|
||||
.Replace(DATE,time.ToString("dd.MM.yyyy"));
|
||||
return Path.Combine(_configuration.RootDirectory, res);
|
||||
}
|
||||
|
||||
public void WriteGood(IFileIdentity fileIdentity, string product)
|
||||
{
|
||||
var path = TransformPath(_configuration.PathFormat, true, product);
|
||||
|
||||
|
||||
_saveQueue.Enqueue(new SaveCandidate(fileIdentity, path));
|
||||
}
|
||||
|
||||
public void WriteBad(IFileIdentity fileIdentity, string product)
|
||||
{
|
||||
var path = TransformPath(_configuration.PathFormat, false, product);
|
||||
|
||||
_saveQueue.Enqueue(new SaveCandidate(fileIdentity, path));
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_stop = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user