Skip to content

Commit

Permalink
Introduces recipient Id and RecipientDescription (#19)
Browse files Browse the repository at this point in the history
  • Loading branch information
tommasobertoni authored Jan 6, 2021
2 parents 91ea7b4 + dd163da commit dbf7a08
Show file tree
Hide file tree
Showing 22 changed files with 282 additions and 146 deletions.
2 changes: 1 addition & 1 deletion samples/NScatterGather.Samples.CompetingTasks/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ static void PrettyPrint(IReadOnlyList<Evaluation> evaluations)
foreach (var invocation in resultsWithPrice.OrderBy(x => x.Duration))
{
var productName = isFirstPrice ? evaluation.Product.Name : string.Empty;
var supplierName = invocation.RecipientName;
var supplierName = invocation.Recipient.Name;
var supplierPrice = invocation.Result!.Value;
var isBestPrice = supplierPrice == bestPrice;
var resultColor = isBestPrice ? "green3_1" : "red";
Expand Down
4 changes: 2 additions & 2 deletions samples/NScatterGather.Samples/Samples/4.HandleErrors.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public async Task Run()
Console.WriteLine($"Completed {response.Completed.Count}");
Console.WriteLine(
$"Faulted {response.Faulted.Count}: " +
$"{response.Faulted[0].RecipientType?.Name} => " +
$"{response.Faulted[0].Recipient.Type?.Name} => " +
$"{response.Faulted[0].Exception?.Message}");
}

Expand All @@ -34,7 +34,7 @@ public string Get(string s) =>

class Bar
{
public string Todo(string s) =>
public string Todo(string _) =>
throw new NotImplementedException("TODO");
}
}
Expand Down
6 changes: 3 additions & 3 deletions samples/NScatterGather.Samples/Samples/5.Timeout.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ public async Task Run()
Console.WriteLine($"Completed {response.Completed.Count}");
Console.WriteLine(
$"Incomplete {response.Incomplete.Count}: " +
$"{response.Incomplete[0].RecipientType?.Name}, " +
$"{response.Incomplete[1].RecipientType?.Name}");
$"{response.Incomplete[0].Recipient.Type?.Name}, " +
$"{response.Incomplete[1].Recipient.Type?.Name}");
}

class Foo
Expand All @@ -46,7 +46,7 @@ public async Task<int> Long(int n)

