-
Notifications
You must be signed in to change notification settings - Fork 1
Using Subflows to organize tasks
Using subflows is a way to organize complicated build processes by splitting it into smaller parts. Subflow is a class inherited from Rosalia.Core.Api.Subflow
, it has RegisterTasks
and all the rest registration methods just like Workflow
.
There are three major reasons why Subflows may be useful:
Here we can see N + M tasks that logically belong to two groups:
using Rosalia.Core.Api;
public class DefaultWorkflow : Workflow
{
protected override void RegisterTasks()
{
var fooTask1 = Task(/*...*/);
var fooTask2 = Task(/*...*/);
/* ... */
var fooTaskN = Task(/*...*/);
var barTask1 = Task(/*...*/);
var barTask2 = Task(/*...*/);
/* ... */
var barTaskM = Task(/*...*/);
}
}
We can introduce two sublfows to simplify the process:
using Rosalia.Core.Api;
public class Foo: Subflow
{
protected override void RegisterTasks()
{
var fooTask1 = Task(/*...*/);
var fooTask2 = Task(/*...*/);
/* ... */
var fooTaskN = Task(/*...*/);
}
}
public class Bar: Subflow
{
protected override void RegisterTasks()
{
var barTask1 = Task(/*...*/);
var barTask2 = Task(/*...*/);
/* ... */
var barTaskM = Task(/*...*/);
}
}
public class DefaultWorkflow : Workflow
{
protected override void RegisterTasks()
{
var foo = Task("foo", new Foo());
var bar = Task("bar", new Bar());
}
}
Assume we have a workflow like this:
using Rosalia.Core.Api;
public class DefaultWorkflow : Workflow
{
protected override void RegisterTasks()
{
var parent1 = Task(/*...*/);
var parent2 = Task(/*...*/);
var bazTask1 = Task(
"bazTask1",
from parent1Value in parent1
from parent2Value in parent2
select new BazTask(parent1Value, parent2Value).AsTask());
var bazTask2 = Task(
"bazTask2",
from parent1Value in parent1
from parent2Value in parent2
select new BazTask(parent1Value, parent2Value).AsTask());
/* ... */
var bazTaskK = Task(
"bazTaskK",
from parent1Value in parent1
from parent2Value in parent2
select new BazTask(parent1Value, parent2Value).AsTask());
}
}
Here we have K tasks and all of them depends on parent1
and parent2
tasks. It is kind of annoying to write LINQ code for every of these tasks, so we can extract all baz tasks to a separate Subflow:
using Rosalia.Core.Api;
public class Baz : Subflow
{
private Something _parent1Value;
private Something _parent2Value;
public Baz(Something parent1Value, Something parent2Value)
{
_parent1Value = parent1Value;
_parent2Value = parent2Value;
}
protected override void RegisterTasks()
{
var bazTask1 = Task(
"bazTask1"
new BazTask(_parent1Value, _parent2Value);
var bazTask2 = Task(
"bazTask2"
new BazTask(_parent1Value, _parent2Value);
/* ... */
var bazTaskK = Task(
"bazTaskK"
new BazTask(_parent1Value, _parent2Value);
}
}
public class DefaultWorkflow : Workflow
{
protected override void RegisterTasks()
{
var parent1 = Task(/*...*/);
var parent2 = Task(/*...*/);
var bazTasks = Task(
"baz",
from parent1Value in parent1
from parent2Value in parent2
select new Baz(parent1Value, parent2Value).AsSubflow());
}
}
Baz
subflow from the previous example can be added to the main workflow multiple times with different arguments:
public class DefaultWorkflow : Workflow
{
protected override void RegisterTasks()
{
var parent1 = Task(/*...*/);
var parent2 = Task(/*...*/);
var parent3 = Task(/*...*/);
var parent4 = Task(/*...*/);
var bazTasks1 = Task(
"baz",
from parent1Value in parent1
from parent2Value in parent2
select new Baz(parent1Value, parent2Value).AsSubflow());
var bazTasks2 = Task(
"baz",
from parent3Value in parent3
from parent4Value in parent4
select new Baz(parent3Value, parent4Value).AsSubflow());
}
}
In this way we reused tasks from Baz
subflow providing different input parameters.
If your subflow depends on previous tasks and you have to use LINQ comprehensions syntax, it is necessary to use AsSubflow()
extension to tell compiler that your object is a subflow and not ITaskResult<Subflow>
:
Task(
"Generate installation packages",
from data in initTask
from version in formatVersionTask
// make sure AsSubflow() is called
select new CreateInstallationPackages(data, version).AsSubflow(),
Default(),
DependsOn(buildSolution));
Writing Tasks
- Creating a Workflow
- Defining Tasks
- Share State accross Tasks
- Mastering Dependencies
- Using result transformers
- Using Subflows to organize tasks
- Tasks Preconditions
- Recovering failure results
- Declaring dynamic tasks
- Creating Custom Tasks
Running Tasks
API
Tasklib