feat(batch27): implement jetstream config validation and error tail
This commit is contained in:
@@ -7,6 +7,7 @@ namespace ZB.MOM.NatsNet.Server;
|
||||
public sealed partial class NatsServer
|
||||
{
|
||||
private const string JetStreamStoreDir = "jetstream";
|
||||
private const long JetStreamMaxMemDefault = 1024L * 1024L * 256L;
|
||||
|
||||
public Exception? EnableJetStream(JetStreamConfig? config)
|
||||
{
|
||||
@@ -495,6 +496,81 @@ public sealed partial class NatsServer
|
||||
null);
|
||||
}
|
||||
|
||||
internal JetStreamConfig DynJetStreamConfig(string storeDir, long maxStore, long maxMem)
|
||||
{
|
||||
var cfg = new JetStreamConfig();
|
||||
if (!string.IsNullOrWhiteSpace(storeDir))
|
||||
{
|
||||
cfg.StoreDir = Path.Combine(storeDir, JetStreamStoreDir);
|
||||
}
|
||||
else
|
||||
{
|
||||
cfg.StoreDir = Path.Combine(Path.GetTempPath(), "nats", JetStreamStoreDir);
|
||||
Warnf("Temporary storage directory used, data could be lost on system reboot");
|
||||
}
|
||||
|
||||
var opts = GetOpts();
|
||||
cfg.Strict = !opts.NoJetStreamStrict;
|
||||
cfg.SyncInterval = opts.SyncInterval;
|
||||
cfg.SyncAlways = opts.SyncAlways;
|
||||
|
||||
cfg.MaxStore = opts.MaxStoreSet && maxStore >= 0
|
||||
? maxStore
|
||||
: DiskAvailability.DiskAvailable(cfg.StoreDir);
|
||||
|
||||
if (opts.MaxMemSet && maxMem >= 0)
|
||||
{
|
||||
cfg.MaxMemory = maxMem;
|
||||
}
|
||||
else
|
||||
{
|
||||
var totalAvailable = GC.GetGCMemoryInfo().TotalAvailableMemoryBytes;
|
||||
cfg.MaxMemory = totalAvailable > 0 && totalAvailable < long.MaxValue
|
||||
? totalAvailable / 4 * 3
|
||||
: JetStreamMaxMemDefault;
|
||||
}
|
||||
|
||||
return cfg;
|
||||
}
|
||||
|
||||
internal void ResourcesExceededError(StorageType storeType)
|
||||
{
|
||||
var didAlert = false;
|
||||
lock (_resourceErrorLock)
|
||||
{
|
||||
var now = DateTime.UtcNow;
|
||||
if (now - _resourceErrorLastUtc > TimeSpan.FromSeconds(10))
|
||||
{
|
||||
var storeName = storeType switch
|
||||
{
|
||||
StorageType.MemoryStorage => "memory",
|
||||
StorageType.FileStorage => "file",
|
||||
_ => storeType.ToString().ToLowerInvariant(),
|
||||
};
|
||||
|
||||
Errorf("JetStream {0} resource limits exceeded for server", storeName);
|
||||
_resourceErrorLastUtc = now;
|
||||
didAlert = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!didAlert)
|
||||
return;
|
||||
|
||||
var js = GetJetStreamState();
|
||||
if (js?.Cluster is JetStreamCluster { Meta: not null } cluster)
|
||||
cluster.Meta.StepDown();
|
||||
}
|
||||
|
||||
internal void HandleWritePermissionError()
|
||||
{
|
||||
if (!JetStreamEnabled())
|
||||
return;
|
||||
|
||||
Errorf("File system permission denied while writing, disabling JetStream");
|
||||
_ = Task.Run(() => DisableJetStream());
|
||||
}
|
||||
|
||||
internal JetStreamEngine? GetJetStream() =>
|
||||
_jetStream == null ? null : new JetStreamEngine(_jetStream);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user