[ci skip] Done with XML documentation for now

Made a few classes internal that were supposed to be
This commit is contained in:
Mark van Renswoude 2019-08-15 11:26:55 +02:00
parent 314a67db00
commit fed377992b
28 changed files with 112 additions and 56 deletions

View File

@ -9,7 +9,7 @@ namespace Tapeti.DataAnnotations
/// <summary>
/// Validates consumed messages using System.ComponentModel.DataAnnotations
/// </summary>
public class DataAnnotationsMessageMiddleware : IMessageMiddleware
internal class DataAnnotationsMessageMiddleware : IMessageMiddleware
{
/// <inheritdoc />
public Task Handle(IMessageContext context, Func<Task> next)

View File

@ -9,7 +9,7 @@ namespace Tapeti.DataAnnotations
/// <summary>
/// Validates published messages using System.ComponentModel.DataAnnotations
/// </summary>
public class DataAnnotationsPublishMiddleware : IPublishMiddleware
internal class DataAnnotationsPublishMiddleware : IPublishMiddleware
{
/// <inheritdoc />
public Task Handle(IPublishContext context, Func<Task> next)

View File

@ -6,7 +6,11 @@ using Tapeti.Flow.FlowHelpers;
namespace Tapeti.Flow.Default
{
public class FlowContinuationMiddleware : IControllerFilterMiddleware, IControllerMessageMiddleware, IControllerCleanupMiddleware
/// <inheritdoc cref="IControllerMessageMiddleware"/> />
/// <summary>
/// Handles methods marked with the Continuation attribute.
/// </summary>
internal class FlowContinuationMiddleware : IControllerFilterMiddleware, IControllerMessageMiddleware, IControllerCleanupMiddleware
{
public async Task Filter(IControllerMessageContext context, Func<Task> next)
{

View File

@ -22,6 +22,7 @@ namespace Tapeti.Flow.Default
private readonly IInternalPublisher publisher;
/// <inheritdoc />
public FlowProvider(ITapetiConfig config, IPublisher publisher)
{
this.config = config;

View File

@ -3,16 +3,20 @@ using System.Linq.Expressions;
using System.Reflection;
using System.Threading.Tasks;
using Tapeti.Config;
using Tapeti.Default;
namespace Tapeti.Flow.Default
{
public class FlowStarter : IFlowStarter
/// <inheritdoc />
/// <summary>
/// Default implementation for IFlowStarter.
/// </summary>
internal class FlowStarter : IFlowStarter
{
private readonly ITapetiConfig config;
private readonly ILogger logger;
/// <inheritdoc />
public FlowStarter(ITapetiConfig config, ILogger logger)
{
this.config = config;
@ -20,22 +24,25 @@ namespace Tapeti.Flow.Default
}
/// <inheritdoc />
public Task Start<TController>(Expression<Func<TController, Func<IYieldPoint>>> methodSelector) where TController : class
{
return CallControllerMethod<TController>(GetExpressionMethod(methodSelector), value => Task.FromResult((IYieldPoint)value), new object[] { });
}
/// <inheritdoc />
public Task Start<TController>(Expression<Func<TController, Func<Task<IYieldPoint>>>> methodSelector) where TController : class
{
return CallControllerMethod<TController>(GetExpressionMethod(methodSelector), value => (Task<IYieldPoint>)value, new object[] {});
}
/// <inheritdoc />
public Task Start<TController, TParameter>(Expression<Func<TController, Func<TParameter, IYieldPoint>>> methodSelector, TParameter parameter) where TController : class
{
return CallControllerMethod<TController>(GetExpressionMethod(methodSelector), value => Task.FromResult((IYieldPoint)value), new object[] {parameter});
}
/// <inheritdoc />
public Task Start<TController, TParameter>(Expression<Func<TController, Func<TParameter, Task<IYieldPoint>>>> methodSelector, TParameter parameter) where TController : class
{
return CallControllerMethod<TController>(GetExpressionMethod(methodSelector), value => (Task<IYieldPoint>)value, new object[] {parameter});

View File

@ -22,12 +22,15 @@ namespace Tapeti.Flow.Default
private volatile bool inUse;
private volatile bool loaded;
/// <inheritdoc />
public FlowStore(IFlowRepository repository)
{
this.repository = repository;
}
/// <inheritdoc />
public async Task Load()
{
if (inUse)
@ -50,6 +53,7 @@ namespace Tapeti.Flow.Default
}
/// <inheritdoc />
public Task<Guid?> FindFlowID(Guid continuationID)
{
if (!loaded)
@ -59,6 +63,7 @@ namespace Tapeti.Flow.Default
}
/// <inheritdoc />
public async Task<IFlowStateLock> LockFlowState(Guid flowID)
{
if (!loaded)
@ -70,18 +75,20 @@ namespace Tapeti.Flow.Default
return flowStatelock;
}
private class FlowStateLock : IFlowStateLock
{
private readonly FlowStore owner;
private readonly Guid flowID;
private volatile IDisposable flowLock;
private FlowState flowState;
public Guid FlowID { get; }
public FlowStateLock(FlowStore owner, Guid flowID, IDisposable flowLock)
{
this.owner = owner;
this.flowID = flowID;
this.FlowID = flowID;
this.flowLock = flowLock;
owner.flowStates.TryGetValue(flowID, out flowState);
@ -94,8 +101,6 @@ namespace Tapeti.Flow.Default
l?.Dispose();
}
public Guid FlowID => flowID;
public Task<FlowState> GetFlowState()
{
if (flowLock == null)
@ -121,22 +126,22 @@ namespace Tapeti.Flow.Default
foreach (var addedContinuation in newFlowState.Continuations.Where(c => flowState == null || !flowState.Continuations.ContainsKey(c.Key)))
{
owner.continuationLookup.TryAdd(addedContinuation.Key, flowID);
owner.continuationLookup.TryAdd(addedContinuation.Key, FlowID);
}
var isNew = flowState == null;
flowState = newFlowState;
owner.flowStates[flowID] = newFlowState;
owner.flowStates[FlowID] = newFlowState;
// Storing the flowstate in the underlying repository
if (isNew)
{
var now = DateTime.UtcNow;
await owner.repository.CreateState(flowID, flowState, now);
await owner.repository.CreateState(FlowID, flowState, now);
}
else
{
await owner.repository.UpdateState(flowID, flowState);
await owner.repository.UpdateState(FlowID, flowState);
}
}
@ -150,12 +155,12 @@ namespace Tapeti.Flow.Default
foreach (var removedContinuation in flowState.Continuations.Keys)
owner.continuationLookup.TryRemove(removedContinuation, out _);
owner.flowStates.TryRemove(flowID, out _);
owner.flowStates.TryRemove(FlowID, out _);
if (flowState != null)
{
flowState = null;
await owner.repository.DeleteState(flowID);
await owner.repository.DeleteState(FlowID);
}
}
}

View File

@ -4,6 +4,9 @@ using System.Threading.Tasks;
namespace Tapeti.Flow.Default
{
/// <summary>
/// Default implementation for IFlowRepository. Does not persist any state, relying on the FlowStore's cache instead.
/// </summary>
public class NonPersistentFlowRepository : IFlowRepository
{
Task<List<KeyValuePair<Guid, T>>> IFlowRepository.GetStates<T>()
@ -11,16 +14,19 @@ namespace Tapeti.Flow.Default
return Task.FromResult(new List<KeyValuePair<Guid, T>>());
}
/// <inheritdoc />
public Task CreateState<T>(Guid flowID, T state, DateTime timestamp)
{
return Task.CompletedTask;
}
/// <inheritdoc />
public Task UpdateState<T>(Guid flowID, T state)
{
return Task.CompletedTask;
}
/// <inheritdoc />
public Task DeleteState(Guid flowID)
{
return Task.CompletedTask;

View File

@ -4,19 +4,27 @@ using System.Threading.Tasks;
namespace Tapeti.Flow.FlowHelpers
{
/// <summary>
/// Implementation of an asynchronous locking mechanism.
/// </summary>
public class LockCollection<T>
{
private readonly Dictionary<T, LockItem> locks;
/// <inheritdoc />
public LockCollection(IEqualityComparer<T> comparer)
{
locks = new Dictionary<T, LockItem>(comparer);
}
/// <summary>
/// Waits for and acquires a lock on the specified key. Dispose the returned value to release the lock.
/// </summary>
/// <param name="key"></param>
public Task<IDisposable> GetLock(T key)
{
// ReSharper disable once InconsistentlySynchronizedField - by design
LockItem nextLi = new LockItem(locks, key);
var nextLi = new LockItem(locks, key);
try
{
bool continueImmediately = false;
@ -45,6 +53,7 @@ namespace Tapeti.Flow.FlowHelpers
return nextLi.GetTask();
}
private class LockItem : IDisposable
{
internal volatile LockItem Next;
@ -83,7 +92,7 @@ namespace Tapeti.Flow.FlowHelpers
if (li != this)
{
// Something is wrong (comparer is not stable?), but we cannot loose the completions sources
// Something is wrong (comparer is not stable?), but we cannot lose the completions sources
while (li.Next != null)
li = li.Next;
li.Next = Next;

View File

@ -2,8 +2,15 @@
namespace Tapeti.Flow.FlowHelpers
{
/// <summary>
/// Converts a method into a unique string representation.
/// </summary>
public static class MethodSerializer
{
/// <summary>
/// Converts a method into a unique string representation.
/// </summary>
/// <param name="method"></param>
public static string Serialize(MethodInfo method)
{
return method.Name + '@' + method.DeclaringType?.Assembly.GetName().Name + ':' + method.DeclaringType?.FullName;

View File

@ -4,11 +4,39 @@ using System.Threading.Tasks;
namespace Tapeti.Flow
{
/// <summary>
/// Provides persistency for flow states.
/// </summary>
public interface IFlowRepository
{
/// <summary>
/// Load the previously persisted flow states.
/// </summary>
/// <returns>A list of flow states, where the key is the unique Flow ID and the value is the deserialized T.</returns>
Task<List<KeyValuePair<Guid, T>>> GetStates<T>();
/// <summary>
/// Stores a new flow state. Guaranteed to be run in a lock for the specified flow ID.
/// </summary>
/// <param name="flowID"></param>
/// <param name="state"></param>
/// <param name="timestamp"></param>
/// <returns></returns>
Task CreateState<T>(Guid flowID, T state, DateTime timestamp);
/// <summary>
/// Updates an existing flow state. Guaranteed to be run in a lock for the specified flow ID.
/// </summary>
/// <param name="flowID"></param>
/// <param name="state"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
Task UpdateState<T>(Guid flowID, T state);
/// <summary>
/// Delete a flow state. Guaranteed to be run in a lock for the specified flow ID.
/// </summary>
/// <param name="flowID"></param>
Task DeleteState(Guid flowID);
}
}

View File

@ -2,8 +2,13 @@
namespace Tapeti.Flow
{
/// <inheritdoc />
/// <summary>
/// Raised when a response is expected to end a flow, but none was provided.
/// </summary>
public class ResponseExpectedException : Exception
{
/// <inheritdoc />
public ResponseExpectedException(string message) : base(message) { }
}
}

View File

@ -2,8 +2,13 @@
namespace Tapeti.Flow
{
/// <inheritdoc />
/// <summary>
/// Raised when an invalid yield point is returned.
/// </summary>
public class YieldPointException : Exception
{
/// <inheritdoc />
public YieldPointException(string message) : base(message) { }
}
}

View File

@ -5,7 +5,7 @@
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<NoWarn>1701;1702;1591</NoWarn>
<NoWarn>1701;1702</NoWarn>
</PropertyGroup>
<ItemGroup>

View File

@ -9,7 +9,7 @@ namespace Tapeti.Transient
/// Implements a binding for transient request response messages.
/// Register this binding using the WithTransient config extension method.
/// </summary>
public class TransientGenericBinding : IBinding
internal class TransientGenericBinding : IBinding
{
private readonly TransientRouter router;
private readonly string dynamicQueuePrefix;

View File

@ -6,7 +6,7 @@ namespace Tapeti.Transient
/// <summary>
/// Default implementation of ITransientPublisher
/// </summary>
public class TransientPublisher : ITransientPublisher
internal class TransientPublisher : ITransientPublisher
{
private readonly TransientRouter router;
private readonly IPublisher publisher;

View File

@ -10,7 +10,7 @@ namespace Tapeti.Transient
/// <summary>
/// Manages active requests and responses. For internal use.
/// </summary>
public class TransientRouter
internal class TransientRouter
{
private readonly int defaultTimeoutMs;
private readonly ConcurrentDictionary<Guid, TaskCompletionSource<object>> map = new ConcurrentDictionary<Guid, TaskCompletionSource<object>>();

View File

@ -9,7 +9,7 @@ namespace Tapeti.Connection
/// <summary>
/// Implements the bridge between the RabbitMQ Client consumer and a Tapeti Consumer
/// </summary>
public class TapetiBasicConsumer : DefaultBasicConsumer
internal class TapetiBasicConsumer : DefaultBasicConsumer
{
private readonly IConsumer consumer;
private readonly Func<ulong, ConsumeResult, Task> onRespond;

View File

@ -9,7 +9,6 @@ using Newtonsoft.Json;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using RabbitMQ.Client.Exceptions;
using RabbitMQ.Client.Framing;
using Tapeti.Config;
using Tapeti.Default;
using Tapeti.Exceptions;
@ -21,7 +20,7 @@ namespace Tapeti.Connection
/// <summary>
/// Implementation of ITapetiClient for the RabbitMQ Client library
/// </summary>
public class TapetiClient : ITapetiClient
internal class TapetiClient : ITapetiClient
{
private const int ReconnectDelay = 5000;
private const int MandatoryReturnTimeout = 30000;

View File

@ -12,7 +12,7 @@ namespace Tapeti.Connection
/// <summary>
/// Implements a RabbitMQ consumer to pass messages to the Tapeti middleware.
/// </summary>
public class TapetiConsumer : IConsumer
internal class TapetiConsumer : IConsumer
{
private readonly ITapetiConfig config;
private readonly string queueName;

View File

@ -1,19 +1,15 @@
using System;
using System.Diagnostics;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using RabbitMQ.Client;
using Tapeti.Annotations;
using Tapeti.Config;
using Tapeti.Default;
using Tapeti.Exceptions;
using Tapeti.Helpers;
namespace Tapeti.Connection
{
/// <inheritdoc />
public class TapetiPublisher : IInternalPublisher
internal class TapetiPublisher : IInternalPublisher
{
private readonly ITapetiConfig config;
private readonly Func<ITapetiClient> clientFactory;

View File

@ -7,7 +7,7 @@ using Tapeti.Config;
namespace Tapeti.Connection
{
/// <inheritdoc />
public class TapetiSubscriber : ISubscriber
internal class TapetiSubscriber : ISubscriber
{
private readonly Func<ITapetiClient> clientFactory;
private readonly ITapetiConfig config;

View File

@ -6,11 +6,7 @@ using Tapeti.Config;
namespace Tapeti.Default
{
/// <inheritdoc />
/// <summary>
/// Default implementation for IControllerBindingContext
/// </summary>
public class ControllerBindingContext : IControllerBindingContext
internal class ControllerBindingContext : IControllerBindingContext
{
private BindingTargetMode? bindingTargetMode;
private readonly List<IControllerMiddlewareBase> middleware = new List<IControllerMiddlewareBase>();

View File

@ -1,11 +1,8 @@
using System;
using System.Collections.Generic;
using Tapeti.Config;
using Tapeti.Config;
namespace Tapeti.Default
{
/// <inheritdoc cref="IControllerMessageContext" />
public class ControllerMessageContext : IControllerMessageContext
internal class ControllerMessageContext : IControllerMessageContext
{
private readonly IMessageContext decoratedContext;

View File

@ -14,7 +14,7 @@ namespace Tapeti.Default
/// instead use the ITapetiConfigBuilder RegisterController / RegisterAllControllers extension
/// methods.
/// </summary>
public class ControllerMethodBinding : IBinding
internal class ControllerMethodBinding : IBinding
{
/// <summary>
/// Contains all the required information to bind a controller method to a queue.

View File

@ -3,11 +3,7 @@ using Tapeti.Config;
namespace Tapeti.Default
{
/// <inheritdoc />
/// <summary>
/// Default implementation of IExceptionStrategyContext.
/// </summary>
public class ExceptionStrategyContext : IExceptionStrategyContext
internal class ExceptionStrategyContext : IExceptionStrategyContext
{
/// <summary>
/// The ConsumeResult as set by the exception strategy. Defaults to Error.

View File

@ -4,8 +4,7 @@ using Tapeti.Config;
namespace Tapeti.Default
{
/// <inheritdoc />
public class MessageContext : IMessageContext
internal class MessageContext : IMessageContext
{
private readonly Dictionary<string, object> items = new Dictionary<string, object>();

View File

@ -6,11 +6,7 @@ using Tapeti.Config;
namespace Tapeti.Default
{
/// <inheritdoc />
/// <summary>
/// Wrapper for RabbitMQ Client's IBasicProperties
/// </summary>
public class RabbitMQMessageProperties : IMessageProperties
internal class RabbitMQMessageProperties : IMessageProperties
{
/// <summary>
/// Provides access to the wrapped IBasicProperties

View File

@ -5,7 +5,7 @@
namespace Tapeti
{
/// <summary>
/// Base class for message controllers
/// Base class for message controllers.
/// </summary>
/// <remarks>
/// Using this base class is not required, you can add the MessageController attribute