batch33 task3 implement group B cluster stream features
This commit is contained in:
@@ -45,6 +45,9 @@ internal sealed class NatsStream : IDisposable
|
||||
|
||||
/// <summary>IRaftNode — stored as object to avoid cross-dependency on Raft session.</summary>
|
||||
private object? _node;
|
||||
private StreamAssignment? _assignment;
|
||||
private bool _migrating;
|
||||
private bool _recovering;
|
||||
|
||||
public NatsStream(Account account, StreamConfig config, DateTime created)
|
||||
{
|
||||
@@ -79,6 +82,7 @@ internal sealed class NatsStream : IDisposable
|
||||
{
|
||||
Store = store,
|
||||
IsMirror = cfg.Mirror != null,
|
||||
_assignment = sa,
|
||||
};
|
||||
return stream;
|
||||
}
|
||||
@@ -317,6 +321,97 @@ internal sealed class NatsStream : IDisposable
|
||||
finally { _mu.ExitReadLock(); }
|
||||
}
|
||||
|
||||
public RaftGroup? RaftGroup()
|
||||
{
|
||||
_mu.EnterReadLock();
|
||||
try { return _assignment?.Group; }
|
||||
finally { _mu.ExitReadLock(); }
|
||||
}
|
||||
|
||||
public IRaftNode? RaftNode()
|
||||
{
|
||||
_mu.EnterReadLock();
|
||||
try { return _node as IRaftNode; }
|
||||
finally { _mu.ExitReadLock(); }
|
||||
}
|
||||
|
||||
public void RemoveNode()
|
||||
{
|
||||
_mu.EnterWriteLock();
|
||||
try
|
||||
{
|
||||
if (_node is IRaftNode raft)
|
||||
raft.Delete();
|
||||
_node = null;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_mu.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
|
||||
public void WaitOnConsumerAssignments(CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
return;
|
||||
|
||||
var stopAt = DateTime.UtcNow.AddSeconds(2);
|
||||
while (DateTime.UtcNow < stopAt)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
if (!_recovering)
|
||||
break;
|
||||
Thread.Sleep(50);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsMigrating()
|
||||
{
|
||||
_mu.EnterReadLock();
|
||||
try { return _migrating; }
|
||||
finally { _mu.ExitReadLock(); }
|
||||
}
|
||||
|
||||
public bool ResetClusteredState(Exception? cause = null)
|
||||
{
|
||||
_mu.EnterWriteLock();
|
||||
try
|
||||
{
|
||||
_recovering = true;
|
||||
_isLeader = false;
|
||||
_leaderTerm = 0;
|
||||
_migrating = false;
|
||||
if (cause != null && _node is IRaftNode raft)
|
||||
raft.StepDown();
|
||||
return true;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_mu.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
|
||||
public bool SkipBatchIfRecovering()
|
||||
{
|
||||
_mu.EnterReadLock();
|
||||
try { return _recovering; }
|
||||
finally { _mu.ExitReadLock(); }
|
||||
}
|
||||
|
||||
public bool ShouldSendLostQuorum()
|
||||
{
|
||||
_mu.EnterReadLock();
|
||||
try
|
||||
{
|
||||
var replicas = Math.Max(1, Config.Replicas);
|
||||
return replicas > 1 && _node is IRaftNode raft && raft.Leaderless();
|
||||
}
|
||||
finally
|
||||
{
|
||||
_mu.ExitReadLock();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Seals the stream so that no new messages can be stored.
|
||||
/// Mirrors <c>stream.seal</c> in server/stream.go.
|
||||
|
||||
Reference in New Issue
Block a user