> ## Documentation Index
> Fetch the complete documentation index at: https://iii.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Create an Ephemeral Function

> How to create a temporary worker that completes a task and gracefully shuts down.

## Goal

Create a script that connects to the engine, waits to process a task (e.g., generating a heavy report), and then gracefully shuts down.

## Context

This pattern is useful for executing resource-intensive or one-off tasks on serverless container platforms (like AWS Fargate or Kubernetes Jobs) where you want to minimize execution time and infrastructure costs.

## Steps

### 1. Initialize and Register

Connect to iii and register the `reports::generate` function handler to process the heavy CPU task.

<Tabs>
  <Tab title="Node / TypeScript">
    ```typescript title="worker.ts" theme={"theme":{"light":"catppuccin-latte","dark":"dark-plus"}}
    import { registerWorker, Logger } from 'iii-sdk'

    const iii = registerWorker(process.env.III_URL ?? 'ws://localhost:49134')

    iii.registerFunction('reports::generate', async (req) => {
      const logger = new Logger()
      const reportId = req.body?.reportId ?? 'unknown'
      
      logger.info('Generating heavy report...', { reportId })
      
      // ... perform resource-intensive work here ...
      await new Promise(resolve => setTimeout(resolve, 5000)) // example 5 second delay 
      
      logger.info('Report generated', { reportId })
      
      return { status_code: 200, body: { success: true, reportId } }
    })
    ```
  </Tab>

  <Tab title="Python">
    ```python title="worker.py" theme={"theme":{"light":"catppuccin-latte","dark":"dark-plus"}}
    import os
    import time

    from iii import Logger, register_worker

    iii = register_worker(os.environ.get("III_URL", "ws://localhost:49134"))


    def generate_report(req):
        logger = Logger()
        report_id = req.get("body", {}).get("reportId", "unknown")

        logger.info("Generating heavy report...", {"reportId": report_id})

        # ... perform resource-intensive work here ...
        time.sleep(5)  # example 5 second delay

        logger.info("Report generated", {"reportId": report_id})

        return {"status_code": 200, "body": {"success": True, "reportId": report_id}}


    iii.register_function("reports::generate", generate_report)
    ```
  </Tab>

  <Tab title="Rust">
    ```rust title="worker.rs" theme={"theme":{"light":"catppuccin-latte","dark":"dark-plus"}}
    use iii_sdk::{register_worker, InitOptions, Logger, RegisterFunction, TriggerRequest};
    use serde_json::{json, Value};

    #[tokio::main]
    async fn main() -> Result<(), Box<dyn std::error::Error>> {
        let url = std::env::var("III_URL").unwrap_or_else(|_| "ws://127.0.0.1:49134".to_string());
        let iii = register_worker(&url, InitOptions::default());

        let reg = RegisterFunction::new_async("reports::generate", |req: Value| async move {
            let logger = Logger::new();
            let report_id = req["body"]["reportId"].as_str().unwrap_or("unknown");

            logger.info("Generating heavy report...", Some(json!({ "reportId": report_id })));

            // ... perform resource-intensive work here ...
            tokio::time::sleep(std::time::Duration::from_secs(5)).await; // example 5 second delay

            logger.info("Report generated", Some(json!({ "reportId": report_id })));

            Ok(json!({
                "status_code": 200,
                "body": { "success": true, "reportId": report_id }
            }))
        });
        iii.register_function(reg);
    ```
  </Tab>
</Tabs>

### 2. Trigger and Graceful Shutdown

The main thread connects, triggers the function, awaits its completion, then calls `shutdown()` (or `shutdown_async().await` in Rust for guaranteed telemetry flush) to cleanly close the WebSocket and exit the process.

<Tabs>
  <Tab title="Node / TypeScript">
    ```typescript title="worker.ts" theme={"theme":{"light":"catppuccin-latte","dark":"dark-plus"}}
    async function main() {
      console.log("Worker ready, triggering task...")
      
      // Trigger the task and await its completion
      const result = await iii.trigger({
        function_id: 'reports::generate',
        payload: { body: { reportId: '123' } },
      })
      
      console.log("Task completed", result.status_code, result.body)
      
      console.log("Task completed. Shutting down worker...")
      
      // Cleanly close the WebSocket connection
      await iii.shutdown()
      process.exit(0)
    }

    main().catch(console.error)
    ```
  </Tab>

  <Tab title="Python">
    ```python title="worker.py" theme={"theme":{"light":"catppuccin-latte","dark":"dark-plus"}}
    print("Worker ready, triggering task...")

    # Trigger the task and await its completion
    result = iii.trigger({
        "function_id": "reports::generate",
        "payload": {"body": {"reportId": "123"}},
    })
    print(f"Task completed: status_code={result.get('status_code')} body={result.get('body')}")

    print("Task completed. Shutting down worker...")

    # Cleanly close the WebSocket connection
    iii.shutdown()
    ```
  </Tab>

  <Tab title="Rust">
    ```rust title="worker.rs" theme={"theme":{"light":"catppuccin-latte","dark":"dark-plus"}}
        println!("Worker ready, triggering task...");

        // Trigger the task and await its completion
        let result = iii
            .trigger(TriggerRequest {
                function_id: "reports::generate".into(),
                payload: json!({ "body": { "reportId": "123" } }),
                action: None,
                timeout_ms: None,
            })
            .await?;
        println!("Task completed: {}", result);

        println!("Task completed. Shutting down worker...");

        // Cleanly close the WebSocket connection
        iii.shutdown_async().await;

        Ok(())
    }
    ```
  </Tab>
</Tabs>

## Result

When the script runs, it connects to the Engine, waits for a single invocation of `reports::generate`, executes it, and cleanly disconnects and exits immediately after. This prevents zombie processes and automatically scales your infrastructure down once the heavy lifting is done.
