diff --git a/src/Stl.Fusion/Extensions/RpcPeerStateMonitor.cs b/src/Stl.Fusion/Extensions/RpcPeerStateMonitor.cs index a6707616..5c720ae6 100644 --- a/src/Stl.Fusion/Extensions/RpcPeerStateMonitor.cs +++ b/src/Stl.Fusion/Extensions/RpcPeerStateMonitor.cs @@ -4,35 +4,45 @@ namespace Stl.Fusion.Extensions; public class RpcPeerStateMonitor : WorkerBase { - private readonly IMutableState _peerState; + private IMutableState _peerState = null!; private ILogger? _log; - private IServiceProvider Services => RpcHub.Services; - private ILogger Log => _log ??= Services.LogFor(GetType()); - private Moment Now => RpcHub.Clock.Now; + protected IServiceProvider Services => RpcHub.Services; + protected ILogger Log => _log ??= Services.LogFor(GetType()); + protected Moment Now => RpcHub.Clock.Now; public RpcHub RpcHub { get; } public RpcPeerRef? PeerRef { get; } public TimeSpan JustDisconnectedPeriod { get; init; } = TimeSpan.FromSeconds(3); public TimeSpan MinReconnectsIn { get; init; } = TimeSpan.FromSeconds(1); - public IState PeerState => _peerState; - public IState LastReconnectDelayCancelledAt { get; } - public IState State { get; } - - public RpcPeerStateMonitor(IServiceProvider services, RpcPeerRef? peerRef, bool mustStart = true) + public IState PeerState { + get => _peerState; + protected set => _peerState = (IMutableState)value; + } + public IState LastReconnectDelayCancelledAt { get; protected set; } = null!; + public IState State { get; protected set; } = null!; + + public RpcPeerStateMonitor( + IServiceProvider services, + RpcPeerRef? peerRef, + bool mustStart = true, + bool mustCreateStates = true) { RpcHub = services.RpcHub(); PeerRef = peerRef; + if (!mustCreateStates) + return; + var connectionState = peerRef == null ? null : RpcHub.GetPeer(peerRef).ConnectionState.Value; var isConnected = connectionState?.IsConnected() ?? true; - RpcPeerState initialState = isConnected + RpcPeerState initialPeerState = isConnected ? new RpcPeerConnectedState(Now) : new RpcPeerDisconnectedState(Now, default, connectionState?.Error); var stateFactory = services.StateFactory(); _peerState = stateFactory.NewMutable( - initialState, + initialPeerState, $"{GetType().Name}.{nameof(PeerState)}"); var stateCategory = $"{GetType().Name}.{nameof(LastReconnectDelayCancelledAt)}"; LastReconnectDelayCancelledAt = peerRef == null @@ -129,7 +139,7 @@ protected override async Task OnRun(CancellationToken cancellationToken) } } - private Task ComputeLastReconnectDelayCancelledAtState( + protected virtual Task ComputeLastReconnectDelayCancelledAtState( IComputedState state, CancellationToken cancellationToken) { var reconnectDelayer = RpcHub.InternalServices.ClientPeerReconnectDelayer; @@ -143,7 +153,7 @@ private Task ComputeLastReconnectDelayCancelledAtState( return Task.FromResult(Now); } - private async Task ComputeState( + protected virtual async Task ComputeState( IComputedState state, CancellationToken cancellationToken) { var s = await PeerState.Use(cancellationToken).ConfigureAwait(false);