Skip to main content

Your First WfSpec


In LittleHorse, a Workflow Specification (WfSpec) defines the sequence of steps that should be executed when you execute a WfSpec. In this guide, we'll create our first WfSpec that uses the TaskDef we created in the previous lesson.

warning

This tutorial assumes you have completed the Your First Task Worker guide and you do not have a Task Worker running.

What is a WfSpec?

A WfSpec is a blueprint that tells LittleHorse exactly how and when your series of tasks and operations should occur as an organized sequence. It defines the following included but not limited to:

  • What input variables are needed
  • Which nodes should be executed
  • In what order those nodes should run
  • What should happen if something goes wrong
info

Think of a WfSpec as a recipe: it lists all the ingredients (variables) and steps (tasks) needed to create the final product (workflow execution).

Creating a WfSpec

In this section, we'll create a simple workflow that uses our greeting Task Worker from the previous lesson.

src/main/java/io/littlehorse/quickstart/QuickstartWorkflow.java
package io.littlehorse.quickstart;

import io.littlehorse.sdk.wfsdk.WfRunVariable;
import io.littlehorse.sdk.wfsdk.Workflow;
import io.littlehorse.sdk.wfsdk.WorkflowThread;

public class QuickstartWorkflow {

public static final String WF_NAME = "quickstart";
public static final String GREET_TASK_NAME = "greet";

/*
* This method defines the logic of our workflow
*/
public void quickstartWf(WorkflowThread wf) {
// Create an input variable, make it searchable
WfRunVariable name = wf.declareStr("input-name").searchable();

// Execute a task and pass in the variable.
wf.execute(GREET_TASK_NAME, name);
}

/*
* This method returns a LittleHorse `Workflow` wrapper object that can be
* used to register the WfSpec to the LittleHorse Server.
*/
public Workflow getWorkflow() {
return Workflow.newWorkflow(WF_NAME, this::quickstartWf);
}
}

Let's break down what this code does:

  1. We create a new WfSpec named quickstart
  2. We define an input variable called name of type String
  3. We execute our greet TaskDef (from the previous lesson) with the name variable

Registering the WfSpec

Before we can start running workflows, we need to register a WfSpec with the LittleHorse Server. The LittleHorse SDK ships with a useful WfSpecClient object that makes it easy to do that. The following executable Main file acccomplishes that:

src/main/java/io/littlehorse/quickstart/Main.java
package io.littlehorse.quickstart;

import io.littlehorse.sdk.common.config.LHConfig;
import io.littlehorse.sdk.wfsdk.WfSpecClient;

public class Main {
public static void main(String[] args) {
// Create configuration from environment variables, which tells the SDK where to talk to LittleHorse.
LHConfig config = new LHConfig();

// Register the WfSpec
QuickstartWorkflow quickstart = new QuickstartWorkflow();
quickstart.getWorkflow().registerWfSpec(config.getBlockingStub());
}
}

Run this code using:

./gradlew run

If you navigate to your LittleHorse dashboard, you should now see the quickstart WfSpec.

A WfSpec in LH Dashboard

Executing the WfSpec

Now that we have registered the WfSpec and TaskDef, we need to tell LittleHorse to execute the WfSpec. Let's execute the WfSpec using the lhctl run command:

lhctl run quickstart name Obi-Wan

If you navigate to your LittleHorse dashboard, you should now see a WfRun in the PENDING state because we haven't started our task worker yet.

A Pending WfRun in LH Dashboard

In the next lesson, we'll learn all the different ways to execute WfSpecs.

Wrapping Up

Congratulations! You've created, registered, and executed your first WfSpec. In the next lesson, we'll explore different ways to run this WfSpec in a more production-like setting.

In the meantime, if you haven't done so already: