You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Zero/ZeroLevel.SqLite/SqLitePacketBuffer.cs

122 lines
3.2 KiB

2 years ago
using SQLite;
using System;
5 years ago
using System.Threading;
using ZeroLevel.Services.Serialization;
namespace ZeroLevel.SqLite
{
2 years ago
public sealed class PacketRecord
{
[PrimaryKey, AutoIncrement]
public long Id { get; set; }
[Indexed]
public long Timestamp { get; set; }
public byte[] Data { get; set; }
}
5 years ago
/// <summary>
/// Промежуточное/временное хранилище пакетов данных, для случаев сбоя доставок через шину данных
/// </summary>
public sealed class SqLitePacketBuffer<T>
2 years ago
: BaseSqLiteDB<PacketRecord>
5 years ago
where T : IBinarySerializable
{
private sealed class PacketBufferRecord
{
public int Id { get; set; }
public byte[] Body { get; set; }
}
#region Fields
private readonly ReaderWriterLockSlim _rwLock = new ReaderWriterLockSlim();
#endregion Fields
public SqLitePacketBuffer(string database_file_path)
2 years ago
: base(database_file_path)
5 years ago
{
2 years ago
CreateTable();
5 years ago
}
public void Push(T frame)
{
long id = -1;
_rwLock.EnterWriteLock();
var creationTime = DateTime.Now.Ticks;
try
{
2 years ago
id = Append(new PacketRecord
{
Data = MessageSerializer.Serialize(frame),
Timestamp = creationTime
}).Id;
5 years ago
}
catch (Exception ex)
{
Log.Error(ex, $"[SqLitePacketBuffer] Fault insert record in buffer storage.");
}
finally
{
_rwLock.ExitWriteLock();
}
}
public bool Pop(Func<T, bool> pop_callback)
{
bool success = false;
long id = -1;
_rwLock.EnterReadLock();
try
{
2 years ago
var record = Single(r => r.Timestamp);
id = record.Id;
var body = record.Data;
try
{
success = pop_callback(MessageSerializer.Deserialize<T>(body));
}
catch (Exception ex)
5 years ago
{
2 years ago
Log.Error(ex, "Fault handle buffered data");
5 years ago
}
}
catch (Exception ex)
{
Log.Error(ex, "[SqLitePacketBuffer] Fault preload datafrom db");
}
finally
{
_rwLock.ExitReadLock();
}
if (success)
{
RemoveRecordById(id);
}
return success;
}
private void RemoveRecordById(long id)
{
_rwLock.EnterWriteLock();
try
{
2 years ago
Delete(r => r.Id == id);
5 years ago
}
catch (Exception ex)
{
Log.Error(ex, $"[SqLitePacketBuffer] Fault remove record by id '{id}'");
}
finally
{
_rwLock.ExitWriteLock();
}
}
2 years ago
protected override void DisposeStorageData()
5 years ago
{
}
}
}

Powered by TurnKey Linux.