using System.Globalization; using System.Text.Json; using System.Text.Json.Serialization; using w4c_workflows.Models; namespace w4c_workflows.Services.Execution; /// /// Serializes a task.run job from the compiled /// into the flat Redis Stream fields the worker understands (see /// ). This is the control-plane side of /// the wire contract; the worker side deserializes the same field names. /// public static class TaskRunMessage { private static readonly JsonSerializerOptions Json = new(JsonSerializerDefaults.Web) { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, }; /// /// Builds the stream fields for executing as part of /// . is the directory /// containing the task's code files; the entry file is taken from the task's /// EntryJson and stays relative to it. /// public static IReadOnlyDictionary ToFields( WorkflowRun run, WorkflowTask task, string? input, string? workingDir, int attempt) { var entry = ParseEntry(task.EntryJson); var fields = new Dictionary { ["type"] = TaskInvocation.TypeValue, ["run_id"] = run.Id.ToString(), ["task_id"] = task.Id.ToString(), ["task_key"] = task.Key, ["language"] = task.Language, ["entry_file"] = entry.File ?? string.Empty, ["tenant_id"] = run.TenantId, ["attempt"] = attempt.ToString(CultureInfo.InvariantCulture), }; if (!string.IsNullOrWhiteSpace(entry.Function)) fields["entry_function"] = entry.Function; var env = DeserializeEnv(task.EnvJson); if (env.Count > 0) fields["env"] = JsonSerializer.Serialize(env, Json); if (input != null) fields["input"] = input; if (!string.IsNullOrWhiteSpace(workingDir)) fields["working_dir"] = workingDir; if (!string.IsNullOrWhiteSpace(task.Server)) fields["server"] = task.Server!; return fields; } private static EntryDefinition ParseEntry(string? entryJson) { if (!string.IsNullOrWhiteSpace(entryJson)) { var entry = JsonSerializer.Deserialize(entryJson, Json); if (entry != null) return entry; } return new EntryDefinition { File = string.Empty }; } private static IReadOnlyDictionary DeserializeEnv(string? envJson) { if (string.IsNullOrWhiteSpace(envJson)) return new Dictionary(); return JsonSerializer.Deserialize>(envJson, Json) ?? new Dictionary(); } }