Move work around a chain into junctions
A train's chain is declared in Junctions() and nowhere else (see why), so work that would otherwise sit above or around the chain goes into the chain. This page says where each kind of work goes.
Find the place for the work
| What you need | Where it goes |
|---|---|
| Logic before or after the chain | A junction at the head or the tail of it |
| Extra objects in Memory | A junction whose return value is that object, or AddServices<IService>(value) or Extract<TIn, TOut>(value) in the chain |
| Returning a failure | A junction that throws; the chain turns it into Left |
| Async setup | A junction, which is async already |
| Merging a nested train's result | A junction that calls ITrainBus and returns the merged value |
| Reading the input to decide what runs | A junction that takes the input, or a Switch on a decision about it; Junctions() cannot read TrainInput |
Run a nested train from a junction
- Write a junction that takes
ITrainBusthrough its constructor and callsRunAsyncwith the child's input, passing itsCancellationToken. - Return the merged result from the junction.
- Chain the junction where the child's result is needed.
using Trax.Core.Functional;
using Trax.Core.Junction;
using Trax.Effect.Services.ServiceTrain;
using Trax.Mediator.Services.TrainBus;
public class ParentTrain : ServiceTrain<ParentInput, ParentResult>, IParentTrain
{
protected override Task<Either<Exception, ParentResult>> Junctions() =>
Chain<RunChildTrain>().Chain<ValidateParentResult>().Resolve();
}
public class RunChildTrain(ITrainBus trainBus) : Junction<ParentInput, ParentResult>
{
public override async Task<ParentResult> Run(ParentInput input)
{
var child = await trainBus.RunAsync<ChildResult>(
new ChildRequest(input.ChildData),
CancellationToken
);
return new ParentResult(input.ParentData, child);
}
}The child runs as a train of its own and is not linked to the parent run. RunAsync takes an optional Metadata, but that is a pre-created Pending row for the child to run as, the way the scheduler uses it, not a parent: passing the running parent's metadata is refused with a TrainException.
Related
- Junctions, what the startup check refuses in a declaration
- AddServices and Extract
- TrainBus
- Removal of RunInternal and Activate
SDK Reference
Junctions | Chain | AddServices | ITrainBus