Skip to content

Commit

Permalink
Translate resource.
Browse files Browse the repository at this point in the history
  • Loading branch information
Codespilot committed Sep 16, 2023
1 parent 92f6deb commit d88358c
Show file tree
Hide file tree
Showing 19 changed files with 947 additions and 481 deletions.
132 changes: 67 additions & 65 deletions Source/Euonia.Modularity/Core/ModuleHelper.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Reflection;
using System.Diagnostics;
using System.Reflection;

namespace Nerosoft.Euonia.Modularity;

Expand All @@ -7,78 +8,79 @@ namespace Nerosoft.Euonia.Modularity;
/// </summary>
public static class ModuleHelper
{
/// <summary>
///
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
public static bool IsModule(Type type)
{
var typeInfo = type.GetTypeInfo();
/// <summary>
///
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
public static bool IsModule(Type type)
{
var typeInfo = type.GetTypeInfo();

return
typeInfo.IsClass &&
!typeInfo.IsAbstract &&
!typeInfo.IsGenericType &&
typeof(IModuleContext).GetTypeInfo().IsAssignableFrom(type);
}
return
typeInfo.IsClass &&
!typeInfo.IsAbstract &&
!typeInfo.IsGenericType &&
typeof(IModuleContext).GetTypeInfo().IsAssignableFrom(type);
}

internal static void CheckModuleType(Type moduleType)
{
if (!IsModule(moduleType))
{
throw new ArgumentException("Given type is not an module: " + moduleType.AssemblyQualifiedName);
}
}
internal static void CheckModuleType(Type moduleType)
{
if (!IsModule(moduleType))
{
throw new ArgumentException("Given type is not an module: " + moduleType.AssemblyQualifiedName);
}
}

/// <summary>
///
/// </summary>
/// <param name="startupModuleType"></param>
/// <returns></returns>
internal static List<Type> FindAllModuleTypes(Type startupModuleType)
{
var moduleTypes = new List<Type>();
AddModuleAndDependenciesRecursively(moduleTypes, startupModuleType);
return moduleTypes;
}
/// <summary>
///
/// </summary>
/// <param name="startupModuleType"></param>
/// <returns></returns>
internal static List<Type> FindAllModuleTypes(Type startupModuleType)
{
var moduleTypes = new List<Type>();
AddModuleAndDependenciesRecursively(moduleTypes, startupModuleType);
return moduleTypes;
}

/// <summary>
///
/// </summary>
/// <param name="moduleType"></param>
/// <returns></returns>
internal static List<Type> FindDependedModuleTypes(Type moduleType)
{
CheckModuleType(moduleType);
/// <summary>
///
/// </summary>
/// <param name="moduleType"></param>
/// <returns></returns>
internal static List<Type> FindDependedModuleTypes(Type moduleType)
{
CheckModuleType(moduleType);

var dependencies = new List<Type>();
var attributes = moduleType.GetCustomAttributes(typeof(DependsOnAttribute), true).OfType<DependsOnAttribute>();
foreach (var attribute in attributes)
{
foreach (var type in attribute.ModuleTypes)
{
dependencies.AddIfNotContains(type);
}
}
var dependencies = new List<Type>();
var attributes = moduleType.GetCustomAttributes(typeof(DependsOnAttribute), true).OfType<DependsOnAttribute>();
foreach (var attribute in attributes)
{
foreach (var type in attribute.ModuleTypes)
{
dependencies.AddIfNotContains(type);
}
}

return dependencies;
}
return dependencies;
}

private static void AddModuleAndDependenciesRecursively(ICollection<Type> moduleTypes, Type moduleType, int depth = 0)
{
CheckModuleType(moduleType);
private static void AddModuleAndDependenciesRecursively(ICollection<Type> moduleTypes, Type moduleType, int depth = 0)
{
Debug.WriteLine($"Module:{moduleType.Name}, Depth: {depth}");
CheckModuleType(moduleType);

if (moduleTypes.Contains(moduleType))
{
return;
}
if (moduleTypes.Contains(moduleType))
{
return;
}

moduleTypes.Add(moduleType);
moduleTypes.Add(moduleType);

foreach (var dependencyModuleType in FindDependedModuleTypes(moduleType))
{
AddModuleAndDependenciesRecursively(moduleTypes, dependencyModuleType, depth + 1);
}
}
foreach (var dependencyModuleType in FindDependedModuleTypes(moduleType))
{
AddModuleAndDependenciesRecursively(moduleTypes, dependencyModuleType, depth + 1);
}
}
}
213 changes: 105 additions & 108 deletions Source/Euonia.Threading.Azure/AzureSynchronizationOptionsBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,124 +5,121 @@
/// </summary>
public sealed class AzureSynchronizationOptionsBuilder
{
/// <summary>
/// From https://docs.microsoft.com/en-us/rest/api/storageservices/lease-blob:
/// "The lock duration can be 15 to 60 seconds, or can be infinite"
/// </summary>
internal static readonly TimeoutValue MinLeaseDuration = TimeSpan.FromSeconds(15),
MaxNonInfiniteLeaseDuration = TimeSpan.FromSeconds(60),
DefaultLeaseDuration = TimeSpan.FromSeconds(30);
/// <summary>
/// From https://docs.microsoft.com/en-us/rest/api/storageservices/lease-blob:
/// "The lock duration can be 15 to 60 seconds, or can be infinite"
/// </summary>
internal static readonly TimeoutValue MinLeaseDuration = TimeSpan.FromSeconds(15),
MaxNonInfiniteLeaseDuration = TimeSpan.FromSeconds(60),
DefaultLeaseDuration = TimeSpan.FromSeconds(30);

private TimeoutValue? _duration, _renewalCadence, _minBusyWaitSleepTime, _maxBusyWaitSleepTime;
private TimeoutValue? _duration, _renewalCadence, _minBusyWaitSleepTime, _maxBusyWaitSleepTime;

internal AzureSynchronizationOptionsBuilder()
{
}
internal AzureSynchronizationOptionsBuilder()
{
}

/// <summary>
/// Specifies how long the lease will last, absent auto-renewal.
///
/// If auto-renewal is enabled (the default), then a shorter duration means more frequent auto-renewal requests,
/// while an infinite duration means no auto-renewal requests. Furthermore, if the lease-holding process were to
/// exit without explicitly releasing, then duration determines how long other processes would need to wait in
/// order to acquire the lease.
///
/// If auto-renewal is disabled, then duration determines how long the lease will be held.
///
/// Defaults to 30s.
/// </summary>
public AzureSynchronizationOptionsBuilder Duration(TimeSpan duration)
{
var durationTimeoutValue = new TimeoutValue(duration);
if (durationTimeoutValue.CompareTo(MinLeaseDuration) < 0
|| (!durationTimeoutValue.IsInfinite && durationTimeoutValue.CompareTo(MaxNonInfiniteLeaseDuration) > 0))
{
throw new ArgumentOutOfRangeException(nameof(duration), duration, $"Must be infinite or in [{MinLeaseDuration}, {MaxNonInfiniteLeaseDuration}]");
}
/// <summary>
/// Specifies how long the lease will last, absent auto-renewal.
///
/// If auto-renewal is enabled (the default), then a shorter duration means more frequent auto-renewal requests,
/// while an infinite duration means no auto-renewal requests. Furthermore, if the lease-holding process were to
/// exit without explicitly releasing, then duration determines how long other processes would need to wait in
/// order to acquire the lease.
///
/// If auto-renewal is disabled, then duration determines how long the lease will be held.
///
/// Defaults to 30s.
/// </summary>
public AzureSynchronizationOptionsBuilder Duration(TimeSpan duration)
{
var durationTimeoutValue = new TimeoutValue(duration);
if (durationTimeoutValue.CompareTo(MinLeaseDuration) < 0
|| (!durationTimeoutValue.IsInfinite && durationTimeoutValue.CompareTo(MaxNonInfiniteLeaseDuration) > 0))
{
throw new ArgumentOutOfRangeException(nameof(duration), duration, string.Format(Resources.IDS_MUST_BE_INFINITE_OR_IN, $"{MinLeaseDuration}, {MaxNonInfiniteLeaseDuration}"));
}

_duration = durationTimeoutValue;
return this;
}
_duration = durationTimeoutValue;
return this;
}

/// <summary>
/// Determines how frequently the lease will be renewed when held. More frequent renewal means more unnecessary requests
/// but also a lower chance of losing the lease due to the process hanging or otherwise failing to get its renewal request in
/// before the lease duration expires.
///
/// To disable auto-renewal, specify <see cref="Timeout.InfiniteTimeSpan"/>
///
/// Defaults to 1/3 of the specified lease duration (may be infinite).
/// </summary>
public AzureSynchronizationOptionsBuilder RenewalCadence(TimeSpan renewalCadence)
{
_renewalCadence = new TimeoutValue(renewalCadence);
return this;
}
/// <summary>
/// Determines how frequently the lease will be renewed when held. More frequent renewal means more unnecessary requests
/// but also a lower chance of losing the lease due to the process hanging or otherwise failing to get its renewal request in
/// before the lease duration expires.
///
/// To disable auto-renewal, specify <see cref="Timeout.InfiniteTimeSpan"/>
///
/// Defaults to 1/3 of the specified lease duration (may be infinite).
/// </summary>
public AzureSynchronizationOptionsBuilder RenewalCadence(TimeSpan renewalCadence)
{
_renewalCadence = new TimeoutValue(renewalCadence);
return this;
}

/// <summary>
/// Waiting to acquire a lease requires a busy wait that alternates acquire attempts and sleeps.
/// This determines how much time is spent sleeping between attempts. Lower values will raise the
/// volume of acquire requests under contention but will also raise the responsiveness (how long
/// it takes a waiter to notice that a contended the lease has become available).
///
/// Specifying a range of values allows the implementation to select an actual value in the range
/// at random for each sleep. This helps avoid the case where two clients become "synchronized"
/// in such a way that results in one client monopolizing the lease.
///
/// The default is [250ms, 1s]
/// </summary>
public AzureSynchronizationOptionsBuilder BusyWaitSleepTime(TimeSpan min, TimeSpan max)
{
var minTimeoutValue = new TimeoutValue(min);
var maxTimeoutValue = new TimeoutValue(max);
/// <summary>
/// Waiting to acquire a lease requires a busy wait that alternates acquire attempts and sleeps.
/// This determines how much time is spent sleeping between attempts. Lower values will raise the
/// volume of acquire requests under contention but will also raise the responsiveness (how long
/// it takes a waiter to notice that a contended the lease has become available).
///
/// Specifying a range of values allows the implementation to select an actual value in the range
/// at random for each sleep. This helps avoid the case where two clients become "synchronized"
/// in such a way that results in one client monopolizing the lease.
///
/// The default is [250ms, 1s]
/// </summary>
public AzureSynchronizationOptionsBuilder BusyWaitSleepTime(TimeSpan min, TimeSpan max)
{
var minTimeoutValue = new TimeoutValue(min);
var maxTimeoutValue = new TimeoutValue(max);

if (minTimeoutValue.IsInfinite)
{
throw new ArgumentOutOfRangeException(nameof(min), "may not be infinite");
}
if (minTimeoutValue.IsInfinite)
{
throw new ArgumentOutOfRangeException(nameof(min), ThreadingResources.IDS_CAN_NOT_BE_INFINITE);
}

if (maxTimeoutValue.IsInfinite || maxTimeoutValue.CompareTo(min) < 0)
{
throw new ArgumentOutOfRangeException(nameof(max), max, "must be non-infinite and greater than " + nameof(min));
}
if (maxTimeoutValue.IsInfinite || maxTimeoutValue.CompareTo(min) < 0)
{
throw new ArgumentOutOfRangeException(nameof(max), max, string.Format(ThreadingResources.IDS_MUST_BE_NON_INFINITE_AND_GREATER_THAN_MIN, nameof(min)));
}

_minBusyWaitSleepTime = minTimeoutValue;
_maxBusyWaitSleepTime = maxTimeoutValue;
return this;
}
_minBusyWaitSleepTime = minTimeoutValue;
_maxBusyWaitSleepTime = maxTimeoutValue;
return this;
}

internal static AzureSynchronizationOptions GetOptions(Action<AzureSynchronizationOptionsBuilder> optionsBuilder)
{
AzureSynchronizationOptionsBuilder options;
if (optionsBuilder != null)
{
options = new AzureSynchronizationOptionsBuilder();
optionsBuilder(options);
internal static AzureSynchronizationOptions GetOptions(Action<AzureSynchronizationOptionsBuilder> optionsBuilder)
{
AzureSynchronizationOptionsBuilder options;
if (optionsBuilder != null)
{
options = new AzureSynchronizationOptionsBuilder();
optionsBuilder(options);

if (options._renewalCadence is { } renewalCadence && !renewalCadence.IsInfinite)
{
var duration = options._duration ?? DefaultLeaseDuration;
if (renewalCadence.CompareTo(duration) >= 0)
{
throw new ArgumentOutOfRangeException(
nameof(renewalCadence),
renewalCadence.TimeSpan,
$"{nameof(renewalCadence)} must not be larger than {nameof(duration)} ({duration}). To disable auto-renewal, specify {nameof(Timeout)}.{nameof(Timeout.InfiniteTimeSpan)}"
);
}
}
}
else
{
options = null;
}
if (options._renewalCadence is { } renewalCadence && !renewalCadence.IsInfinite)
{
var duration = options._duration ?? DefaultLeaseDuration;
if (renewalCadence.CompareTo(duration) >= 0)
{
var message = string.Format(Resources.IDS_MUST_BE_GREATTER_THAN, nameof(renewalCadence), $"{nameof(duration)} ({duration})", $"{nameof(Timeout)}.{nameof(Timeout.InfiniteTimeSpan)}");
throw new ArgumentOutOfRangeException(nameof(renewalCadence), renewalCadence.TimeSpan, message);
}
}
}
else
{
options = null;
}

var durationToUse = options?._duration ?? DefaultLeaseDuration;
return new AzureSynchronizationOptions(
durationToUse,
options?._renewalCadence ?? (durationToUse.IsInfinite ? Timeout.InfiniteTimeSpan : TimeSpan.FromMilliseconds(durationToUse.InMilliseconds / 3.0)),
options?._minBusyWaitSleepTime ?? TimeSpan.FromMilliseconds(250),
options?._maxBusyWaitSleepTime ?? TimeSpan.FromSeconds(1)
);
}
var durationToUse = options?._duration ?? DefaultLeaseDuration;
return new AzureSynchronizationOptions(
durationToUse,
options?._renewalCadence ?? (durationToUse.IsInfinite ? Timeout.InfiniteTimeSpan : TimeSpan.FromMilliseconds(durationToUse.InMilliseconds / 3.0)),
options?._minBusyWaitSleepTime ?? TimeSpan.FromMilliseconds(250),
options?._maxBusyWaitSleepTime ?? TimeSpan.FromSeconds(1)
);
}
}
4 changes: 4 additions & 0 deletions Source/Euonia.Threading.Azure/Euonia.Threading.Azure.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@
<ProjectReference Include="..\Euonia.Threading\Euonia.Threading.csproj" />
</ItemGroup>

<ItemGroup>
<Using Include="Nerosoft.Euonia.Threading.Properties.Resources" Alias="ThreadingResources"/>
</ItemGroup>

<ItemGroup>
<Compile Update="Properties\Resources.Designer.cs">
<DesignTime>True</DesignTime>
Expand Down
Loading

0 comments on commit d88358c

Please sign in to comment.