class Baz
{
public Task<int> Block(int n)
public Task<int> Block(int _)
{
var tcs = new TaskCompletionSource<int>();
return tcs.Task; // It will never complete.
Expand Down
19 changes: 5 additions & 14 deletions src/NScatterGather/Invocations/CompletedInvocation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,37 +3,28 @@

namespace NScatterGather
{
public class CompletedInvocation<TResponse>
public class CompletedInvocation<TResponse> : Invocation
{
public string? RecipientName { get; }

public Type? RecipientType { get; }

[AllowNull, MaybeNull]
public TResponse Result { get; }

public TimeSpan Duration { get; }

internal CompletedInvocation(
string? recipientName,
Type? recipientType,
RecipientDescription recipient,
[AllowNull] TResponse result,
TimeSpan duration)
TimeSpan duration) : base(recipient)
{
RecipientName = recipientName;
RecipientType = recipientType;
Result = result;
Duration = duration;
}

public void Deconstruct(
out string? recipientName,
out Type? recipientType,
out RecipientDescription recipient,
[MaybeNull] out TResponse result,
out TimeSpan duration)
{
recipientName = RecipientName;
recipientType = RecipientType;
recipient = Recipient;
result = Result;
duration = Duration;
}
Expand Down
19 changes: 5 additions & 14 deletions src/NScatterGather/Invocations/FaultedInvocation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,27 @@

namespace NScatterGather
{
public class FaultedInvocation
public class FaultedInvocation : Invocation
{
public string? RecipientName { get; }

public Type? RecipientType { get; }

public Exception? Exception { get; }

public TimeSpan Duration { get; }

internal FaultedInvocation(
string? recipientName,
Type? recipientType,
RecipientDescription recipient,
Exception? exception,
TimeSpan duration)
TimeSpan duration) : base(recipient)
{
RecipientName = recipientName;
RecipientType = recipientType;
Exception = exception;
Duration = duration;
}

public void Deconstruct(
out string? recipientName,
out Type? recipientType,
out RecipientDescription recipient,
out Exception? exception,
out TimeSpan duration)
{
recipientName = RecipientName;
recipientType = RecipientType;
recipient = Recipient;
exception = Exception;
duration = Duration;
}
Expand Down
24 changes: 3 additions & 21 deletions src/NScatterGather/Invocations/IncompleteInvocation.cs
Original file line number Diff line number Diff line change
@@ -1,27 +1,9 @@
using System;

namespace NScatterGather
namespace NScatterGather
{
public class IncompleteInvocation
public class IncompleteInvocation : Invocation
{
public string? RecipientName { get; }

public Type? RecipientType { get; }

internal IncompleteInvocation(
string? recipientName,
Type? recipientType)
internal IncompleteInvocation(RecipientDescription recipient) : base(recipient)
{
RecipientName = recipientName;
RecipientType = recipientType;
}

public void Deconstruct(
out string? recipientName,
out Type? recipientType)
{
recipientName = RecipientName;
recipientType = RecipientType;
}
}
}
12 changes: 12 additions & 0 deletions src/NScatterGather/Invocations/Invocation.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace NScatterGather
{
public abstract class Invocation
{
public RecipientDescription Recipient { get; }

protected Invocation(RecipientDescription recipient)
{
Recipient = recipient;
}
}
}
45 changes: 45 additions & 0 deletions src/NScatterGather/Invocations/RecipientDescription.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using System;

namespace NScatterGather
{
public class RecipientDescription
{
public Guid Id { get; }

public string? Name { get; }

public Type? Type { get; }

public Lifetime Lifetime { get; }

public CollisionStrategy CollisionStrategy { get; }

internal RecipientDescription(
Guid id,
string? name,
Type? type,
Lifetime lifetime,
CollisionStrategy collisionStrategy)
{
Id = id;
Name = name;
Type = type;
Lifetime = lifetime;
CollisionStrategy = collisionStrategy;
}

public void Deconstruct(
out Guid id,
out string? name,
out Type? type,
out Lifetime lifetime,
out CollisionStrategy collisionStrategy)
{
id = Id;
name = Name;
type = Type;
lifetime = Lifetime;
collisionStrategy = CollisionStrategy;
}
}
}
21 changes: 21 additions & 0 deletions src/NScatterGather/Invocations/RecipientDescriptionFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using NScatterGather.Recipients;

namespace NScatterGather.Invocations
{
internal class RecipientDescriptionFactory
{
public static RecipientDescription CreateFrom(Recipient recipient)
{
var recipientType = recipient is TypeRecipient ir ? ir.Type : null;

var description = new RecipientDescription(
recipient.Id,
recipient.Name,
recipientType,
recipient.Lifetime,
recipient.CollisionStrategy);

return description;
}
}
}
49 changes: 25 additions & 24 deletions src/NScatterGather/Recipients/Collection/RecipientsCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,36 +24,36 @@ public RecipientsCollection(CollisionStrategy defaultCollisionStrategy = IgnoreR
_defaultCollisionStrategy = defaultCollisionStrategy;
}

public void Add<TRecipient>(string name) =>
AddWithDefaultFactoryMethod<TRecipient>(name: name);
public Guid Add<TRecipient>(string name) =>
AddTypeRecipientWithDefaultFactoryMethod<TRecipient>(name: name);

public void Add<TRecipient>(Lifetime lifetime) =>
AddWithDefaultFactoryMethod<TRecipient>(lifetime: lifetime);
public Guid Add<TRecipient>(Lifetime lifetime) =>
AddTypeRecipientWithDefaultFactoryMethod<TRecipient>(lifetime: lifetime);

public void Add<TRecipient>(Func<TRecipient> factoryMethod) =>
Internal_Add(factoryMethod: factoryMethod);
public Guid Add<TRecipient>(Func<TRecipient> factoryMethod) =>
AddTypeRecipient(factoryMethod: factoryMethod);

public void Add<TRecipient>(CollisionStrategy collisionStrategy) =>
AddWithDefaultFactoryMethod<TRecipient>(collisionStrategy: collisionStrategy);
public Guid Add<TRecipient>(CollisionStrategy collisionStrategy) =>
AddTypeRecipientWithDefaultFactoryMethod<TRecipient>(collisionStrategy: collisionStrategy);

public void Add<TRecipient>(
public Guid Add<TRecipient>(
string? name = null,
Lifetime lifetime = Transient,
CollisionStrategy? collisionStrategy = null)
{
AddWithDefaultFactoryMethod<TRecipient>(name, lifetime, collisionStrategy);
return AddTypeRecipientWithDefaultFactoryMethod<TRecipient>(name, lifetime, collisionStrategy);
}

public void Add<TRecipient>(
public Guid Add<TRecipient>(
Func<TRecipient> factoryMethod,
string? name = null,
Lifetime lifetime = Transient,
CollisionStrategy? collisionStrategy = null)
{
Internal_Add(factoryMethod, name, lifetime, collisionStrategy);
return AddTypeRecipient(factoryMethod, name, lifetime, collisionStrategy);
}

internal void AddWithDefaultFactoryMethod<TRecipient>(
internal Guid AddTypeRecipientWithDefaultFactoryMethod<TRecipient>(
string? name = null,
Lifetime lifetime = Transient,
CollisionStrategy? collisionStrategy = null)
Expand All @@ -63,7 +63,7 @@ internal void AddWithDefaultFactoryMethod<TRecipient>(

static TRecipient factoryMethod() => ((TRecipient)Activator.CreateInstance(typeof(TRecipient)))!;

Internal_Add(factoryMethod, name, lifetime, collisionStrategy);
return AddTypeRecipient(factoryMethod, name, lifetime, collisionStrategy);

// Local functions.

Expand All @@ -74,7 +74,7 @@ static bool HasADefaultConstructor<T>()
}
}

internal void Internal_Add<TRecipient>(
internal Guid AddTypeRecipient<TRecipient>(
Func<TRecipient> factoryMethod,
string? name = null,
Lifetime lifetime = Transient,
Expand All @@ -86,10 +86,12 @@ internal void Internal_Add<TRecipient>(
var typeRecipient = TypeRecipient.Create(
_registry, factoryMethod, name, lifetime, collisionStrategy ?? _defaultCollisionStrategy);

Add(typeRecipient);
_recipients.Add(typeRecipient);

return typeRecipient.Id;
}

public void Add(
public Guid Add(
object instance,
string? name = null,
CollisionStrategy? collisionStrategy = null)
Expand All @@ -100,10 +102,12 @@ public void Add(
var instanceRecipient = InstanceRecipient.Create(
_registry, instance, name, collisionStrategy ?? _defaultCollisionStrategy);

Add(instanceRecipient);
_recipients.Add(instanceRecipient);

return instanceRecipient.Id;
}

public void Add<TRequest, TResponse>(
public Guid Add<TRequest, TResponse>(
Func<TRequest, TResponse> @delegate,
string? name = null)
{
Expand All @@ -112,12 +116,9 @@ public void Add<TRequest, TResponse>(

var delegateRecipient = DelegateRecipient.Create(@delegate, name);

Add(delegateRecipient);
}
_recipients.Add(delegateRecipient);

private void Add(Recipient recipient)
{
_recipients.Add(recipient);
return delegateRecipient.Id;
}

internal IRecipientsScope CreateScope()
Expand Down
2 changes: 2 additions & 0 deletions src/NScatterGather/Recipients/Recipient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ namespace NScatterGather.Recipients
{
internal abstract class Recipient
{
public Guid Id { get; } = Guid.NewGuid();

public string? Name { get; }

public Lifetime Lifetime { get; }
Expand Down
4 changes: 2 additions & 2 deletions src/NScatterGather/Recipients/Run/RecipientRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ private void InspectAndExtract(Task<TResult> task)

private Exception? ExtractException(Exception exception)
{
if (exception is AggregateException aEx && aEx.InnerExceptions.Count == 1)
return aEx.InnerException is null ? aEx : ExtractException(aEx.InnerException);
if (exception is AggregateException aEx)
return aEx.InnerExceptions.Count == 1 ? ExtractException(aEx.InnerException!) : aEx;

if (exception is TargetInvocationException tIEx)
return tIEx.InnerException is null ? tIEx : ExtractException(tIEx.InnerException);
Expand Down
7 changes: 2 additions & 5 deletions src/NScatterGather/Responses/AggregatedResponseExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,14 @@ namespace NScatterGather
{
public static class AggregatedResponseExtensions
{
public static IReadOnlyDictionary<Type, TResult> AsResultsDictionary<TResult>(
public static IReadOnlyDictionary<RecipientDescription, TResult> AsResultsDictionary<TResult>(
this AggregatedResponse<TResult> aggregatedResponse)
{
if (aggregatedResponse is null)
throw new ArgumentNullException(nameof(aggregatedResponse));

var dictionary = aggregatedResponse.Completed
.Where(x => x.RecipientType is not null)
.ToDictionary(
x => x.RecipientType!,
x => x.Result!);
.ToDictionary(keySelector: i => i.Recipient, elementSelector: i => i.Result!);

return dictionary;
}
Expand Down
Loading

0 comments on commit dbf7a08

Please sign in to comment.