fix(historian): QuestDB final-review fix wave (I-1, M-1, M-3, M-5, M-8, M-9)
- I-1: QuestDbConnection caps Npgsql Maximum Pool Size at 24 (DefaultMaxPoolSize) when the connection string does not set it; an explicit value is kept. The effective value is logged once at Information. - M-1: QuestDbTagCatalog.EnsureAsync waits for the tag table's sequenced commits and re-checks before inserting, so it no longer overwrites a provisioner row (unit/description) that is committed but not yet applied. Integration test reproduces the clobber against real QuestDB (falsified). - M-3: the pre-1970 drop Warning is rate-limited per tag (once per 10 min); DroppedPre1970 still counts every sample. - M-5: QuestDbHistorianProvider is IAsyncDisposable/IDisposable and disposes the shared Npgsql pool; Program.cs registers the provider through a factory and every seam resolves it from the container, so DI disposes it at shutdown. - M-8, M-9: docs fixes (HistoryUpdate transaction wording; folded duplicate HistoryUpdate paragraph). Pool-size docs updated for the new default cap. Claude-Session: https://claude.ai/code/session_01Ef2ozxS7QPanGT8uoATbTe
This commit is contained in:
+44
@@ -137,4 +137,48 @@ public sealed class QuestDbConnectionTests
|
||||
c.EventTable.ShouldBe("p_event");
|
||||
c.TagTable.ShouldBe("p_tag");
|
||||
}
|
||||
|
||||
// ---- pool size (final review I-1) -------------------------------------------------------------------------------
|
||||
|
||||
private static int PoolOf(string cs)
|
||||
{
|
||||
using var c = new QuestDbConnection(new QuestDbHistorianOptions { ConnectionString = cs });
|
||||
return c.EffectiveMaxPoolSize;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void An_unset_Maximum_Pool_Size_is_capped_at_24() =>
|
||||
PoolOf("Host=127.0.0.1;Port=1").ShouldBe(24);
|
||||
|
||||
[Fact]
|
||||
public void The_default_cap_constant_is_24() => QuestDbConnection.DefaultMaxPoolSize.ShouldBe(24);
|
||||
|
||||
[Theory]
|
||||
[InlineData("Host=127.0.0.1;Port=1;Maximum Pool Size=10", 10)]
|
||||
[InlineData("Host=127.0.0.1;Port=1;Maximum Pool Size=80", 80)]
|
||||
[InlineData("Host=127.0.0.1;Port=1;maximum pool size=30", 30)]
|
||||
[InlineData("Host=127.0.0.1;Port=1;MaxPoolSize=80", 80)]
|
||||
public void An_explicit_Maximum_Pool_Size_is_preserved(string cs, int expected) =>
|
||||
PoolOf(cs).ShouldBe(expected);
|
||||
|
||||
[Fact]
|
||||
public void The_effective_pool_size_is_logged_once_at_Information()
|
||||
{
|
||||
var log = new InfoLogger();
|
||||
using var c = new QuestDbConnection(new QuestDbHistorianOptions { ConnectionString = "Host=127.0.0.1;Port=1" }, log);
|
||||
log.Messages.Count.ShouldBe(1);
|
||||
log.Messages[0].ShouldContain("24");
|
||||
}
|
||||
|
||||
private sealed class InfoLogger : Microsoft.Extensions.Logging.ILogger
|
||||
{
|
||||
public List<string> Messages { get; } = [];
|
||||
public IDisposable? BeginScope<TState>(TState state) where TState : notnull => null;
|
||||
public bool IsEnabled(Microsoft.Extensions.Logging.LogLevel logLevel) => true;
|
||||
public void Log<TState>(Microsoft.Extensions.Logging.LogLevel logLevel, Microsoft.Extensions.Logging.EventId eventId, TState state,
|
||||
Exception? exception, Func<TState, Exception?, string> formatter)
|
||||
{
|
||||
if (logLevel == Microsoft.Extensions.Logging.LogLevel.Information) Messages.Add(formatter(state, exception));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user