Skip to content

Commit

Permalink
feat(sdk-dotnet): add mutation expression in the workflow thread (#1283)
Browse files Browse the repository at this point in the history
  • Loading branch information
KarlaCarvajal authored Feb 13, 2025
1 parent 5a8852a commit e4daa3d
Show file tree
Hide file tree
Showing 6 changed files with 265 additions and 1 deletion.
14 changes: 14 additions & 0 deletions sdk-dotnet/Examples/MutationExample/MutationExample.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\LittleHorse.Sdk\LittleHorse.Sdk.csproj" />
</ItemGroup>

</Project>
22 changes: 22 additions & 0 deletions sdk-dotnet/Examples/MutationExample/MyWorker.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using LittleHorse.Sdk.Worker;

namespace MutationExample;

public class MyWorker
{
[LHTaskMethod("spider-bite")]
public string SpiderBite(string name)
{
Console.WriteLine("Executing spider-bite");
var names = new List<string> { "Miles", "Peter" };

if (names.Contains(name))
{
Console.WriteLine($"{name} got bitten");

return "Spider-man";
}

return $"The spider bite has no effect on {name}";
}
}
71 changes: 71 additions & 0 deletions sdk-dotnet/Examples/MutationExample/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
using LittleHorse.Sdk;
using LittleHorse.Sdk.Common.Proto;
using LittleHorse.Sdk.Worker;
using LittleHorse.Sdk.Workflow.Spec;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using MutationExample;

public abstract class Program
{
const string TaskDefName = "spider-bite";
private static ServiceProvider? _serviceProvider;
private static void SetupApplication()
{
_serviceProvider = new ServiceCollection()
.AddLogging(config =>
{
config.AddConsole();
config.SetMinimumLevel(LogLevel.Debug);
})
.BuildServiceProvider();
}

private static LHConfig GetLHConfig(string[] args, ILoggerFactory loggerFactory)
{
var config = new LHConfig(loggerFactory);

string filePath = Path.Combine(Directory.GetCurrentDirectory(), ".config/littlehorse.config");
if (File.Exists(filePath))
config = new LHConfig(filePath, loggerFactory);

return config;
}

private static Workflow GetWorkflow()
{
void MyEntryPoint(WorkflowThread wf)
{
var theName = wf.DeclareStr("name");
// We pass the name of the person and receive if it is spider-man or not
NodeOutput output = wf.Execute(TaskDefName, theName);

// We save the output in the variable
wf.Mutate(theName, VariableMutationType.Assign, output);
}

return new Workflow("example-mutation", MyEntryPoint);
}

static void Main(string[] args)
{
SetupApplication();
if (_serviceProvider != null)
{
var loggerFactory = _serviceProvider.GetRequiredService<ILoggerFactory>();
var config = GetLHConfig(args, loggerFactory);

var executable = new MyWorker();
var worker = new LHTaskWorker<MyWorker>(executable, TaskDefName, config);

worker.RegisterTaskDef();

var workflow = GetWorkflow();
workflow.RegisterWfSpec(config.GetGrpcClientInstance());

Thread.Sleep(300);

worker.Start();
}
}
}
33 changes: 33 additions & 0 deletions sdk-dotnet/Examples/MutationExample/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
## Running MutationExample

In this example you will see how to mutate variables.

Let's run the example in `MutationExample`

```
dotnet build
dotnet run
```

In another terminal, use `lhctl` to run the workflow:

```
# Execute with Peter or Miles
lhctl run example-mutation name Peter
# Execute with other names
lhctl run example-mutation name Pepito
```

In addition, you can check the result with:

```
# This call shows the result
lhctl get wfRun <wf_run_id>
# This will show you all nodes in the run
lhctl list nodeRun <wf_run_id>
# This shows the task run information
lhctl get taskRun <wf_run_id> <task_run_global_id>
```
119 changes: 118 additions & 1 deletion sdk-dotnet/LittleHorse.Sdk/Workflow/Spec/WfRunVariable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -146,16 +146,133 @@ public void Assign(object rhs)
_parent.Mutate(this, VariableMutationType.Assign, rhs);
}

/// <summary>
/// Returns an expression whose value is the `other` added to this expression.
/// </summary>
/// <param name="other">
/// It is the value to be added to this expression.
/// </param>
/// <returns> An expression whose value is the `other` added to this expression.
/// </returns>
public LHExpression Add(object other)
{
return new LHExpression(this, VariableMutationType.Add, other);
}

/// <summary>
/// Returns an expression whose value is the `other` subtracted from this expression.
/// </summary>
/// <param name="other">
/// It is the value to be subtracted from this expression.
/// </param>
/// <returns> An expression whose value is the `other` subtracted from this expression. <paramref name="LHExpression" />
/// <returns> An expression whose value is the `other` subtracted from this expression.
/// </returns>
public LHExpression Subtract(object other)
{
return new LHExpression(this, VariableMutationType.Subtract, other);
}

