2017-01-31 11:01:08 +00:00
|
|
|
|
using System;
|
2017-02-15 21:05:01 +00:00
|
|
|
|
using System.Linq.Expressions;
|
2017-01-31 11:01:08 +00:00
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
2018-12-19 19:50:56 +00:00
|
|
|
|
// ReSharper disable UnusedMember.Global
|
|
|
|
|
|
2017-01-31 11:01:08 +00:00
|
|
|
|
namespace Tapeti.Flow
|
|
|
|
|
{
|
2019-08-14 18:48:40 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Provides methods to build an IYieldPoint to indicate if and how Flow should continue.
|
|
|
|
|
/// </summary>
|
2017-01-31 11:01:08 +00:00
|
|
|
|
public interface IFlowProvider
|
|
|
|
|
{
|
2019-08-14 18:48:40 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Publish a request message and continue the flow when the response arrives.
|
|
|
|
|
/// The request message must be marked with the [Request] attribute, and the
|
|
|
|
|
/// Response type must match. Used for asynchronous response handlers.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="message"></param>
|
|
|
|
|
/// <param name="responseHandler"></param>
|
|
|
|
|
/// <typeparam name="TRequest"></typeparam>
|
|
|
|
|
/// <typeparam name="TResponse"></typeparam>
|
2017-01-31 11:01:08 +00:00
|
|
|
|
IYieldPoint YieldWithRequest<TRequest, TResponse>(TRequest message, Func<TResponse, Task<IYieldPoint>> responseHandler);
|
|
|
|
|
|
2019-08-14 18:48:40 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Publish a request message and continue the flow when the response arrives.
|
|
|
|
|
/// The request message must be marked with the [Request] attribute, and the
|
|
|
|
|
/// Response type must match. Used for synchronous response handlers.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <remarks>
|
|
|
|
|
/// The reason why this requires the extra 'Sync' in the name: one does not simply overload methods
|
|
|
|
|
/// with Task vs non-Task Funcs. "Ambiguous call". Apparantly this is because a return type
|
|
|
|
|
/// of a method is not part of its signature,according to:
|
|
|
|
|
/// http://stackoverflow.com/questions/18715979/ambiguity-with-action-and-func-parameter
|
|
|
|
|
/// </remarks>
|
|
|
|
|
/// <param name="message"></param>
|
|
|
|
|
/// <param name="responseHandler"></param>
|
|
|
|
|
/// <typeparam name="TRequest"></typeparam>
|
|
|
|
|
/// <typeparam name="TResponse"></typeparam>
|
|
|
|
|
/// <returns></returns>
|
2017-01-31 11:01:08 +00:00
|
|
|
|
IYieldPoint YieldWithRequestSync<TRequest, TResponse>(TRequest message, Func<TResponse, IYieldPoint> responseHandler);
|
|
|
|
|
|
2019-08-14 18:48:40 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Create a request builder to publish one or more requests messages. Call Yield on the resulting builder
|
|
|
|
|
/// to acquire an IYieldPoint.
|
|
|
|
|
/// </summary>
|
2017-01-31 11:01:08 +00:00
|
|
|
|
IFlowParallelRequestBuilder YieldWithParallelRequest();
|
|
|
|
|
|
2019-08-14 18:48:40 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// End the flow by publishing the specified response message. Only allowed, and required, when the
|
|
|
|
|
/// current flow was started by a message handler for a Request message.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="message"></param>
|
|
|
|
|
/// <typeparam name="TResponse"></typeparam>
|
2017-01-31 11:01:08 +00:00
|
|
|
|
IYieldPoint EndWithResponse<TResponse>(TResponse message);
|
2019-08-14 18:48:40 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// End the flow and dispose any state.
|
|
|
|
|
/// </summary>
|
2017-01-31 11:01:08 +00:00
|
|
|
|
IYieldPoint End();
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-14 18:48:40 +00:00
|
|
|
|
|
2017-02-15 21:05:01 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Allows starting a flow outside of a message handler.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public interface IFlowStarter
|
|
|
|
|
{
|
2019-08-14 18:48:40 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Starts a new flow.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="methodSelector"></param>
|
2017-02-15 21:05:01 +00:00
|
|
|
|
Task Start<TController>(Expression<Func<TController, Func<IYieldPoint>>> methodSelector) where TController : class;
|
2019-08-14 18:48:40 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Starts a new flow.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="methodSelector"></param>
|
2017-02-15 21:05:01 +00:00
|
|
|
|
Task Start<TController>(Expression<Func<TController, Func<Task<IYieldPoint>>>> methodSelector) where TController : class;
|
2019-08-14 18:48:40 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Starts a new flow and passes the parameter to the method.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="methodSelector"></param>
|
|
|
|
|
/// <param name="parameter"></param>
|
2017-09-22 09:19:49 +00:00
|
|
|
|
Task Start<TController, TParameter>(Expression<Func<TController, Func<TParameter, IYieldPoint>>> methodSelector, TParameter parameter) where TController : class;
|
2019-08-14 18:48:40 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Starts a new flow and passes the parameter to the method.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="methodSelector"></param>
|
|
|
|
|
/// <param name="parameter"></param>
|
2017-09-22 09:19:49 +00:00
|
|
|
|
Task Start<TController, TParameter>(Expression<Func<TController, Func<TParameter, Task<IYieldPoint>>>> methodSelector, TParameter parameter) where TController : class;
|
2017-02-15 21:05:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-08-14 18:48:40 +00:00
|
|
|
|
|
2017-02-15 21:05:01 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Internal interface. Do not call directly.
|
|
|
|
|
/// </summary>
|
2017-01-31 11:01:08 +00:00
|
|
|
|
public interface IFlowHandler
|
|
|
|
|
{
|
2019-08-14 18:48:40 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Executes the YieldPoint for the given message context.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="context"></param>
|
|
|
|
|
/// <param name="yieldPoint"></param>
|
2019-08-15 10:04:03 +00:00
|
|
|
|
Task Execute(IFlowHandlerContext context, IYieldPoint yieldPoint);
|
2017-01-31 11:01:08 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-08-14 18:48:40 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Builder to publish one or more request messages and continuing the flow when the responses arrive.
|
|
|
|
|
/// </summary>
|
2017-01-31 11:01:08 +00:00
|
|
|
|
public interface IFlowParallelRequestBuilder
|
|
|
|
|
{
|
2019-08-14 18:48:40 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Publish a request message and continue the flow when the response arrives.
|
|
|
|
|
/// Note that the response handler can not influence the flow as it does not return a YieldPoint.
|
|
|
|
|
/// It can instead store state in the controller for the continuation passed to the Yield method.
|
|
|
|
|
/// Used for asynchronous response handlers.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="message"></param>
|
|
|
|
|
/// <param name="responseHandler"></param>
|
2017-01-31 11:01:08 +00:00
|
|
|
|
IFlowParallelRequestBuilder AddRequest<TRequest, TResponse>(TRequest message, Func<TResponse, Task> responseHandler);
|
2019-08-14 18:48:40 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Publish a request message and continue the flow when the response arrives.
|
|
|
|
|
/// Note that the response handler can not influence the flow as it does not return a YieldPoint.
|
|
|
|
|
/// It can instead store state in the controller for the continuation passed to the Yield method.
|
|
|
|
|
/// Used for synchronous response handlers.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="message"></param>
|
|
|
|
|
/// <param name="responseHandler"></param>
|
2017-01-31 11:01:08 +00:00
|
|
|
|
IFlowParallelRequestBuilder AddRequestSync<TRequest, TResponse>(TRequest message, Action<TResponse> responseHandler);
|
|
|
|
|
|
2019-08-14 18:48:40 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Constructs an IYieldPoint to continue the flow when responses arrive.
|
|
|
|
|
/// The continuation method is called when all responses have arrived.
|
|
|
|
|
/// Response handlers and the continuation method are guaranteed thread-safe access to the
|
|
|
|
|
/// controller and can store state.
|
|
|
|
|
/// Used for asynchronous continuation methods.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="continuation"></param>
|
2017-01-31 11:01:08 +00:00
|
|
|
|
IYieldPoint Yield(Func<Task<IYieldPoint>> continuation);
|
2019-08-14 18:48:40 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Constructs an IYieldPoint to continue the flow when responses arrive.
|
|
|
|
|
/// The continuation method is called when all responses have arrived.
|
|
|
|
|
/// Response handlers and the continuation method are guaranteed thread-safe access to the
|
|
|
|
|
/// controller and can store state.
|
|
|
|
|
/// Used for synchronous continuation methods.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="continuation"></param>
|
2017-02-12 18:04:26 +00:00
|
|
|
|
IYieldPoint YieldSync(Func<IYieldPoint> continuation);
|
2017-01-31 11:01:08 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-08-14 18:48:40 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Defines if and how the Flow should continue. Construct using any of the IFlowProvider methods.
|
|
|
|
|
/// </summary>
|
2017-01-31 11:01:08 +00:00
|
|
|
|
public interface IYieldPoint
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
}
|