w4c-workflows-api/Services/Nodes/Executors/WaitNodeExecutor.cs
2026-09-12 01:02:46 +03:00

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;
}
}