Skip to main content
Workflows are the core orchestration component in Infinitic. They coordinate the execution of services, manage state, handle timing, and ensure reliable distributed execution.

What are Workflows?

Workflows in Infinitic are classes that:
  • Extend the Workflow base class
  • Define business logic that orchestrates services and other workflows
  • Execute deterministically to ensure reliability
  • Maintain state across distributed executions
  • Handle failures and retries automatically

Key Features

Service Orchestration

Call and coordinate multiple services with automatic retry and error handling

Asynchronous Execution

Dispatch tasks asynchronously and wait for results when needed using Deferred objects

Sub-workflows

Compose complex workflows from simpler workflow components

Channels

Receive external signals and events during workflow execution

Timers

Wait for specific durations or until specific times

Versioning

Update workflow logic while maintaining compatibility with running instances

Basic Workflow Structure

import io.infinitic.workflows.Workflow

// Define the workflow interface
interface BookingWorkflow {
  fun bookTrip(userId: String, destination: String): BookingResult
}

// Implement the workflow
class BookingWorkflowImpl : Workflow(), BookingWorkflow {
  
  // Create service stubs
  private val flightService = newService(FlightService::class.java)
  private val hotelService = newService(HotelService::class.java)
  private val paymentService = newService(PaymentService::class.java)
  
  override fun bookTrip(userId: String, destination: String): BookingResult {
    // Book flight
    val flight = flightService.bookFlight(userId, destination)
    
    // Book hotel
    val hotel = hotelService.bookHotel(userId, destination)
    
    // Process payment
    val payment = paymentService.charge(userId, flight.price + hotel.price)
    
    return BookingResult(flight, hotel, payment)
  }
}

Workflow Context

Every workflow has access to contextual information during execution:
class MyWorkflow : Workflow(), MyWorkflowInterface {
  override fun process() {
    // Access workflow context
    val wfName = Workflow.workflowName     // Workflow name
    val wfId = Workflow.workflowId         // Unique workflow instance ID
    val methodName = Workflow.methodName   // Current method being executed
    val methodId = Workflow.methodId       // Unique method execution ID
    val tags = Workflow.tags               // Workflow tags
    val meta = Workflow.meta               // Workflow metadata
  }
}

Determinism

Workflows must be deterministic to ensure reliability. This means:
Avoid Non-Deterministic OperationsDo not use these directly in workflow code:
  • System.currentTimeMillis(), Instant.now(), or any time-based functions
  • Random number generators
  • External API calls outside of service stubs
  • Direct database access
  • File I/O operations
Instead:
  • Use timer() for time-based operations
  • Use inline() for operations that need to run synchronously
  • Use service stubs for all external interactions

Inline Tasks

For simple computations that don’t require services, use inline tasks:
class MyWorkflow : Workflow(), MyWorkflowInterface {
  override fun calculate(values: List<Int>): Int {
    // Run computation inline (synchronously)
    return inline {
      values.sum()
    }
  }
}

Next Steps

Defining Workflows

Learn how to create and structure workflows

Calling Services

Understand how to call services from workflows

Workflow Methods

Explore available workflow methods and operations

Channels

Receive external signals during execution

Build docs developers (and LLMs) love