Osy#betaRun it on Osyrin: osyrin.com

Reference / Workflow

Graph — every state and every transition of a workflow

<Wf>.Graph // WorkflowGraph { WorkflowStateInfo[] States; WorkflowTransitionInfo[] Transitions; }

The whole shape of a workflow — every state (with its label, and whether it starts or ends a run) and every transition the declaration makes possible — as an ordinary value. Built by the compiler from the declaration, so it costs nothing to read anywhere; it is what you draw a picture of a process from.

preview1 example compiled by CIworkflowqueries

Summary#

<Wf>.Graph is the answer to "what does this process look like?" — the question Transitions — where this item may go next does not answer, because it is asked of ONE run and says only where that run may go next.

var g = OrderFlow.Graph;
g.States        // every state, in declaration order
g.Transitions   // every declared transition, each joining two real states

It is not a server read. The graph is the declaration, the same for every run, so the compiler builds it — from the very graph osy model, the workflow diagram and the workflow lints use — and a page reads it like a constant.

Where a run is is its own tracked field (order.Status, see Tracks and Initial (the field a workflow drives)), live like any field; where it has been is <Wf>.For(item).TimeInStates (Flow metrics — how long an item took, and how much was waiting). Those three are everything a live picture of a run needs.

Signature#

<Wf>.Graph                       // WorkflowGraph
  .States                        // WorkflowStateInfo[]  — Id, Name, Label, IsInitial, IsTerminal, Outcome
  .Transitions                   // WorkflowTransitionInfo[] — Id, From, To, Trigger, Kind, Guard
WorkflowStateInfo
Ida key — the state's name, unique in its workflow
Nameas declared (Placed) — what goto and the tracked enum spell
Labelfor a person: the tracked enum member's [Label], or its name
IsInitial / IsTerminalwhere a run starts; where it ends
OutcomeSuccess, Cancel or Error for a terminal; empty otherwise
WorkflowTransitionInfo
Ida key unique in the graph
From / Tothe two states' Ids
Triggerwhat fires it: an event (Ship), complete when, enter, a clock (Expire), an SLA breach
Kindevent, completion, timeout, cancel or sla
Guarda when (…) arm's condition as written; null when unconditional

Description#

What counts as a transition#

Every way the declaration can move a run: each state's on X { goto Y; } (every arm of it), complete when (…) goto Y, a goto in a state's enter hook, and an SLA breach body. A route declared on the workflow (on Cancel { goto Cancelled; }) applies in every state that is not terminal, so it appears once per state it leaves — each edge joins two real states. Its Kind (cancel) is how a picture leaves that fan out when it wants to:

var moves = OrderFlow.Graph.Transitions.Where(t => t.Kind != "cancel");

Reading it#

using Osysharp.Workflow;

enum ParcelStatus { Placed, [Label("Out for delivery")] Shipped, Delivered, Cancelled }

entity Parcel {
  [Required, MaxLength(40)] string Ref;
  ParcelStatus Status;
  security { allow read, create, update when IsAuthenticated || IsAnonymous; }
}

workflow Shipping {
  Tracks    = Parcel.Status;
  Autostart = true;
  Initial   = Placed;

  event Ship();
  event Deliver();
  event Cancel();

  state Placed {
    subscribe Ship();
    on Ship { goto Shipped; }
  }

  state Shipped {
    subscribe Deliver();
    on Deliver { goto Delivered; }
  }

  on Cancel { goto Cancelled; }

  terminal success Delivered { }
  terminal cancel Cancelled { }
}

[Route("/process")] [AllowAnonymous]
component Process() {
  render {
    Stack(gap: 2) {
      foreach (var s in Shipping.Graph.States) {
        Text(s.Label + " — " + Shipping.Graph.Transitions.Count(t => t.To == s.Id) + " way(s) in");
      }
    }
  }
}

Drawing it#

The The flow kit — a node-and-edge canvas whose nodes are your own Osy# canvas draws a workflow from this directly — nodes: OrderFlow.Graph.States, edges: OrderFlow.Graph.Transitions, sourceField: e => e.From, targetField: e => e.To — lays it out itself, and marks a run's current state and path with highlighted and visited. See A live picture of a workflow run there.

See also#

Related

Transitions — where this item may go next

One row per move this instance can make right now, with each arm's guard evaluated against it. A board offers only the…

Tracks and Initial (the field a workflow drives)

Names the enum field a workflow owns and the state a run starts in. No application code may write that field, and when…

Flow metrics — how long an item took, and how much was waiting

Wall-clock lead time for a run, split into the part somebody was working it and the part it sat waiting — plus where…

The flow kit — a node-and-edge canvas whose nodes are your own Osy#

A modelling canvas — pan, zoom, drag nodes, draw edges between ports, select and delete, by mouse and by keyboard —…

Workflows (the run that outlives the request)

A `workflow` is a run that survives the process it started in — it parks, waits days for a person or a timer, and…