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
58 changes: 41 additions & 17 deletions src/core/Akka/Actor/PipeToSupport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,30 @@ 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>
/// <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, IActorRef sender = null, Func<T, object> success = null, Func<Exception, object> failure = null)
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,
bool useConfigureAwait = true)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have to add an overload. Can't do a new optional parameter.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding an overload will actually break everything because it will create an abiguous method fingerprint

Copy link
Member

@Aaronontheweb Aaronontheweb Feb 24, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then re-arrange the new overload as a non-optional parameter that appears before the optional ones - that will resolve that.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to keep the current callsite unchanged - adding a new callsite with a different signature (new explicit boolean parameter) is no problem.

{
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 +61,33 @@ 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>
/// <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,
IActorRef sender = null,
Func<object> success = null,
Func<Exception, object> failure = null,
bool useConfigureAwait = true)
{
sender = sender ?? ActorRefs.NoSender;

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

if (success != null)
{
Expand Down