< Summary - erichiller/mkmrk.Channels coverage

Information
Class: mkmrk.Channels.BroadcastChannelReader<TData, TResponse>
Assembly: mkmrk.Channels
File(s): /home/runner/work/mkmrk.Channels/mkmrk.Channels/src/mkmrk.Channels/BroadcastChannel/BroadcastChannelReader.cs
Tag: 161_8859726157
Line coverage
83%
Covered lines: 36
Uncovered lines: 7
Coverable lines: 43
Total lines: 142
Line coverage: 83.7%
Branch coverage
29%
Covered branches: 7
Total branches: 24
Branch coverage: 29.1%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Metrics

MethodBranch coverage Cyclomatic complexity Line coverage
.ctor(...)100%1100%
.ctor(...)100%1100%
TryRead(...)50%2100%
TryPeek(...)0%20%
WaitToReadAsync(...)50%2100%
ReadAllAsync(...)0%20%
WriteResponseAsync(...)100%1100%
get_Completion()0%20%
get_Count()0%20%
get_CanCount()0%20%
get_CanPeek()0%20%
Dispose()100%1100%
Dispose(...)75%488.89%
ToString()50%4100%

File(s)

/home/runner/work/mkmrk.Channels/mkmrk.Channels/src/mkmrk.Channels/BroadcastChannel/BroadcastChannelReader.cs

