Jobs
In Tork, a Job is a series of tasks running in the order they appear on the job description from top to bottom.
Super simple example
Section titled “Super simple example”name: hello jobtasks: - name: say hello image: ubuntu:mantic var: task1 run: | echo -n hello world > $TORK_OUTPUT - name: say goodbye image: ubuntu:mantic run: | echo -n bye world
curl -s -X POST \ --data-binary @job.yaml \ -H "Content-type: text/yaml" \ http://localhost:8000/jobs
What will happen:
-
The Coordinator will schedule the first task (
say hello
) for execution by inserting it into thedefault
queue. -
One of the worker nodes that is subscribed to the
default
queue will pick up the task. -
The worker node will inspect the
image
property to find out what Docker image is needed to execute the task. -
If the
ubuntu:mantic
image doesn’t exist locally the worker node will pull it from Docker Hub. -
The worker node will start a container in order to execute the task.
-
The worker node will execute the
run
script on the container. -
The worker node will collect the output from the
$TORK_OUTPUT
file assigned to the container for any optional task output. -
The worker will terminate the container.
-
The worker will insert the task to the
completions
queue. -
The Coordinator will pick up the task from the
completions
queue and mark it as completed in theDatastore
. -
The Coordinator will insert the output of the task to the Job’s context under the key specified in the
var
property (task1
). -
The Coordinator will check if there are any additional tasks to be executed on the job.
-
Since there is another task, the Coordinator will be repeat the above steps for this task.
-
Once all tasks are completed, the job state will be marked as
COMPLETED
.
Inputs
Section titled “Inputs”Jobs may specify inputs
which can be used by any of the job’s tasks. Example:
name: mov to mp4inputs: source: https://example.com/path/to/video.movtasks: - name: convert the video to mp4 image: jrottenberg/ffmpeg:3.4-alpine env: SOURCE_URL: "{{ inputs.source }}" run: | ffmpeg -i $SOURCE_URL /tmp/output.mp4
Secrets
Section titled “Secrets”Sensitive values can be specified in the secrets
block so they can be auto-redacted from API responses.
name: my jobsecrets: api_key: 1111-1111-1111-1111tasks: - name: my task image: alpine:latest queue: default env: # use the 'secrets' namespace to inject a secret API_KEY: "{{secrets.api_key}}" run: | curl -X POST -H "API_KEY: $API_KEY" http://example.com
Defaults
Section titled “Defaults”Jobs may specify default values for all their tasks. All properties are optional.
name: my jobdefaults: retry: # a task will retry up to 2 times in case of a failure limit: 2 # resource limits imposed on a task limits: # 1 CPU limit cpus: 1 # 500MB of RAM limit memory: 500m # a task will automatically fail if not completed within 10 minutes timeout: 10m # tasks will be routed to the highcpu queue by default queue: highcpu # values between 0-9. Higher numbers mean higher priority priority: 3tasks: - name: my task image: alpine:latest queue: default # override the job defaults run: | echo hello world
Auto Delete
Section titled “Auto Delete”Jobs may specify a period of retention past their completion timestamp, after which they will be automatically deleted. Cancelled or failed jobs will not be automatically deleted.
name: my jobautoDelete: # job will be automatically deleted 6 hours after its completion. after: 6htasks: - name: my task image: alpine:latest run: | echo hello world
Webhooks
Section titled “Webhooks”Jobs may specify zero or more webhooks that will be called for various events.
Webhooks will be triggerd on either of two event types:
job.StateChange
(Default) - the webhook will be called every time the job changes from one state to another - e.g. fromSCHEDULED
toRUNNING
.task.StateChange
- the webhook will be called every time a task changes from one state to another.
name: my jobwebhooks: # Webhook URL (assuming POST) - url: http://example.com/my/webhook # event type event: job.StateChange # optional headers to send when calling the webhook endpoint headers: my-header: somevalue # optional: conditional execution of the webhook if: "{{ job.State == 'COMPLETED' }}"tasks: - name: my task image: alpine:latest run: | echo hello world
Permissions
Section titled “Permissions”When specified, permissions specify which user(s) or role(s) should have access to this particular job.
Jobs without permissions
will be viewable to all users.
name: my jobpermissions: # the role's slug - role: some-role # the user's username - user: someusertasks: - name: my task image: alpine:latest run: | echo hello world
Scheduled jobs
Section titled “Scheduled jobs”Jobs can be scheduled to execute at specific times using the schedule
property. The schedule uses the cron syntax to define the intervals.
Example:
name: scheduled job testschedule: cron: "0/5 * * * *" # run the job every 5 minutestasks: - name: my first task image: alpine:3.18.3 run: echo -n hello world
curl -s -X POST \ --data-binary @job.yaml \ -H "Content-type: text/yaml" \ http://localhost:8000/scheduled-jobs | jq .
{ "id": "c90188cce61244a1aabcdbedf31f51d6", "state": "ACTIVE", "name": "scheduled job test", "createdAt": "2024-12-21T14:53:05.709793Z", "cron": "0/5 * * * *"}