Skip to main content

Tips, Pointers, and FAQ

We do our best to make our documentation easy to navigate; however, LittleHorse has a lot of features and it may not always be easy to find what you are looking for.

Think of this page as an "index" that will help you find what you need to make your project a success.

Workflow Basics

Read here for how to get started.

What is a WfSpec and WfRun?

The core concept of LittleHorse is a Workflow, which defines a series of tasks to execute and events to wait for. A WfSpec defines a workflow specification. A WfRun is a running instance of that WfSpec. workflow specification is the configuration, or metadata object, that tells the engine what Tasks to run, what order to run the tasks, how to handle exceptions or failures, what variables are to be passed from task to task, and what inputs and outputs are required to run the workflow.

In LittleHorse the Workflow Spec is submitted to and held by the LittleHorse server. It is a written in Code, using the LittleHorse SDK.
In the background LittleHorse server takes the submitted spec from the SDK, and compiles a protobuf object that is submitted to the LittleHorse server.

Example:

public class QuickstartWorkflow {

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

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

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

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

How do I create a WfSpec?

Check out our WfSpec development docs! In short, you can use our Java, Python, or Go SDK's to define the WfSpec logic and then register them to the LH Server.

Tasks

Tasks are the unit of work for a work flow engine.
It's best to think in examples:

  • Change lower case letters to upper case letters.
  • Call an API with an input variable and pass along the output.
  • Wait for user input or an event to happen.

What is a Task Worker?

A Task Worker is a program that opens a connection to a LittleHorse Cluster and listens to a task queue for a specific TaskDef. When a WfRun arrives at a point where it needs to execute that specific type of TaskRun, then the scheduled Task will be dispatched to the Task Worker. The Task Worker executes it and reports the result to the LH Server.

A task worker can be a bare metal machine, Virtual Machine, cloud instance, Kubernetes pod, or anywhere that can execute Java/Python/Golang or C# code.

How do I write a Task Worker?

Check out our Task Worker Development Docs!

How do I run a Workflow?

You can run a workflow in two ways:

