EffectJunction

A Junction that records a JunctionMetadata for each run and lets junction effects (the junction logger, junction progress, or your own IJunctionEffectProvider) run before and after it. You write it exactly as you would a Junction.

It works only inside a ServiceTrain. Chained into a plain Train, it throws TrainException.

Signature

namespace Trax.Effect.Services.EffectJunction;
 
public abstract class EffectJunction<TIn, TOut> : Junction<TIn, TOut>
{
    protected EffectJunction();
 
    public JunctionMetadata? Metadata { get; }
 
    public abstract override Task<TOut> Run(TIn input);
}

It also overrides RailwayJunction, and adds a RailwayJunction overload that takes a ServiceTrain. The train calls them; you do not.

Members

MemberDescription
Run(TIn input)Your implementation, as on Junction.
MetadataThe in-memory record of the current or most recent run of this junction: name, input and output types, start and end time, railway state, whether Run was called (HasRan), and OutputJson when the junction logger serializes output. null until the junction first runs, replaced at the start of each run. It is not written to the database itself; the junction effects read it, and the junction logger logs it.
CancellationTokenInherited from Junction.

What happens around Run

  1. A fresh Metadata is created, named after the junction class, with the train's metadata as its parent.
  2. Each enabled junction effect's BeforeJunctionExecution runs, in registration order.
  3. The start time is stamped, and the junction runs on the railway as a Junction does. A failed predecessor skips Run and leaves HasRan false.
  4. The end time and railway state are stamped.
  5. Each junction effect's AfterJunctionExecution runs, whether the junction succeeded, failed or was skipped.

An exception from a junction effect is not caught: it stops the remaining effects and fails the train.

Example

using Trax.Effect.Services.EffectJunction;
 
public class PersistOrder(IOrderStore store) : EffectJunction<PaymentReceipt, OrderResult>
{
    public override async Task<OrderResult> Run(PaymentReceipt receipt)
    {
        var order = await store.Save(receipt, CancellationToken);
        return new OrderResult(order.Id);
    }
}

When to use it

UseWhen
EffectJunctionThe junction is in a ServiceTrain and should appear in junction logs, junction progress, or your own junction effect
JunctionThe junction is used by a plain Train, or you do not want it observed

See EffectJunction vs Junction for the concepts.

Package

dotnet add package Trax.Effect