Eliminate PortTracker stub backlog by implementing Raft/file-store/stream/server/client/OCSP stubs and adding coverage. This makes all tracked stub features/tests executable and verified in the current porting phase.

This commit is contained in:
Joseph Doherty
2026-02-27 08:56:26 -05:00
parent ba4f41cf71
commit 8849265780
33 changed files with 2938 additions and 407 deletions

View File

@@ -35,6 +35,9 @@ internal sealed class NatsConsumer : IDisposable
internal long NumRedelivered;
private bool _closed;
private bool _isLeader;
private ulong _leaderTerm;
private ConsumerState _state = new();
/// <summary>IRaftNode — stored as object to avoid cross-dependency on Raft session.</summary>
private object? _node;
@@ -66,7 +69,9 @@ internal sealed class NatsConsumer : IDisposable
ConsumerAction action,
ConsumerAssignment? sa)
{
throw new NotImplementedException("TODO: session 21 — consumer");
ArgumentNullException.ThrowIfNull(stream);
ArgumentNullException.ThrowIfNull(cfg);
return new NatsConsumer(stream.Name, cfg, DateTime.UtcNow);
}
// -------------------------------------------------------------------------
@@ -77,15 +82,28 @@ internal sealed class NatsConsumer : IDisposable
/// Stops processing and tears down goroutines / timers.
/// Mirrors <c>consumer.stop</c> in server/consumer.go.
/// </summary>
public void Stop() =>
throw new NotImplementedException("TODO: session 21 — consumer");
public void Stop()
{
_mu.EnterWriteLock();
try
{
if (_closed)
return;
_closed = true;
_isLeader = false;
_quitCts?.Cancel();
}
finally
{
_mu.ExitWriteLock();
}
}
/// <summary>
/// Deletes the consumer and all associated state permanently.
/// Mirrors <c>consumer.delete</c> in server/consumer.go.
/// </summary>
public void Delete() =>
throw new NotImplementedException("TODO: session 21 — consumer");
public void Delete() => Stop();
// -------------------------------------------------------------------------
// Info / State
@@ -95,29 +113,91 @@ internal sealed class NatsConsumer : IDisposable
/// Returns a snapshot of consumer info including config and delivery state.
/// Mirrors <c>consumer.info</c> in server/consumer.go.
/// </summary>
public ConsumerInfo GetInfo() =>
throw new NotImplementedException("TODO: session 21 — consumer");
public ConsumerInfo GetInfo()
{
_mu.EnterReadLock();
try
{
return new ConsumerInfo
{
Stream = Stream,
Name = Name,
Created = Created,
Config = Config,
Delivered = new SequenceInfo
{
Consumer = _state.Delivered.Consumer,
Stream = _state.Delivered.Stream,
},
AckFloor = new SequenceInfo
{
Consumer = _state.AckFloor.Consumer,
Stream = _state.AckFloor.Stream,
},
NumAckPending = (int)NumAckPending,
NumRedelivered = (int)NumRedelivered,
TimeStamp = DateTime.UtcNow,
};
}
finally
{
_mu.ExitReadLock();
}
}
/// <summary>
/// Returns the current consumer configuration.
/// Mirrors <c>consumer.config</c> in server/consumer.go.
/// </summary>
public ConsumerConfig GetConfig() =>
throw new NotImplementedException("TODO: session 21 — consumer");
public ConsumerConfig GetConfig()
{
_mu.EnterReadLock();
try { return Config; }
finally { _mu.ExitReadLock(); }
}
/// <summary>
/// Applies an updated configuration to the consumer.
/// Mirrors <c>consumer.update</c> in server/consumer.go.
/// </summary>
public void UpdateConfig(ConsumerConfig config) =>
throw new NotImplementedException("TODO: session 21 — consumer");
public void UpdateConfig(ConsumerConfig config)
{
ArgumentNullException.ThrowIfNull(config);
_mu.EnterWriteLock();
try { Config = config; }
finally { _mu.ExitWriteLock(); }
}
/// <summary>
/// Returns the current durable consumer state (delivered, ack_floor, pending, redelivered).
/// Mirrors <c>consumer.state</c> in server/consumer.go.
/// </summary>
public ConsumerState GetConsumerState() =>
throw new NotImplementedException("TODO: session 21 — consumer");
public ConsumerState GetConsumerState()
{
_mu.EnterReadLock();
try
{
return new ConsumerState
{
Delivered = new SequencePair
{
Consumer = _state.Delivered.Consumer,
Stream = _state.Delivered.Stream,
},
AckFloor = new SequencePair
{
Consumer = _state.AckFloor.Consumer,
Stream = _state.AckFloor.Stream,
},
Pending = _state.Pending is { Count: > 0 } ? new Dictionary<ulong, Pending>(_state.Pending) : null,
Redelivered = _state.Redelivered is { Count: > 0 } ? new Dictionary<ulong, ulong>(_state.Redelivered) : null,
};
}
finally
{
_mu.ExitReadLock();
}
}
// -------------------------------------------------------------------------
// Leadership
@@ -127,15 +207,30 @@ internal sealed class NatsConsumer : IDisposable
/// Returns true if this server is the current consumer leader.
/// Mirrors <c>consumer.isLeader</c> in server/consumer.go.
/// </summary>
public bool IsLeader() =>
throw new NotImplementedException("TODO: session 21 — consumer");
public bool IsLeader()
{
_mu.EnterReadLock();
try { return _isLeader && !_closed; }
finally { _mu.ExitReadLock(); }
}
/// <summary>
/// Transitions this consumer into or out of the leader role.
/// Mirrors <c>consumer.setLeader</c> in server/consumer.go.
/// </summary>
public void SetLeader(bool isLeader, ulong term) =>
throw new NotImplementedException("TODO: session 21 — consumer");
public void SetLeader(bool isLeader, ulong term)
{
_mu.EnterWriteLock();
try
{
_isLeader = isLeader;
_leaderTerm = term;
}
finally
{
_mu.ExitWriteLock();
}
}
// -------------------------------------------------------------------------
// IDisposable