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