Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make PipeTo ConfigureAwait() optional #5684

Merged
merged 8 commits into from
Feb 24, 2022
2 changes: 2 additions & 0 deletions src/core/Akka.API.Tests/CoreAPISpec.ApproveCore.approved.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1387,7 +1387,9 @@ namespace Akka.Actor
public class static PipeToSupport
{
public static System.Threading.Tasks.Task PipeTo<T>(this System.Threading.Tasks.Task<T> taskToPipe, Akka.Actor.ICanTell recipient, Akka.Actor.IActorRef sender = null, System.Func<T, object> success = null, System.Func<System.Exception, object> failure = null) { }
public static System.Threading.Tasks.Task PipeTo<T>(this System.Threading.Tasks.Task<T> taskToPipe, Akka.Actor.ICanTell recipient, bool useConfigureAwait, Akka.Actor.IActorRef sender = null, System.Func<T, object> success = null, System.Func<System.Exception, object> failure = null) { }
public static System.Threading.Tasks.Task PipeTo(this System.Threading.Tasks.Task taskToPipe, Akka.Actor.ICanTell recipient, Akka.Actor.IActorRef sender = null, System.Func<object> success = null, System.Func<System.Exception, object> failure = null) { }
public static System.Threading.Tasks.Task PipeTo(this System.Threading.Tasks.Task taskToPipe, Akka.Actor.ICanTell recipient, bool useConfigureAwait, Akka.Actor.IActorRef sender = null, System.Func<object> success = null, System.Func<System.Exception, object> failure = null) { }
}
public sealed class PoisonPill : Akka.Actor.IAutoReceivedMessage, Akka.Actor.IPossiblyHarmful, Akka.Event.IDeadLetterSuppression
{
Expand Down
95 changes: 78 additions & 17 deletions src/core/Akka/Actor/PipeToSupport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,49 @@ public static class PipeToSupport
/// Pipes the output of a Task directly to the <paramref name="recipient"/>'s mailbox once
/// the task completes
/// </summary>
/// <typeparam name="T">TBD</typeparam>
/// <param name="taskToPipe">TBD</param>
/// <param name="recipient">TBD</param>
/// <param name="sender">TBD</param>
/// <param name="success">TBD</param>
/// <param name="failure">TBD</param>
/// <typeparam name="T">The type of result of the Task</typeparam>
/// <param name="taskToPipe">The Task that result needs to be piped to an actor</param>
/// <param name="recipient">The actor that will receive the Task result</param>
/// <param name="sender">The IActorRef that will be used as the sender of the result. Defaults to <see cref="ActorRefs.Nobody"/> </param>
/// <param name="success">A callback function that will be called on Task success. Defaults to <c>null</c> for no callback</param>
/// <param name="failure">A callback function that will be called on Task failure. Defaults to <c>null</c> for no callback</param>
/// <returns>A detached task</returns>
public static async Task PipeTo<T>(this Task<T> taskToPipe, ICanTell recipient, IActorRef sender = null, Func<T, object> success = null, Func<Exception, object> failure = null)
public static Task PipeTo<T>(
this Task<T> taskToPipe,
ICanTell recipient,
IActorRef sender = null,
Func<T, object> success = null,
Func<Exception, object> failure = null)
=> PipeTo(taskToPipe, recipient, true, sender, success, failure);

/// <summary>
/// Pipes the output of a Task directly to the <paramref name="recipient"/>'s mailbox once
/// the task completes
/// </summary>
/// <typeparam name="T">The type of result of the Task</typeparam>
/// <param name="taskToPipe">The Task that result needs to be piped to an actor</param>
/// <param name="recipient">The actor that will receive the Task result</param>
/// <param name="sender">The IActorRef that will be used as the sender of the result. Defaults to <see cref="ActorRefs.Nobody"/> </param>
/// <param name="success">A callback function that will be called on Task success. Defaults to <c>null</c> for no callback</param>
/// <param name="failure">A callback function that will be called on Task failure. Defaults to <c>null</c> for no callback</param>
/// <param name="useConfigureAwait">If set to true, <c>taskToPipe</c> will be awaited using <c>ConfigureAwait(false)</c></param>
/// <returns>A detached task</returns>
public static async Task PipeTo<T>(
this Task<T> taskToPipe,
ICanTell recipient,
bool useConfigureAwait,
IActorRef sender = null,
Func<T, object> success = null,
Func<Exception, object> failure = null)
{
sender = sender ?? ActorRefs.NoSender;

try
{
var result = await taskToPipe.ConfigureAwait(false);
var result = useConfigureAwait
? await taskToPipe.ConfigureAwait(false)
: await taskToPipe;

recipient.Tell(success != null
? success(result)
: result, sender);
Expand All @@ -51,19 +80,51 @@ public static async Task PipeTo<T>(this Task<T> taskToPipe, ICanTell recipient,
/// Pipes the output of a Task directly to the <paramref name="recipient"/>'s mailbox once
/// the task completes. As this task has no result, only exceptions will be piped to the <paramref name="recipient"/>
/// </summary>
/// <param name="taskToPipe">TBD</param>
/// <param name="recipient">TBD</param>
/// <param name="sender">TBD</param>
/// <param name="success">TBD</param>
/// <param name="failure">TBD</param>
/// <returns>TBD</returns>
public static async Task PipeTo(this Task taskToPipe, ICanTell recipient, IActorRef sender = null, Func<object> success = null, Func<Exception, object> failure = null)
/// <param name="taskToPipe">The Task that result needs to be piped to an actor</param>
/// <param name="recipient">The actor that will receive the Task result</param>
/// <param name="sender">The IActorRef that will be used as the sender of the result. Defaults to <see cref="ActorRefs.Nobody"/> </param>
/// <param name="success">A callback function that will be called on Task success. Defaults to <c>null</c> for no callback</param>
/// <param name="failure">A callback function that will be called on Task failure. Defaults to <c>null</c> for no callback</param>
/// <returns>A detached task</returns>
public static Task PipeTo(
this Task taskToPipe,
ICanTell recipient,
IActorRef sender = null,
Func<object> success = null,
Func<Exception, object> failure = null)
=> PipeTo(taskToPipe, recipient, true, sender, success, failure);

/// <summary>
/// Pipes the output of a Task directly to the <paramref name="recipient"/>'s mailbox once
/// the task completes. As this task has no result, only exceptions will be piped to the <paramref name="recipient"/>
/// </summary>
/// <param name="taskToPipe">The Task that result needs to be piped to an actor</param>
/// <param name="recipient">The actor that will receive the Task result</param>
/// <param name="sender">The IActorRef that will be used as the sender of the result. Defaults to <see cref="ActorRefs.Nobody"/> </param>
/// <param name="success">A callback function that will be called on Task success. Defaults to <c>null</c> for no callback</param>
/// <param name="failure">A callback function that will be called on Task failure. Defaults to <c>null</c> for no callback</param>
/// <param name="useConfigureAwait">If set to true, <c>taskToPipe</c> will be awaited using <c>ConfigureAwait(false)</c></param>
/// <returns>A detached task</returns>
public static async Task PipeTo(
this Task taskToPipe,
ICanTell recipient,
bool useConfigureAwait,
IActorRef sender = null,
Func<object> success = null,
Func<Exception, object> failure = null)
{
sender = sender ?? ActorRefs.NoSender;

try
{
await taskToPipe.ConfigureAwait(false);
{
if (useConfigureAwait)
{
await taskToPipe.ConfigureAwait(false);
}
else
{
await taskToPipe;
}

if (success != null)
{
Expand Down