/// <summary>
/// Returns an expression whose value is the `other` multiplied by this expression.
/// </summary>
/// <param name="other">
/// It is the value to be multiplied by this expression.
/// </param>
/// <returns> An expression whose value is the `other` multiplied by this expression.
/// </returns>
public LHExpression Multiply(object other)
{
return new LHExpression(this, VariableMutationType.Multiply, other);
}

/// <summary>
/// Returns an expression whose value is the `other` divided by the `other`.
/// </summary>
/// <param name="other">
/// It is the value to divide this expression by.
/// </param>
/// <returns> An expression whose value is this expression divided by the `other`.
/// </returns>
public LHExpression Divide(object other)
{
return new LHExpression(this, VariableMutationType.Divide, other);
}

/// <summary>
/// Returns an expression whose value is this expression extended by the `other`.
/// </summary>
/// <param name="other">
/// It is the value to extend this expression by.
/// </param>
/// <returns> An expression whose value is this expression extended by the `other`. </returns>
public LHExpression Extend(object other)
{
return new LHExpression(this, VariableMutationType.Extend, other);
}

/// <summary>
/// Returns an expression whose value is this expression with all occurrences of
/// `other` removed.
/// </summary>
/// <param name="other">
/// It is the value to remove from this expression.
/// </param>
/// <returns> An expression whose value is this expression with all occurrences of
/// `other` removed.
/// </returns>
public LHExpression RemoveIfPresent(object other)
{
return new LHExpression(this, VariableMutationType.RemoveIfPresent, other);
}

/// <summary>
/// Returns an expression whose value is this expression with the index specified
/// by `index` removed.
///
/// Valid only for JSON_ARR expressions.
/// </summary>
/// <param name="index">
/// It is the index at which to insert the other `index`.
/// </param>
/// <returns> An expression whose value is this expression with the `other` inserted
/// at the specified `index`.
/// </returns>
public LHExpression RemoveIndex(int index)
{
return new LHExpression(this, VariableMutationType.RemoveIndex, index);
}

/// <summary>
/// Returns an expression whose value is this expression with the index specified
/// by `index` removed.
///
/// Valid only for JSON_ARR expressions.
/// </summary>
/// <param name="index">
/// It is the index at which to remove the value.
/// </param>
/// <returns> An expression whose value is this expression with the value at the
/// specified `index` removed.
/// </returns>
public LHExpression RemoveIndex(LHExpression index)
{
return new LHExpression(this, VariableMutationType.RemoveIndex, index);
}

/// <summary>
/// Returns an expression whose value is this expression with the key specified
/// by `key` removed.
///
/// Valid only for JSON_OBJ expressions.
/// </summary>
/// <param name="key">
/// It is the key to remove from this expression.
/// </param>
/// <returns> An expression whose value is this expression with the key specified
/// by `key` removed.
/// </returns>
public LHExpression RemoveKey(object key)
{
return new LHExpression(this, VariableMutationType.RemoveKey, key);
}
}
7 changes: 7 additions & 0 deletions sdk-dotnet/Littlehorse.sln
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConditionalsExample", "Exam
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConditionalsWhileExample", "Examples\ConditionalsWhileExample\ConditionalsWhileExample.csproj", "{40D76EE3-8B4F-4EAA-A3F0-AAA0DE9D8113}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MutationExample", "Examples\MutationExample\MutationExample.csproj", "{DEA03A93-461C-48BC-A218-9C75313DC210}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -62,6 +64,10 @@ Global
{40D76EE3-8B4F-4EAA-A3F0-AAA0DE9D8113}.Debug|Any CPU.Build.0 = Debug|Any CPU
{40D76EE3-8B4F-4EAA-A3F0-AAA0DE9D8113}.Release|Any CPU.ActiveCfg = Release|Any CPU
{40D76EE3-8B4F-4EAA-A3F0-AAA0DE9D8113}.Release|Any CPU.Build.0 = Release|Any CPU
{DEA03A93-461C-48BC-A218-9C75313DC210}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DEA03A93-461C-48BC-A218-9C75313DC210}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DEA03A93-461C-48BC-A218-9C75313DC210}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DEA03A93-461C-48BC-A218-9C75313DC210}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{88CB23B3-1174-45F5-9F72-46AB57BAB661} = {EEC3BB78-BFA5-4525-A965-4EAA3455BBAE}
Expand All @@ -70,5 +76,6 @@ Global
{93DB9DF9-A48B-436F-8892-AE4CAD42323E} = {EEC3BB78-BFA5-4525-A965-4EAA3455BBAE}
{D37393B1-3D05-4A76-BEC3-D801EB576130} = {EEC3BB78-BFA5-4525-A965-4EAA3455BBAE}
{40D76EE3-8B4F-4EAA-A3F0-AAA0DE9D8113} = {EEC3BB78-BFA5-4525-A965-4EAA3455BBAE}
{DEA03A93-461C-48BC-A218-9C75313DC210} = {EEC3BB78-BFA5-4525-A965-4EAA3455BBAE}
EndGlobalSection
EndGlobal

0 comments on commit e4daa3d

Please sign in to comment.