SlimFaas Documentation

repository·main·Indexed 19 days ago

https://github.com/slimplanet/slimfaas

A lightweight, autoscaling-first Function-as-a-Service (FaaS) platform optimized for Kubernetes and Docker. It features a two-phase scaling model (wake-up from zero via HTTP/Kafka/Schedules and scaling via PromQL) and built-in data management for binaries and KV state. The platform provides client libraries for .NET (SlimFaasClient) and Python (slimfaas-client) to connect processes via WebSockets, enabling them to handle asynchronous requests, synchronous streaming, and event pub/sub without exposing HTTP ports.

Tokens
68.5K
Snippets
164
Records
251
Agent score
65%

What's inside SlimFaas

  1. Overview of SlimFaas features and capabilities

    main

    SlimFaas is a lightweight, plug-and-play Function-as-a-Service (FaaS) platform designed for Kubernetes, Docker-Compose, or Podman-Compose. It focuses on an autoscaling-first design with several key capabilities:

    • Two-Phase Autoscaling:
      • 0 → N (Wake-up): Driven by HTTP history, time-based schedules, and Kafka topic activity (via SlimFaas Kafka).
      • N → M (Scaling): Driven by Prometheus metrics using a built-in PromQL evaluator.
    • Function Types: Supports both synchronous (HTTP) and asynchronous (queued) functions, as well as one-off, batch, and scheduled (cron) jobs.
    • Data Management:
      • Data Sets (/data/sets): A Redis-like KV store for small JSON/blobs (max 1 MiB) with millisecond TTL and atomic counters.
      • Data Files (/data/files): Stream-first endpoints for ingesting and serving temporary files of any size.
    • Internal Events: Built-in publish/subscribe mechanism to broadcast events to all replicas of a function without an external bus.
    • Security: Supports private functions (cluster-only) and public functions (via Ingress/API Gateways).
    • Observability: Built-in User Interface for monitoring functions, jobs, and queues, plus a "Mind Changer" REST API for inspecting state and waking functions on demand.
  2. Overview of SlimFaas MCP

    main
    SlimFaas MCP is a runtime Model-Context-Protocol (MCP) proxy that dynamically transforms any OpenAPI (Swagger v3) definition into a fully compliant MCP toolset. It acts as a dynamic proxy, meaning it exposes API endpoints as MCP tools on-the-fly without requiring code changes or static generation. This allows for live documentation updates and prompting overrides via the mcp_prompt parameter. It is designed to be lightweight (single binary > 15MB) and secure, supporting OIDC tokens and RFC 9728 for client dynamic discovery.
  3. Overview of SlimFaas Kafka Connector

    main

    SlimFaas-Kafka is a lightweight micro-service that acts as a sidecar orchestration component. It monitors Kafka topics for pending messages (lag) and recent consumption activity to automatically trigger the SlimFaas wake-up API. This enables event-driven autoscaling (scaling from 0 to N pods) based on Kafka queues.

    Key behavior:

    • Non-intrusive: It never consumes messages from your topics. It only queries high watermark offsets and committed consumer group offsets.
    • Triggers: It calls the SlimFaas wake-up API (POST /wake-functions/{functionName}) when pending messages exceed a threshold or recent activity is detected.
    • Architecture: Kafka TopicsSlimFaasKafkaSlimFaas OrchestratorFunction Pods.
  4. Overview of the Local Orchestrator

    main

    The Local orchestrator allows you to run a real multi-process SlimFaas cluster on your machine without requiring Kubernetes, Docker, or Podman. It is designed for local development, integration testing, diagnostics, and performance investigations.

    What is real

    • Three independent operating-system processes.
    • DotNext HTTP Raft (elections, replication, WAL, snapshots).
    • Synchronous and asynchronous function routing.
    • Async queues, workers, SlimData sets, TTLs, and counters.
    • File storage and cross-node file transfer.
    • Readiness and Prometheus metrics.

    What is simulated

    • Kubernetes discovery snapshot.
    • A single function pod advertised at 127.0.0.1:5050.
    • Function scale state (limited to 0 or 1).

    Note: The Local orchestrator does not manage containers or Kubernetes objects. Job operations are no-ops, and scaling only affects local discovery metadata.

  5. How SlimData ensures ordering and idempotency

    main

    SlimData guarantees total order via the RAFT leader and preserves FIFO order for each individual producer.

    Ordering Model

    Each producer (identified by hostname and SlimData port) emits batches with the following metadata:

    • ProducerId: Stable replica identity.
    • GenerationId: Unique identifier for the current process lifetime.
    • Sequence: A monotonic number for the producer's batches.
    • RequestId: A stable identifier for the request, used to handle transport retries.
    • Mutations: An ordered array of mutations, each with its own request ID.

    Retry and Deduplication

    To prevent duplicate operations (like double-incrementing a value) during network failures or leader changes:

    1. The local FIFO worker retries the exact same serialized batch if a leader is unavailable; it will not skip to a later batch.
    2. The state machine stores the last Sequence, RequestId, and Response for each producer in a replicated internal key.
    3. If a batch is replayed (e.g., after a leader change where the original acknowledgement was lost), the state machine recognizes the duplicate and returns the cached response without re-applying the mutation.
    4. Out-of-order or missing sequences are rejected to maintain integrity.
  6. Keepalive and Disconnection behavior

    main

    Keepalive: Clients can send Ping messages to maintain the connection. SlimFaas responds with a Pong using the same correlationId.

    Disconnection: When a WebSocket connection is lost:

    1. The connection is automatically unregistered.
    2. Pending async callbacks are completed with a 503 status.
    3. Pending synchronous streams are cancelled.
    4. If it was the last connection for that functionName, the virtual function is removed from the SlimFaas status.

    Official client libraries (.NET and Python) handle automatic reconnection.

  7. How SlimFaasKafka decides to wake up a function

    main

    SlimFaasKafka evaluates each binding (a combination of topic, consumer group, and function) using three main logic components:

    1. Pending Messages: Calculated as pending = high_watermark - committed_offset. If Kafka ACLs prevent reading offsets, it falls back to using high_watermarks (less accurate but safe).
    2. Recent Activity: It tracks changes in committed offsets. If the delta of committed messages exceeds the configured MinConsumedDeltaForActivity, it is considered real activity. This can be used to keep a function awake via the ActivityKeepAliveSeconds window.
    3. Cooldown: To prevent spamming the SlimFaas API, a cooldown period (CooldownSeconds) is applied per (topic, group) binding.
  8. Map MCP `_meta` values to HTTP headers

    main

    SlimFaas MCP allows you to dynamically map values from the MCP _meta object to outgoing HTTP headers. This is useful for clients (like Spring AI) that transmit authentication tokens via _meta instead of standard headers.

    Configuration: Define the mapping in the McpMetaHeaderMapping section of appsettings.json:

    {
      "McpMetaHeaderMapping": {
        "authToken": "Authorization",
        "xSessionId": "X-Session-Id"
      }
    }

    How it works: When a tool is called, the values in _meta are injected into the outgoing request headers.

    • If the mapped header is Authorization, SlimFaas MCP automatically prepends Bearer if it is missing.
    • This feature supports OAuth challenge compatibility: if _meta.authToken is mapped to Authorization, the 401 challenge is automatically bypassed.

    Example Request:

    {
      "jsonrpc": "2.0",
      "method": "tools/call",
      "params": {
        "name": "get_dashboard_policies",
        "arguments": {},
        "_meta": {
          "authToken": "eyJhbGciOiJSUzI1NiIsInR5cCI...",
          "xSessionId": "abc-123"
        }
      }
    }

    Resulting Headers: Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI... X-Session-Id: abc-123

    {
      "McpMetaHeaderMapping": {
        "authToken": "Authorization",
        "xSessionId": "X-Session-Id"
      }
    }
  9. How the SlimFaas autoscaling decision algorithm works

    main

    SlimFaas uses a two-tier decision process during each periodic tick of CheckScaleAsync:

    1. HTTP/Schedule System (Tier 1): This system runs first and is the only mechanism that can propose a transition from 0 to > 0 replicas. It calculates a proposedReplicas value based on HTTP history, scheduled wake-up times, and dependency activity.
    2. Prometheus-based System (Tier 2): This system only runs if currentReplicas > 0. It calculates desiredFromMetrics using the PromQL queries defined in your SlimFaas/Scale annotations.

    Scale-to-Zero Logic

    When ReplicasMin = 0, scaling to zero requires agreement between both systems:

    • The HTTP/Schedule system must propose scaling down to 0 (due to inactivity).
    • The Prometheus system must also return a value where desiredFromMetrics <= 0.
    • If metrics still require capacity (desiredFromMetrics > 0), SlimFaas will maintain at least one replica (max(1, desiredFromMetrics)).

    Multi-Trigger Logic

    If multiple triggers are defined in the SlimFaas/Scale annotation, the final desiredReplicas is the maximum value produced by any individual trigger.

  10. Understand SlimFaas Autoscaling Architecture

    main

    SlimFaas uses two complementary autoscaling systems to manage function replicas:

    1. 0 → N scaling (Wake-up from zero): Driven by HTTP call history, scheduled wake-up times, and function dependencies (DependsOn). This is the only system capable of bringing a function from 0 replicas to a positive number.
    2. N → M scaling (Prometheus AutoScaler): Driven by Prometheus metrics and PromQL. This system manages scaling when a function already has at least one pod (replicas > 0).

    Scale-to-Zero Logic: If you want to scale to zero (ReplicasMin: "0"), the two systems must agree. If the Prometheus AutoScaler is enabled (via the SlimFaas/Scale annotation with triggers), it can "veto" a scale-down to zero if its metrics indicate capacity is still needed (desired > 0). To allow the HTTP/Schedule system to control scale-to-zero exclusively, set Triggers: [] in the SlimFaas/Scale annotation.

    flowchart LR
      R[ReplicasService.CheckScaleAsync]
      SW[ScaleReplicasWorker]
      K8S[(Kubernetes API)]
    
      subgraph HTTP_history["HTTP history and Schedule (0->N)"]
        H["History HTTP (in-memory + DB)"] --> R
        SC[Schedule config] --> R
        DP[DependsOn] --> R
      end
    
      subgraph Prometheus["Prometheus AutoScaler (N->M)"]
        MSW[MetricsScrapingWorker] --> MS[Metrics store]
        MS --> PQ[PromQL evaluator]
        PQ --> AS[AutoScaler]
        AS --> ASS[AutoScalerStore]
      end
    
      SW --> R
      R -- scale 0->N / N->0 --> K8S
      R -- desiredReplicas N->M --> K8S
  11. Use local-only process dependencies

    main

    In native local mode, a function, Job, or scheduled Job can wait for an auxiliary process to be running before it starts. This is achieved by using the processes:<name> prefix within the SlimFaas/DependsOn annotation.

    How it works:

    • A process is considered "ready" as soon as the managed operating-system process is running.
    • Functions waiting on a process dependency will not scale up until the process is running.
    • Jobs will remain queued until the process dependency is running.
    • Note: There is no health probe for auxiliary processes. If a process dies, functions that are already running will not automatically scale down.
    • This mechanism is ignored by Docker and Kubernetes, allowing you to use the same annotation to combine deployed dependencies (e.g., orders-database) with local development replacements (e.g., processes:database-emulator).
    functions:
      orders-api:
        annotations:
          SlimFaas/Function: "true"
          SlimFaas/DependsOn: "orders-database,processes:database-emulator"
    
    processes:
      database-emulator:
        command: ["database-emulator", "--port", "{port}"]
        port: auto
        restartPolicy: always
  12. Configure OAuth metadata via `oauth` parameter

    main

    To allow clients to perform dynamic authorization server discovery (RFC 9728), provide an oauth query parameter. This parameter must be a UTF-8 Base64 encoded JSON object containing OAuth Protected Resource Metadata.

    Example JSON structure:

    {
        "resource":"https://api.example.com/v1/",
        "authorization_servers":["https://auth.example.com"],
        "scopes_supported":["read:data","write:data"]
    }

    If a client attempts to access a protected resource without an Authorization header, the server will return a 401 with a WWW-Authenticate: Bearer resource_metadata=".../.well-known/oauth-protected-resource" challenge.