feat(batch27): implement jetstream usage foundations and limit helpers
This commit is contained in:
@@ -250,6 +250,162 @@ public sealed partial class Account
|
||||
return null;
|
||||
}
|
||||
|
||||
public JetStreamAccountStats JetStreamUsage()
|
||||
{
|
||||
_mu.EnterReadLock();
|
||||
var jsa = JetStream;
|
||||
var accountName = Name;
|
||||
var configuredLimits = JetStreamLimits;
|
||||
_mu.ExitReadLock();
|
||||
|
||||
var stats = new JetStreamAccountStats();
|
||||
if (jsa == null)
|
||||
return stats;
|
||||
|
||||
var (js, _) = jsa.JetStreamAndClustered();
|
||||
if (js == null)
|
||||
return stats;
|
||||
|
||||
jsa.UsageLock.EnterReadLock();
|
||||
try
|
||||
{
|
||||
long mem = 0;
|
||||
long store = 0;
|
||||
foreach (var usage in jsa.Usage.Values)
|
||||
{
|
||||
mem += usage.Total.Mem;
|
||||
store += usage.Total.Store;
|
||||
}
|
||||
|
||||
stats.Memory = (ulong)Math.Max(0, mem);
|
||||
stats.Store = (ulong)Math.Max(0, store);
|
||||
stats.Domain = js.Config.Domain;
|
||||
stats.Api = new JetStreamApiStats
|
||||
{
|
||||
Level = JetStreamVersioning.JsApiLevel,
|
||||
Total = jsa.ApiTotal,
|
||||
Errors = jsa.ApiErrors,
|
||||
};
|
||||
|
||||
if (jsa.Limits.TryGetValue(string.Empty, out var defaultTier))
|
||||
{
|
||||
stats.Limits = defaultTier;
|
||||
}
|
||||
else
|
||||
{
|
||||
stats.Tiers = new Dictionary<string, JetStreamTier>(StringComparer.Ordinal);
|
||||
foreach (var (tier, usage) in jsa.Usage)
|
||||
{
|
||||
jsa.Limits.TryGetValue(tier, out var tierLimits);
|
||||
stats.Tiers[tier] = new JetStreamTier
|
||||
{
|
||||
Memory = (ulong)Math.Max(0, usage.Total.Mem),
|
||||
Store = (ulong)Math.Max(0, usage.Total.Store),
|
||||
Limits = tierLimits ?? new JetStreamAccountLimits(),
|
||||
};
|
||||
}
|
||||
|
||||
if (configuredLimits != null)
|
||||
{
|
||||
foreach (var (tier, value) in configuredLimits)
|
||||
{
|
||||
if (stats.Tiers.ContainsKey(tier))
|
||||
continue;
|
||||
if (value is not JetStreamAccountLimits lim)
|
||||
continue;
|
||||
stats.Tiers[tier] = new JetStreamTier { Limits = lim };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
jsa.UsageLock.ExitReadLock();
|
||||
}
|
||||
|
||||
var allStreams = Streams();
|
||||
stats.Streams = allStreams.Count;
|
||||
foreach (var stream in allStreams)
|
||||
stats.Consumers += stream.State().Consumers;
|
||||
|
||||
if (stats.Tiers != null)
|
||||
{
|
||||
foreach (var stream in allStreams)
|
||||
{
|
||||
var tier = JetStreamEngine.TierName(stream.Config.Replicas);
|
||||
if (!stats.Tiers.TryGetValue(tier, out var u))
|
||||
u = new JetStreamTier();
|
||||
u.Streams++;
|
||||
u.Consumers += stream.State().Consumers;
|
||||
stats.Tiers[tier] = u;
|
||||
}
|
||||
}
|
||||
|
||||
if (stats.Tiers == null || stats.Tiers.Count == 0)
|
||||
{
|
||||
var (rmem, rstore) = jsa.ReservedStorage(string.Empty);
|
||||
stats.ReservedMemory = rmem;
|
||||
stats.ReservedStore = rstore;
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var tier in stats.Tiers.Keys.ToArray())
|
||||
{
|
||||
var tierStats = stats.Tiers[tier];
|
||||
(tierStats.ReservedMemory, tierStats.ReservedStore) = jsa.ReservedStorage(tier);
|
||||
stats.Tiers[tier] = tierStats;
|
||||
}
|
||||
}
|
||||
|
||||
_ = accountName;
|
||||
return stats;
|
||||
}
|
||||
|
||||
internal Exception? DisableJetStream() => RemoveJetStream();
|
||||
|
||||
internal Exception? RemoveJetStream()
|
||||
{
|
||||
_mu.EnterWriteLock();
|
||||
var server = Server as NatsServer;
|
||||
var jsa = JetStream;
|
||||
JetStream = null;
|
||||
_mu.ExitWriteLock();
|
||||
|
||||
if (server == null)
|
||||
return new InvalidOperationException("jetstream account not registered");
|
||||
var js = server.GetJetStream();
|
||||
if (js == null)
|
||||
return new InvalidOperationException("jetstream not enabled for account");
|
||||
|
||||
return js.DisableJetStream(jsa);
|
||||
}
|
||||
|
||||
internal bool JetStreamConfigured()
|
||||
{
|
||||
_mu.EnterReadLock();
|
||||
try
|
||||
{
|
||||
return JetStreamLimits != null && JetStreamLimits.Count > 0;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_mu.ExitReadLock();
|
||||
}
|
||||
}
|
||||
|
||||
internal bool JetStreamEnabled()
|
||||
{
|
||||
_mu.EnterReadLock();
|
||||
try
|
||||
{
|
||||
return JetStream != null;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_mu.ExitReadLock();
|
||||
}
|
||||
}
|
||||
|
||||
internal Exception? EnableAllJetStreamServiceImportsAndMappings()
|
||||
{
|
||||
_mu.EnterReadLock();
|
||||
|
||||
Reference in New Issue
Block a user