#LineLine coverage
 1using System;
 2using System.Collections.Generic;
 3using System.ComponentModel;
 4using System.Diagnostics.CodeAnalysis;
 5using System.Runtime.CompilerServices;
 6using System.Threading;
 7using System.Threading.Channels;
 8using System.Threading.Tasks;
 9
 10using Microsoft.Extensions.Logging;
 11
 12namespace mkmrk.Channels;
 13
 14/// <inheritdoc cref="IBroadcastChannelReader{TData,TResponse}" />
 15public class BroadcastChannelReader<TData, TResponse> : ChannelReader<TData>, IBroadcastChannelReader<TData, TResponse> 
 16    private readonly RemoveWriterByHashCode                            _removeReader;
 17    private readonly ChannelWriter<TResponse>                          _responseWriter;
 18    private readonly ChannelReader<TData>                              _dataReader;
 19    private          bool                                              _isDisposed;
 20    private readonly int                                               _writerHash;
 21    private readonly ILogger<BroadcastChannelReader<TData, TResponse>> _logger;
 22
 223    internal BroadcastChannelReader(
 224        ChannelReader<TData>                              dataReader,
 225        int                                               inputDataWriterHashCode,
 226        ChannelWriter<TResponse>                          responseWriter,
 227        RemoveWriterByHashCode                            removeReaderFunction,
 228        ILogger<BroadcastChannelReader<TData, TResponse>> logger
 229    ) {
 230        this._writerHash     = inputDataWriterHashCode;
 231        this._logger         = logger;
 232        this._removeReader   = removeReaderFunction;
 233        this._responseWriter = responseWriter;
 234        this._dataReader     = dataReader;
 235    }
 36
 37    /// <summary>
 38    /// This is only for Dependency Injection purposes and should not be used by the user. Instead use <see cref="IBroad
 39    /// </summary>
 40    /// <param name="broadcastChannelWriter"></param>
 41    [ EditorBrowsable( EditorBrowsableState.Never ) ]
 242    public BroadcastChannelReader( IBroadcastChannelWriter<TData, TResponse> broadcastChannelWriter ) {
 243        ArgumentNullException.ThrowIfNull( broadcastChannelWriter );
 244        ( this._dataReader, this._writerHash, this._removeReader, this._responseWriter, this._logger ) = broadcastChanne
 245        this._logger.LogTrace( "Registered with Writer: {Writer}", broadcastChannelWriter );
 246    }
 47
 48    /* ************************************************** */
 49
 50    /// <inheritdoc cref="System.Threading.Channels.ChannelReader{T}.TryRead"/>
 251    public override bool TryRead( [ MaybeNullWhen( false ) ] out TData item ) => !this._isDisposed ? this._dataReader.Tr
 52
 53    /// <inheritdoc cref="System.Threading.Channels.ChannelReader{T}.TryPeek"/>
 054    public override bool TryPeek( [ MaybeNullWhen( false ) ] out TData item ) => !this._isDisposed ? this._dataReader.Tr
 55
 56    /// <inheritdoc cref="System.Threading.Channels.ChannelReader{T}.WaitToReadAsync"/>
 57    public override ValueTask<bool> WaitToReadAsync( CancellationToken cancellationToken = default ) =>
 258        !this._isDisposed
 259            ? this._dataReader.WaitToReadAsync( cancellationToken )
 260            : ThrowHelper.ThrowObjectDisposedException<ValueTask<bool>>( nameof(BroadcastChannelReader<TData, TResponse>
 61
 62    // warning occurs because there is no `yield` statement, but this is a direct return for ChannelReader<T>.ReadAllAsy
 63#pragma warning disable CS8424
 64    // TODO: try: does [AggressiveInlining] help here?
 65    /// <inheritdoc cref="System.Threading.Channels.ChannelReader{T}.ReadAllAsync"/>
 66    public override IAsyncEnumerable<TData> ReadAllAsync( [ EnumeratorCancellation ] CancellationToken cancellationToken
 067        => !this._isDisposed ? this._dataReader.ReadAllAsync( cancellationToken ) : ThrowHelper.ThrowObjectDisposedExcep
 68
 69#pragma warning restore CS8424
 70
 71    /// <inheritdoc cref="ChannelWriter{T}.WriteAsync" />
 272    public ValueTask WriteResponseAsync( TResponse response, CancellationToken cancellationToken = default ) => this._re
 73
 74
 75    /// <inheritdoc cref="ChannelReader{T}.Completion"/>
 076    public override Task Completion => !this._isDisposed ? this._dataReader.Completion : ThrowHelper.ThrowObjectDisposed
 77
 78    /// <inheritdoc />
 079    public override int Count => !this._isDisposed ? this._dataReader.Count : ThrowHelper.ThrowObjectDisposedException<i
 80
 81    /// <inheritdoc />
 082    public override bool CanCount => !this._isDisposed ? this._dataReader.CanCount : ThrowHelper.ThrowObjectDisposedExce
 83
 84    /// <inheritdoc />
 085    public override bool CanPeek => !this._isDisposed ? this._dataReader.CanPeek : ThrowHelper.ThrowObjectDisposedExcept
 86
 87
 88    /* *
 89     * As long as I have Dispose (){ if (_disposed) ... } it doesn't matter if a transient service is disposed by the de
 90     */
 91
 92    /// <summary>
 93    /// Removes reader from BroadcastChannel
 94    /// </summary>
 95    /// <remarks>
 96    /// This method is only needed because if used in Dependency Injection, it might not be disposed when done using,
 97    /// which means the Channel would continually be written to without being read,
 98    /// wasting potentially significant amounts of memory.
 99    /// <p/>
 100    /// While the documentation says that a dependent/requesting type should never Dispose of an injected type
 101    /// that was created by the ServiceProvider (and the factory pattern can not be used with Open Generic Types),
 102    /// it is still ok (and really <b>MUST</b> be done) for the dependent type to Dispose this <see cref="BroadcastChann
 103    /// as the Disposed status is tracked and it will not be disposed of twice.
 104    /// </remarks>
 2105    public void Dispose( ) {
 2106        this.Dispose( true );
 2107        GC.SuppressFinalize( this );
 2108    }
 109
 110    // ReSharper disable once InconsistentNaming
 111    /// <inheritdoc cref="IDisposable.Dispose"/>
 2112    protected virtual void Dispose( bool disposing ) {
 2113        this._logger.LogTrace( "Dispose({Disposing}) {Type}", disposing, this.GetType().GenericTypeShortDescriptor( useS
 2114        if ( this._isDisposed ) {
 0115            return;
 116        }
 117
 2118        if ( disposing ) {
 2119            this._removeReader( _writerHash );
 2120        }
 121
 2122        this._isDisposed = true;
 2123    }
 124
 125    /// <inheritdoc />
 126    // NULL checking is required here, as this could be called from within the constructor before the properties are set
 127    // ReSharper disable ConditionalAccessQualifierIsNonNullableAccordingToAPIContract
 2128    public override string ToString( ) => $"{this.GetType().GenericTypeShortDescriptor( useShortGenericName: false )} [H
 129    // ReSharper restore ConditionalAccessQualifierIsNonNullableAccordingToAPIContract
 130}
 131
 132/// <inheritdoc />
 133/// <remarks>
 134/// <see cref="BroadcastChannelReader{TData}"/> with a default Response type of <see cref="IBroadcastChannelResponse"/> 
 135/// </remarks>
 136public class BroadcastChannelReader<TData> : BroadcastChannelReader<TData, IBroadcastChannelResponse> {
 137    /// <inheritdoc />
 138    [ EditorBrowsable( EditorBrowsableState.Never ) ]
 139    public BroadcastChannelReader( IBroadcastChannelWriter<TData> broadcastChannelWriter )
 140        : base( broadcastChannelWriter as IBroadcastChannelWriter<TData, IBroadcastChannelResponse>
 141                ?? ThrowHelper.ThrowInvalidCastException<IBroadcastChannelWriter<TData>, IBroadcastChannelWriter<TData, 
 142}