  • On the command line by using lhctl. This method is best suited for testing, development, or debugging.
  • Programmatically by using one of our SDK's. Under the covers, the SDKs call the GRPC endpoint on the LittleHorse server. Programmatic execution is ideal for incorporating into your dashboards, and operational tools.

Variables and Control Flow

How do I pass information from one task to another?

Variables are how you pass info from one task to another. Take the output of one task and ASSIGN it to a variable, then pass that variable into the next task. Check out our mutating variables documentation.

How do I define variables in a Workflow?

Check out the Variables Section of our WfSpec docs.

Can I search for workflows by their variables?

Yes, you can. To do that, mark the variable as searchable() and then use `rpc SearchVariable to search for it.

How do I do if/else in a Workflow?

Check out the Conditionals Section of our WfSpec docs.

Can a workflow have loops?

Yes, check out the loops section.

External Events

What is an ExternalEvent?

External Events in LittleHorse represent events that occur outside of the context of a single WfRun. For example, you might use an ExternalEvent to notify a WfRun when someone signs a DocuSign document, or when a text message is replied to.

An ExternalEvent is an instance of an ExternalEventDef.

How do I make a WfRun wait for an event?

Check out the External Events section of our WfSpec docs. What you want is an ExternalEventNode, which blocks until an ExternalEvent arrives.

How do I interrupt a WfRun?

Check out the Interrupts section of our WfSpec docs. What you want to do is register an Interrupt Handler for a certain ExternalEventDef.

What happens when a WfRun is interrupted?

The interrupted ThreadRun is HALTED, and a child ThreadRun is created to act as the Interrupt Handler. For info, check out our concept docs and our WfSpec development docs.

You may want to interrupt a WfRun for various reasons including: A user cancels an order in on an e-commerce site, A business request is Denied or an external API returns a back off or denied status.

How can I access the content of an ExternalEvent inside my workflow?

You can use the output of an ExternalEventNode just like any other node in our SDK. Check out these docs

How do I post an ExternalEvent?

You need to know the WfRunId of the WfRun you want to notify, and you need to know the ExternalEventDefId.

Can I make ExternalEvents idempotent?

Yes, just pass the guid parameter in the PutExternalEventRequest when making the rpc PutExternalEvent.

Workflow Threading

Can I run tasks in parallel?

To run tasks in parallel within a single WfRun, you need to create a Child Thread.

Can different threads share variables?

A child ThreadRun can read and write the variables of its parent. A parent cannot view the variables of its child.

What happens when a child fails?

When a child fails, the failure propagates to the parent either at:

  • The WaitForThreadsNode, or
  • The ExitNode.

See the Child Thread Docs for info on how to handle these failures.

What happens to the child when a parent fails?

When a parent ThreadRun fails (ERROR or EXCEPTION) or moves to HALTED, the child will move to HALTED.

In order to recover from a failed Parent thread you can either catch the exception, and programmatically handle it. Or require that a human restarts the workflow.

User Tasks

What are User Tasks?

User Tasks allow a workflow to wait for input from a human.

How do I add a user task to my workflow?

A userTask is to manage tasks involving humans alongside standard computer tasks in your LittleHorse Workflow. Check out the User Tasks page of our WfSpec docs.

Do User Tasks support users and user groups?

Yes, user tasks can be assigned to either a user_id or a user_group. Note that user and group identities are not managed by the LH Server. User and group identies are managed by an external identity provider(IDP), for example any oAUTH provider.

How do I complete User Tasks?

For testing purposes, you can do it using lhctl. For production applications, check out our docs on managing User Tasks with grpc.

How do I create a UserTaskDef?

Check out our Managing Metadata docs.

Exception Handling

What is the difference between ERROR and EXCEPTION?

As per our Failure Handling Concepts Docs, an ERROR represents a technical failure such as a type error, network outage, timeout, or unexpected exception thrown by a task worker. An EXCEPTION represents something going wrong at the business process level, such as an invalid credit card or an item being out of stock.

How do I catch a failure in a workflow?

Check out our Failure Handling WfSpec docs.

How do I throw an EXCEPTION?

You can throw an EXCEPTION from a Task Worker. You can also make a ThreadRun fail with the WorkflowThread.fail() method.

Reliability

Is LittleHorse Fault-Tolerant?

Yes, it was built into the core DNA of our system. Every component of the LittleHorse tech stack is highly available and fault tolerant. At the workflow layer LittleHorse provides the primitives to handle faults in a way to suit the business needs.

Does LittleHorse scale?

Yes, in our internal benchmarks a moderately resourced, single instance, of LittleHorse server can execute 30,000 tasks per second in a moderately complex workflow.

How do I make Workflows idempotent?

You can pass the WfRunId when running a WfRun. Only one WfRun can exist with a given Id, so this makes the request idempotent.

How do I make Tasks idempotent?

You can use the WorkerContext to get an idempotency key.

About the Project

The source code for LittleHorse is copyright of LittleHorse Enterprises LLC, a Nevada LLC.

Can I use LittleHorse for free in production?

LittleHorse is covered by the SSPL 1.0 License. You may run LittleHorse in production for free and with no restrictions so long as you are not offering LittleHorse-as-a-Service. Basically, if your customers are not using the LittleHorse GRPC clients to interact with LittleHorse directly, you can run LittleHorse for free in production.

The SSPL license was originally created by Mongo DB, who has an excellent FAQ about the license terms.

Can I get enterprise support?

Yes. LittleHorse Enterprises LLC, which is the company behind the LittleHorse workflow engine, offers three forms of support for LittleHorse:

  • 24/7 enterprise support for LittleHorse OSS.
  • LittleHorse Cloud, which is a fully-managed SaaS service for LittleHorse.
  • LittleHorse for Kubernetes, which is an enterprise distribution of LittleHorse delivered through Kubernetes Operator into your K8s cluster.

You can reach LittleHorse Enterprises LLC via their website.

Do you accept contributions?

Yes, we do accept contributions. Check out our GitHub for tips on how to contribute.