Your First Task Worker
In LittleHorse, Task Workers are the building blocks of your WfSpec
s. They do the actual "work" when a WfRun
schedules a TaskRun
to be executed. In this guide, we'll learn how to create your first Task Worker.
What is a Task Worker?
A Task Worker is a program that uses the LittleHorse SDK to poll TaskRun
s from the queue in the LittleHorse Server. Every time the LittleHorse Server tells it to, the Task Worker executes a function or method that you write. That method invocation becomes a TaskRun
in a WfRun
; when it is executed the result is reported automatically back to the LittleHorse Server so the engine can decide what happens next in that particular WfRun
.
The TaskDef
LittleHorse needs to keep track of all of the available types of TaskDef
s that you can execute. This is done with the TaskDef
. Before you can create a WfSpec
that refers to a TaskDef
, you must first register the TaskDef
that you want to refer to. The TaskDef
stores useful information such as the name and input / output types of the TaskDef
.
A TaskDef
is like a method signature. It tells LittleHorse the method's name, what inputs it needs, and what output it gives back.
Creating a Task Worker
In this section, we will write the code for the Task Worker from the quickstart which executes the simple greet()
method.
Project Setup
First, make sure you have the LittleHorse Server running in your local environment:
docker run --pull always --name littlehorse --rm -d -p 2023:2023 -p 8080:8080 ghcr.io/littlehorse-enterprises/littlehorse/lh-standalone:latest
For the purposes of this tutorial, we will be using your respective language's Quickstart:
- Java
- Python
- Go
- C#
git clone https://github.com/littlehorse-enterprises/lh-quickstart-java.git
cd lh-quickstart-java
Let's delete all the files in the src/main/java/io/littlehorse/quickstart
directory before we start.
git clone https://github.com/littlehorse-enterprises/lh-quickstart-python.git
cd lh-quickstart-python
Let's delete all the files in the quickstart
directory before we start.
git clone https://github.com/littlehorse-enterprises/lh-quickstart-go.git
cd lh-quickstart-go
Let's delete all the files in the src
directory before we start.
git clone https://github.com/littlehorse-enterprises/lh-quickstart-dotnet.git
cd lh-quickstart-dotnet
Let's delete all the files in the src
directory before we start.
Writing the Task Method
Let's create a simple greeting TaskDef
implementation:
- Java
- Python
- Go
- C#
package io.littlehorse.quickstart;
import io.littlehorse.sdk.worker.LHTaskMethod;
public class Greeter {
@LHTaskMethod("greet")
public String normalJavaMethod(String name) {
return "Hello, " + name + "!";
}
}
from littlehorse.sdk.worker import LHTaskMethod
class Greeter:
@LHTaskMethod("greet")
def normal_python_method(self, name: str) -> str:
return f"Hello, {name}!"
package quickstart
import "fmt"
import "github.com/littlehorse/sdk-go/worker"
type Greeter struct{}
func (g *Greeter) Greet(name string) string {
return fmt.Sprintf("Hello, %s!", name)
}
func init() {
worker.RegisterTaskMethod("greet", new(Greeter).Greet)
}
Registering the Task Worker
Before we can use our Task Worker in workflows, we need to register it with the LittleHorse Server by creating a TaskDef
. The LittleHorse SDK ships with a useful LHTaskWorker
object that makes it easy to do that. The following executable Main
file accomplishes that:
- Java
- Python
- Go
- C#
package io.littlehorse.quickstart;
import io.littlehorse.sdk.common.config.LHConfig;
import io.littlehorse.sdk.worker.LHTaskWorker;
public class Main {
public static void main(String[] args) {
LHConfig config = new LHConfig();
LHTaskWorker worker = new LHTaskWorker(new Greeter(), "greet", config);
worker.registerTaskDef();
}
}
from littlehorse.sdk.common.config import LHConfig
from littlehorse.sdk.worker import LHTaskWorker
from greeter import Greeter
def main():
config = LHConfig()
worker = LHTaskWorker(Greeter(), "greet", config)
worker.register_task_def()
if __name__ == "__main__":
main()
package main
import (
"github.com/littlehorse/sdk-go/common/config"
"github.com/littlehorse/sdk-go/worker"
"io/littlehorse/quickstart"
)
func main() {
config := config.NewLHConfig()
worker := worker.NewLHTaskWorker(new(quickstart.Greeter), "greet", config)
worker.RegisterTaskDef()
}
Running the Worker
The last thing that remains is to run the Task Worker so that it can start listening for TaskRun
s to execute. The following executable Main
file can do that:
- Java
- Python
- Go
- C#
package io.littlehorse.quickstart;
import io.littlehorse.sdk.common.config.LHConfig;
import io.littlehorse.sdk.worker.LHTaskWorker;
public class Main {
public static void main(String[] args) {
LHConfig config = new LHConfig();
LHTaskWorker worker = new LHTaskWorker(new Greeter(), "greet", config);
worker.start();
}
}
from littlehorse.sdk.common.config import LHConfig
from littlehorse.sdk.worker import LHTaskWorker
from greeter import Greeter
def main():
config = LHConfig()
worker = LHTaskWorker(Greeter(), "greet", config)
worker.start()
if __name__ == "__main__":
main()
package main
import (
"github.com/littlehorse/sdk-go/common/config"
"github.com/littlehorse/sdk-go/worker"
"io/littlehorse/quickstart"
)
func main() {
config := config.NewLHConfig()
worker := worker.NewLHTaskWorker(new(quickstart.Greeter), "greet", config)
worker.Start()
}
Wrapping Up
In this tutorial, you learned about the basic building blocks used in a WfSpec
: TaskDef
s and Task Workers. Now that you have created your first Task Worker, continue on to the next lesson to learn how to use it inside a WfSpec
.
In the meantime, if you haven't done so already:
- Join the LittleHorse Slack Community
- Give us a star on GitHub
- Check out our documentation