Skip to content

Commit

Permalink
Make PipeTo ConfigureAwait() optional (#5684)
Browse files Browse the repository at this point in the history
* Remove ConfigureAwait() from PipeTo()

* Remove ConfigureAwait() from PipeTo()

* Add ConfigureAwait back to PipeTo, make it configurable instead

* Update API Approval list

* Add function overload for backward compatibility

* Update API Approval list

Co-authored-by: Gregorius Soedharmo <gregorius.soedharmo@petabridge.com>
  • Loading branch information
Arkatufus and Greg-Petabridge committed Feb 24, 2022
1 parent 700f33d commit 655e4f3
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 17 deletions.
2 changes: 2 additions & 0 deletions src/core/Akka.API.Tests/CoreAPISpec.ApproveCore.approved.txt
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
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

0 comments on commit 655e4f3

Please sign in to comment.