Jobs

SDK source (GitHub): https://github.com/tangle-network/blueprint/tree/main/crates/runner

Jobs are the core building blocks of a Blueprint Runner. They define the computational tasks that your Blueprint will execute in response to events.

Jobs are event-driven functions

In a Blueprint, jobs are functions that:

  1. Receive inputs from producers
  2. Perform specific computational tasks
  3. Return results that can be processed by consumers

Job Definition

Jobs in a Blueprint are defined in the library package of your project. A job definition consists of:

  1. A unique job ID that identifies the job
  2. A function that implements the job’s logic
  3. Input parameters that the job accepts
  4. Return values that the job produces

Basic Job Structure

A squaring handler with its imports, for src/lib.rs in a Blueprint project:

lib.rs
use blueprint_sdk::macros::debug_job;
use blueprint_sdk::tangle::extract::{TangleArg, TangleResult};

#[debug_job]
pub async fn square(TangleArg((x,)): TangleArg<(u64,)>) -> TangleResult<u64> {
    let result = x * x;
    TangleResult(result)
}

In this example:

  • The router below registers square under the XSQUARE_JOB_ID constant
  • square is the function that implements the job’s logic
  • The job takes a single ABI-encoded input parameter x extracted by TangleArg<(u64,)>
  • The job returns a TangleResult<u64>, which the runner ABI-encodes for submission

Job Context

Jobs can access context information provided by the Blueprint Runner. This context can include:

  • Configuration settings
  • Connections to external systems
  • State information
  • Utility functions

Pass shared state with Router::with_context. Jobs read that state through the Context extractor. See the Contexts guide for complete examples.

Job Registration

Register the handler with the router. This complete src/lib.rs registers the squaring job on the Tangle layer:

lib.rs
use blueprint_sdk::macros::debug_job;
use blueprint_sdk::tangle::extract::{TangleArg, TangleResult};
use blueprint_sdk::tangle::TangleLayer;
use blueprint_sdk::{Job, Router};

pub const XSQUARE_JOB_ID: u8 = 0;

#[debug_job]
pub async fn square(TangleArg((x,)): TangleArg<(u64,)>) -> TangleResult<u64> {
    let result = x * x;
    TangleResult(result)
}

#[must_use]
pub fn router() -> Router {
    Router::new().route(XSQUARE_JOB_ID, square.layer(TangleLayer))
}

Job Execution Flow

The execution flow of a job in a Blueprint Runner follows these steps:

  1. A producer generates a job call with specific parameters
  2. The router directs the job call to the appropriate job handler
  3. The job executes its logic and produces a result
  4. The result is passed to consumers for further processing

Integration with Other Components

Jobs work closely with other Blueprint Runner components:

  • Routers: Routers direct job calls to the appropriate job handlers
  • Producers: Producers generate job calls with specific parameters
  • Consumers: Consumers process the results of job execution

Next Steps

Now that you understand jobs, it might be helpful to take a look at:

Before You Ship

Test each job with valid input, invalid input, and an execution failure. The handler should reject malformed calls before doing work and return errors that let a consumer decide whether to retry, alert, or stop.