66 lines
2.3 KiB
C#
66 lines
2.3 KiB
C#
using System.Globalization;
|
|
using System.Text.Json.Nodes;
|
|
using w4c_workflows.Models.Nodes;
|
|
|
|
namespace w4c_workflows.Services.Nodes.Executors;
|
|
|
|
/// <summary>
|
|
/// Wait node. Pauses for the configured duration (per item, since it runs in
|
|
/// each-item mode) and then passes the item through unchanged. The delay is
|
|
/// capped to protect the in-process run loop from a runaway configuration.
|
|
/// </summary>
|
|
public sealed class WaitNodeExecutor : INodeExecutor
|
|
{
|
|
/// <summary>Upper bound on a single wait, so one node cannot stall the run loop indefinitely.</summary>
|
|
public static readonly TimeSpan MaxDelay = TimeSpan.FromMinutes(5);
|
|
|
|
public string Type => "core.wait";
|
|
|
|
public async Task<NodeExecutionOutcome> RunAsync(NodeExecutionContext context, CancellationToken ct)
|
|
{
|
|
var delay = ResolveDelay(context);
|
|
if (delay > TimeSpan.Zero)
|
|
await Task.Delay(delay, ct);
|
|
|
|
return NodeExecutionOutcome.Single(context.Input(0).ToList());
|
|
}
|
|
|
|
private static TimeSpan ResolveDelay(NodeExecutionContext context)
|
|
{
|
|
var amount = ReadDouble(context, "amount", 1);
|
|
if (amount <= 0)
|
|
return TimeSpan.Zero;
|
|
|
|
var unit = context.Parameters["unit"] is JsonValue value && value.TryGetValue<string>(out var text)
|
|
? text
|
|
: "seconds";
|
|
|
|
var delay = unit switch
|
|
{
|
|
"milliseconds" => TimeSpan.FromMilliseconds(amount),
|
|
"minutes" => TimeSpan.FromMinutes(amount),
|
|
_ => TimeSpan.FromSeconds(amount),
|
|
};
|
|
|
|
return delay > MaxDelay ? MaxDelay : delay;
|
|
}
|
|
|
|
private static double ReadDouble(NodeExecutionContext context, string name, double defaultValue)
|
|
{
|
|
if (context.Parameters[name] is not JsonValue value)
|
|
return defaultValue;
|
|
|
|
if (value.TryGetValue<double>(out var doubleValue))
|
|
return doubleValue;
|
|
if (value.TryGetValue<decimal>(out var decimalValue))
|
|
return (double)decimalValue;
|
|
if (value.TryGetValue<long>(out var longValue))
|
|
return longValue;
|
|
if (value.TryGetValue<string>(out var text)
|
|
&& double.TryParse(text, NumberStyles.Float, CultureInfo.InvariantCulture, out var parsed))
|
|
return parsed;
|
|
|
|
return defaultValue;
|
|
}
|
|
}
|