Only this pageAll pages
Powered by GitBook
1 of 27

Tarmac

Loading...

Functions

Loading...

Writing Functions

Loading...

Loading...

Loading...

Capabilities

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Running Tarmac

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

WebAssembly Developer Resources

Introduction

Tarmac Banner

Framework for writing functions, microservices, or monoliths with Web Assembly

Tarmac is a new approach to application frameworks. Tarmac is language agnostic and offers built-in support for key/value stores like BoltDB, Redis, and Cassandra, traditional SQL databases like MySQL and Postgres, and fundamental capabilities like mutual TLS authentication and observability.

Supporting languages like Go, Rust, & Zig, you can focus on writing your functions in whatever language you like while benefiting from a robust suite of capabilities for building modern distributed services.

Quick Start

Tarmac makes it easy to get started with building complex functions. The below function (written in Go) is an excellent example of its simplicity.

To start running this function, navigate to our examples directory and run the make build command. The make build command compiles the code and generates a WebAssembly module.

Once compiled, you can run this function as a standalone microservice using the following Docker command.

With Tarmac now running, we can access our WASM function using any HTTP Client such as curl.

That's it! You can write and deploy functions in Go, Rust, AssemblyScript, Swift, or Zig with Tarmac. For more advanced functions, check out our .

Multi-Function Services

While users of Tarmac can build standalone microservices with a single function quickly, it shines with multi-function services. Tarmac's ability to run multiple functions means you can create purpose-built platforms with the developer experience of serverless functions.

To get started with multi-function services, you must provide a tarmac.json configuration file (via the WASM_FUNCTION_CONFIG configuration parameter) that lists the Functions to load and the various protocols and routes to expose as endpoints. Below is a sample tarmac.json configuration file.

Each function has its own code base but shares the same service namespace and configurations in a multi-function service configuration.

In the example above, we have a service named my-service with function1 and function2 functions. Each function has a .wasm file at /path/to/function1.wasm and /path/to/function2.wasm.

To define the routes for each function, add a route object to the routes array with the type set to http and the function set to the function's name.

In addition to the http route type, Tarmac also supports scheduled_task routes that execute a function at a specific interval. The frequency parameter specifies the interval (in seconds).

With Tarmac's support for multiple functions, you can quickly build complex, distributed services by dividing your service into smaller, more manageable pieces.

Architecture

Tarmac is a serverless platform that enables users to define and execute WebAssembly Functions. When Tarmac receives requests, it forwards them to WebAssembly Functions, which act as request handlers. The communication between Tarmac and WebAssembly Functions is via WebAssembly Procedure Calls (waPC).

By leveraging waPC, WebAssembly Functions can interact with Tarmac's core capabilities. Capabilities include performing callbacks to the Tarmac server to access key-value stores, interact with SQL databases, or make HTTP requests to downstream services.

To provide a streamlined developer experience, Tarmac offers a Go SDK that simplifies the usage of waPC. The SDK abstracts away the complexity of using waPC, allowing developers to focus on writing their functions and leveraging Tarmac's features.

Example Application Architecture

The below diagram shows the architecture of an . This application demonstrates how to build a multi-function service with Tarmac using Go.

This example application will execute WebAssembly functions on boot and via a scheduler to manage airport data. The application also includes an HTTP server that serves the airport data to clients via a WebAssembly function.

Language
waPC Client
Tarmac SDK

Contributing

We are thrilled that you are interested in contributing to Tarmac and helping to make it even better! To get started, please check out our contributing guide for information on how to submit bug reports, feature requests, and code contributions.

Project Contributors

Zig

✅

AssemblyScript

✅

Go

✅

✅

Rust

✅

Swift

✅

developer guides
example application

// Tac is a small, simple Go program that is an example WASM module for Tarmac. This program will accept a Tarmac
// server request, log it, and echo back the payload in reverse.
package main

import (
	"fmt"
	"github.com/tarmac-project/tarmac/pkg/sdk"
)

var tarmac *sdk.Tarmac

func main() {
	var err error

	// Initialize the Tarmac SDK
	tarmac, err = sdk.New(sdk.Config{Handler: Handler})
	if err != nil {
		return
	}
}

// Handler is the custom Tarmac Handler function that will receive a payload and
// must return a payload along with a nil error.
func Handler(payload []byte) ([]byte, error) {
	var err error

	// Log it
	tarmac.Logger.Trace(fmt.Sprintf("Reversing Payload: %s", payload))

	// Check Cache
	key := string(payload)
	rsp, err := tarmac.KV.Get(key)
	if err != nil || len(payload) < 1 {
		// Flip it and reverse
		if len(payload) > 0 {
			for i, n := 0, len(payload)-1; i < n; i, n = i+1, n-1 {
				payload[i], payload[n] = payload[n], payload[i]
			}
		}
		rsp = payload

		// Store in Cache
		err = tarmac.KV.Set(key, payload)
		if err != nil {
			tarmac.Logger.Error(fmt.Sprintf("Unable to cache reversed payload: %s", err))
			return rsp, nil
		}
	}

	// Return the payload
	return rsp, nil
}
$ cd example/tac/go
$ make build
$ docker run -p 8080:8080 \
  -e "APP_ENABLE_TLS=false" -e "APP_LISTEN_ADDR=0.0.0.0:8080" \
  -v `pwd`/functions:/functions madflojo/tarmac
$ curl -v --data "Tarmac Example" http://localhost:8080
{
  "services": {
    "my-service": {
      "name": "my-service",
      "functions": {
        "function1": {
          "filepath": "/path/to/function1.wasm"
        },
        "function2": {
          "filepath": "/path/to/function2.wasm"
        }
      },
      "routes": [
        {
          "type": "http",
          "path": "/function1",
          "methods": ["GET"],
          "function": "function1"
        },
        {
          "type": "http",
          "path": "/function2",
          "methods": ["POST"],
          "function": "function2"
        }
      ]
    }
  }
}
{
  "type": "scheduled_task",
  "function": "function1",
  "frequency": 10
}
graph TB
    Client[Client]
    
    subgraph TarmacHost["Tarmac Host"]
        HTTPHandler[HTTP Request Handler]
        OnBootTrigger[On Boot Function Trigger]
        ScheduledTrigger[Scheduled Function Trigger]
        
        subgraph WASMEngine["WebAssembly Engine"]
            Init[Init: Creates DB Tables, Calls Load]
            Load[Load: Calls Fetch, then loads results to SQL Database]
            Fetch[Fetch: Download AirportData.csv]
            Lookup[Lookup: Fetches Data from Cache/DB]
        end
        
        subgraph Capabilities["Tarmac Capabilities"]
            KVStore[KV Store]
            SQLDatabase[SQL Database]
            Metrics[Metrics]
            Logger[Logger]
        end
    end
    
    HTTPServer[HTTP Server: AirportData.csv]
    
    subgraph ExternalServices["External Services (Not all used in Example Application)"]
        Consul[Consul]
        Prometheus[Prometheus]
        Redis[Redis]
        MySQL[MySQL]
        PostgreSQL[PostgreSQL]
        Cassandra[Cassandra]
    end
    
    Client --> HTTPHandler
    HTTPHandler --> Lookup
    OnBootTrigger --> Init
    ScheduledTrigger --> Load
    Init --> Load
    Load --> Fetch
    Fetch --> HTTPServer
    
    Lookup --> KVStore
    Lookup --> SQLDatabase
    Load --> SQLDatabase
    
    KVStore --> Redis
    KVStore --> Cassandra
    SQLDatabase --> MySQL
    SQLDatabase --> PostgreSQL
    Metrics --> Prometheus
Build Status
codecov

Rust

Creating a WASM Function in Rust.

Web Assembly (WASM) support is a first-class feature in Rust, making Rust an excellent language to write WASM functions for Tarmac.

This guide will walk users through creating a WASM function for Tarmac in the Rust language. This walkthrough assumes there is some familiarity with the Rust tooling and language to start.

Creating the WASM Function

We will need to begin with a new project folder, creating the src/ directory. Within that directory, we will make our main.rs file.

Tarmac internally uses a Web Assembly Procedure Calls (waPC) runtime, which means all WASM functions running within Tarmac must import and use a waPC compliant library.

Along with the waPC imports, you should also see a wapc_init() function created. This function is the primary entry point for Tarmac execution. We will register our handler function for Tarmac to execute using the register_function() function within this function.

In the example above, we have registered the handler() function. When Tarmac receives an HTTP POST request for this WASM function, it will execute the handler function as defined.

With our handler function now registered, we must create a basic version of this handler for Tarmac to call.

As we can see from the example above, the handler input a slice of 8-bit unsigned integers, which is the raw HTTP payload. And a return value of CallResult.

Adding Logic

Now that we have the basic structure of our WASM function created, we can start adding logic to the function and process our request.

Host Callbacks

One of the unique benefits of Tarmac is the ability for WASM functions to perform host callbacks to the Tarmac service itself. These Host Callbacks give users the ability to execute common framework code provided to the WASM function by Tarmac. These common framework functions can include storing data within a database, calling a remote API, or logging data.

For our example, we will use the Host Callbacks to create a Trace log entry.

For a full list of Host Callbacks checkout the documentation.

Do Work and Generate a Response

We can add our logic to the example, which in this case will just return the input payload.

Full WASM function

For quick reference, the below code is the full WASM function from this example.

Building the WASM Function

Now that our function is ready, we must compile our Rust code into a .wasm file. To do this, we will need to create our Cargo manifest and build the project.

Within the Cargo.toml file, we must specify the different packages used in our WASM function.

With our manifest defined, we can now build our module.

After the code build completes, we will copy the .wasm file into a directory Tarmac can use to run.

Running the WASM Function

We are now ready to run our WASM function via Tarmac. To make this process easier, we will be using Docker to execute Tarmac. It is not necessary to use Docker with Tarmac as it can run outside of Docker as well.

In the above command, we pass two environment variables to the container using the -e flag. These environment variables will tell Tarmac to use HTTP rather than HTTPS, which is the default. For additional configuration options, check out the documentation.

With Tarmac now running, we can access our WASM function using any HTTP Client such as curl.

Conclusion

Developers can use this guide to get started with WASM functions and using Tarmac. Some of the information in this guide is subject to change as WASM advances. However, the concepts should stay pretty consistent.

fn main() {}
Callbacks
Configuration
extern crate wapc_guest as guest;
use guest::prelude::*;

fn main() {}

#[no_mangle]
pub extern "C" fn wapc_init() {}
#[no_mangle]
pub extern "C" fn wapc_init() {
  register_function("handler", handler);
}
fn handler(msg: &[u8]) -> CallResult {}
  // Perform a host callback to log the incoming request
  let _res = host_call("tarmac", "logger", "trace", &msg.to_vec());
  Ok(msg.to_vec())
// Echo is a small, simple Rust program that is an example WASM module for Tarmac.
// This program will accept a Tarmac server request, log it, and echo back the payload.
extern crate wapc_guest as guest;
use guest::prelude::*;

fn main() {}

#[no_mangle]
pub extern "C" fn wapc_init() {
  register_function("handler", handler);
}

fn handler(msg: &[u8]) -> CallResult {
  // Perform a host callback to log the incoming request
  let _res = host_call("tarmac", "logger", "trace", &msg.to_vec());
  Ok(msg.to_vec())
}
$ cargo init
[package]
name = "echo"
version = "0.1.0"
authors = ["Example Developer <developer@example.com>"]
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
wapc-guest = "0.4.0"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
base64 = "0.13.0"
$ cargo build --target wasm32-unknown-unknown --release
$ mkdir -p functions
$ cp target/wasm32-unknown-unknown/release/echo.wasm functions/tarmac.wasm
$ docker run -p 8080:8080 \
  -e "APP_ENABLE_TLS=false" -e "APP_LISTEN_ADDR=0.0.0.0:8080" \
  -v ./functions:/functions madflojo/tarmac
$ curl -v --data "Tarmac Example" http://localhost:8080

Callbacks

Powered by Web Assembly Procedure Calls

Tarmac, at its core, is powered by the Web Assembly Procedure Call (waPC) Project. The Web Assembly Procedure Call Project defines imported and exported functions between a WASM host and a guest WASM function. A WASM runtime host like Tarmac and a WASM Function running within Tarmac can communicate back and forth using these functions.

A prime example of this is the HostCall() function used by guest WASM functions. This HostCall() is a callback function that enables WASM functions to pass back data to the Tarmac host for the explicit goal of executing host-level functionality.

This ability to perform a Host Callback is what sets Tarmac apart from most other serverless runtimes. A WASM function can use the Host Callback functionality to access a full suite of standard functionality that would traditionally be too heavy for a serverless function.

Essentially, Host Callbacks allow Tarmac to provide developers the functionality of a standard Microservice Framework along with the convenience of a serverless runtime.

Using Host Callbacks

Calling a Host Callback is relatively straightforward for WASM functions. As outlined in the language guides, each WASM function must import a waPC compliant guest library. This guest library will allow users to access a HostCall() function for their language of choice.

The example below is an example of calling the Host Callback function in Go.

The HostCall() function takes three parameters. The first is the namespace which developers should always set to tarmac. The second is the capability requested, such as logger or kvstore. The third is the function to execute; for a kvstore capability, we may want to perform a get or a set.

This section of documentation outlines all of the various host-level capabilities Tarmac provides. Each unit will outline the capabilities, functions, and input/output data.

Functions

Function to Function calls

The Functions capability allows WASM functions to call other WASM functions. Unlike other callback capabilities, functions must register within the routes configuration within the tarmac.json configuration file.

Function

_, err := wapc.HostCall("tarmac", "function", "function-name", []byte("Input to Function"))

Interface Details

Namespace
Capability
Function
Input
Output

tarmac

function

Function Name

Input Data

Function Output Data

_, err := wapc.HostCall("tarmac", "logger", "debug", payload)

Multi-Function Services

Configure multi-function services as well as multi-service instances.

Configuring Multi-Function Services is a core capability of Tarmac. To do so, we will create a tarmac.json file that defines Functions and Routes to expose those functions.

By default, Tarmac looks within the /functions/ directory for a tarmac.json; however this can be overridden using the WASM_FUNCTION_CONFIG configuration parameter.

The tarmac.json file has a simple structure that consists of a single object with a services key. The services key defines each service and its corresponding functions and routes.

Configuration Options

Services

The services object contains one or more key-value pairs, with each key representing the name of a service.

Each service object should include the following properties:

  • name: The name of the service (required).

  • functions: An object containing the functions for the service (required).

  • routes: An array of objects defining the routes for the service (required).

Functions

The functions object contains one or more key-value pairs, with each key representing the name of a function.

Each function object should include the following properties:

  • filepath: The file path to the .wasm file containing the function code (required).

  • pool_size: The number of instances of the function to create (optional). Defaults to 100.

Routes

The "routes" property in the tarmac.json configuration file defines the endpoints (HTTP or scheduled task) of the service and maps them to their respective functions.

HTTP Routes

The routes array in the tarmac.json configuration file defines the HTTP endpoints for your service.

Each route object contains the following properties:

  • type (required): For HTTP routes, set this to http.

  • path (required): The URL path for the endpoint.

  • methods (required): An array of HTTP methods that the endpoint supports (i.e. GET

Here is an example of a route object that defines an HTTP endpoint that responds to GET requests on the root path and calls the default function:

You can define multiple HTTP routes in the routes array.

Scheduled Tasks

In addition to HTTP endpoints, Tarmac also supports scheduled tasks.

You can define a scheduled task route by adding a route object with the following properties to the routes array:

  • type (required): For Schedule Tasks, set to scheduled_task.

  • function (required): The function to call when the task is executed.

  • frequency (required): The frequency in seconds to execute the function.

Here is an example of a route object that defines a scheduled task that executes the default function every 15 seconds:

You can define multiple scheduled tasks in the routes array.

Init Functions

In addition to HTTP and scheduled task routes, Tarmac also supports init functions.

You can define an init function route by adding a route object with the following properties to the routes array:

  • type (required): For Init Functions, set to init.

  • function (required): The function to call when the service is initialized.

  • retries (optional): The number of times to retry the function if it fails. Defaults to 0.

Here is an example of a route object that defines an init function that executes the default function when the service is initialized:

You can define multiple init functions in the routes array. Functions will be executed before the server is fully started but after the WASM modules are loaded and callbacks are registered.

Functions

Tarmac supports the ability for Functions to call other Functions using the Function to Function route.

You can define a function route by adding a route object with the following properties to the route array.

  • type (required): For Function to Function routes, set to function.

  • function (required): The function to call when executed.

Here is an example of a route object that defines the "function1" function.

{
  "services": {
    "my-service": {
      "name": "my-service",
      "functions": {
        "function1": {
          "filepath": "/path/to/function1.wasm",
          "pool_size": 10
        },
        "function2": {
          "filepath": "/path/to/function2.wasm"
        }
      },
      "routes": [
        {
          "type": "http",
          "path": "/function1",
          "methods": ["GET"],
          "function": "function1"
        },
        {
          "type": "http",
          "path": "/function2",
          "methods": ["POST"],
          "function": "function2"
        }
      ]
    }
  }
}
,
POST
,
PUT
,
DELETE
).
  • function (required): The function to call when the endpoint receives requests.

  • frequency (optional): The frequency in seconds to retry the function if it fails. Exponential backoff is used. Defaults to 1.

    {
      "type": "http",
      "path": "/",
      "methods": ["GET"],
      "function": "default"
    }
    
    {
      "type": "scheduled_task",
      "function": "default",
      "frequency": 15
    }
    {
      "type": "init",
      "function": "default"
    }
    {
      "type": "function",
      "function": "function1"
    }

    Go

    Creating a WASM Function in Go.

    Tarmac leverages the Web Assembly System Interface (WASI), which is currently only supported by TinyGo. While TinyGo has many features, there are some limitations to its support.

    However, thanks to the Go SDK, writing Tarmac functions is quick and easy. This guide will walk users through creating a simple function using Go.

    Basic WASM function

    We will first need to begin with a new project folder creating a main.go file within it. This file will hold all of our application logic.

    Within our main.go file; we will need first to import the Tarmac Go SDK.

    Once we've imported the SDK, we will need to both create our Function and register it with the SDK. We will start by initializing the SDK and registering our Function, Handler().

    As Tarmac receives requests such as an HTTP POST request, the Handler() function will be called with the HTTP payload provided as the payload parameter.

    We can create our Function, which returns a simple "Howdie" message.

    Building the WASM Function

    Now that our function is ready, we must compile our Go code into a .wasm file. To do this, we will be using TinyGo.

    The first step above is using mkdir to create a functions directory, this is not required but will be helpful when running Tarmac in the next stage.

    After the functions directory is created, we are using the tinygo command to build our .wasm file. The inclusion of -target wasi is important as it directs TinyGo to compile the Go code using the Web Assembly System Interface (wasi) standard. This standard is useful for running Web Assembly on the server vs. on the browser.

    With this step complete, we have built our WASM function.

    Running the WASM Function

    We are now ready to run our WASM function via Tarmac. To make this process easier, we will be using Docker to execute Tarmac. It is not necessary to use Docker with Tarmac as it can run outside of Docker as well.

    In the above command, we are passing two environment variables to the container using the -e flag. These environment variables will tell Tarmac to use HTTP rather than HTTPS, which is the default. For additional configuration options, check out the documentation.

    With Tarmac now running, we can access our WASM function using any HTTP Client such as curl.

    Expanding beyond Hello World

    While the above Hello World example provides an excellent introduction to creating Go functions, it does not showcase the power of Tarmac.

    Tarmac provides integrations with many of the capabilities required to build today's modern platforms. These capabilities include Key:Value datastores such as Redis or Cassandra. The ability to create metrics for observability and log messages via a structured logger. Or even the ability to call HTTP end-points with an HTTP Client.

    These integrations are simple to call with the Go SDK; the below Function showcases several capabilities, such as calling a key:value cache and logging.

    Conclusion

    Developers can use this guide to get started with WASM functions and using Tarmac. Some of the information in this guide is subject to change as support for WASM in Go advances.

    Supported Languages

    What languages are known to work with Tarmac.

    Currently, Tarmac leverages the Web Assembly Procedure Call (waPC) to interact and run WASM Functions. As such, Tarmac is limited to languages that support both Web Assembly and the waPC protocol.

    The below table outlines languages that are fully supported.

    Language
    waPC Guest Library
    Caveats

    AssemblyScript

    Go

    Metrics

    Custom Metrics for WASM Functions

    The Metrics capability provides WASM function developers the ability to create user-defined metrics exposed as part of the Tarmac /metrics end-point. This capability supports the three predominant metrics types, Counters, Gauges, & Histograms.

    Counter

    The Counter function will give users the ability to create a custom counter metric. When called, this function will increment the counter by one.

    Interface Details

    Namespace
    Capability
    Function
    Input
    Output

    Example JSON

    This callback uses JSON messages as input and output to facilitate communications between WASM functions and the Tarmac host.

    MetricsCounter

    Gauge

    The Gauge function will give users the ability to create a custom gauge metric. When called, this function will either increment or decrement the gauge by one.

    Interface Details

    Namespace
    Capability
    Function
    Input
    Output

    Example JSON

    This callback uses JSON messages as input and output to facilitate communications between WASM functions and the Tarmac host.

    MetricsCounter

    Valid actions are inc (Increment) and dec (Decrement).

    Histogram

    The Histogram function will give users the ability to create a custom histogram metric. When called, this function will observe the provided value and summarize the metric results.

    Interface Details

    Namespace
    Capability
    Function
    Input
    Output

    Example JSON

    This callback uses JSON messages as input and output to facilitate communications between WASM functions and the Tarmac host.

    MetricsCounter

    _, err := wapc.HostCall("tarmac", "metrics", "counter", MetricsCounterJSON)

    https://github.com/wapc/wapc-guest-tinygo

    Rust

    https://github.com/wapc/wapc-guest-rust

    Swift

    https://github.com/wapc/wapc-guest-swift

    Zig

    https://github.com/wapc/wapc-guest-zig

    https://github.com/wapc/as-guest
    Configuration

    tarmac

    metrics

    counter

    MetricsCounter

    nil

    tarmac

    metrics

    gauge

    MetricsGauge

    nil

    tarmac

    metrics

    histogram

    MetricsHistogram

    nil

    package main
    
    import (
    	"github.com/tarmac-project/tarmac/pkg/sdk"
    )
    func main() {
    	// Initialize the Tarmac SDK
    	_, err := sdk.New(sdk.Config{Namespace: "test-service", Handler: Handler})
    	if err != nil {
    		return
    	}
    }
    func Handler(payload []byte) ([]byte, error) {
    	// Return a happy message
    	return []byte("Howdie"), nil
    }
    $ mkdir -p functions
    $ tinygo build -o functions/tarmac.wasm -target wasi main.go
    $ docker run -p 8080:8080 \
      -e "APP_ENABLE_TLS=false" -e "APP_LISTEN_ADDR=0.0.0.0:8080" \
      -v `pwd`./functions:/functions madflojo/tarmac
    $ curl -v --data "Tarmac Example" http://localhost:8080
    // Tac is a small, simple Go program that is an example WASM module for Tarmac. This program will accept a Tarmac
    // server request, log it, and echo back the payload in reverse.
    package main
    
    import (
    	"fmt"
    	"github.com/tarmac-project/tarmac/pkg/sdk"
    )
    
    var tarmac *sdk.Tarmac
    
    func main() {
    	var err error
    
    	// Initialize the Tarmac SDK
    	tarmac, err = sdk.New(sdk.Config{Handler: Handler})
    	if err != nil {
    		return
    	}
    }
    
    // Handler is the custom Tarmac Handler function that will receive a payload and
    // must return a payload along with a nil error.
    func Handler(payload []byte) ([]byte, error) {
    	var err error
    
    	// Log it
    	tarmac.Logger.Trace(fmt.Sprintf("Reversing Payload: %s", payload))
    
    	// Check Cache
    	key := string(payload)
    	rsp, err := tarmac.KV.Get(key)
    	if err != nil || len(payload) < 1 {
    		// Flip it and reverse
    		if len(payload) > 0 {
    			for i, n := 0, len(payload)-1; i < n; i, n = i+1, n-1 {
    				payload[i], payload[n] = payload[n], payload[i]
    			}
    		}
    		rsp = payload
    
    		// Store in Cache
    		err = tarmac.KV.Set(key, payload)
    		if err != nil {
    			tarmac.Logger.Error(fmt.Sprintf("Unable to cache reversed payload: %s", err))
    			return rsp, nil
    		}
    	}
    
    	// Return the payload
    	return rsp, nil
    }
    {
    	"name": "custom_metric_name"
    }
    _, err := wapc.HostCall("tarmac", "metrics", "gauge", MetricsGaugeJSON)
    {
    	"name": "custom_metric_name",
    	"action": "inc"
    }
    _, err := wapc.HostCall("tarmac", "metrics", "histogram", MetricsHistogramJSON)
    {
    	"name": "custom_metric_name",
    	"value": 0.0001
    }

    HTTP Client

    Make HTTP requests with a simple HTTP client

    The HTTPClient capability provides WASM function developers to perform HTTP client requests to remote or local HTTP servers. While a simplistic client, Tarmac supports multiple HTTP requests, setting headers, and custom payloads.

    Security and Resource Management

    To prevent DoS attacks and excessive memory usage, HTTP response bodies are limited to a configurable maximum size. By default, responses are limited to 10MB. This limit can be configured service-wide using the http_client_max_response_body_size configuration parameter (see Configuration for details).

    Call

    The Call function provides users with the ability to make HTTP client requests to the specified URL. The body key within the request and response JSON will be base64 encoded to avoid conflicts.

    Interface Details

    Namespace
    Capability
    Function
    Input
    Output

    Example JSON

    This callback uses JSON messages as input and output to facilitate communications between WASM functions and the Tarmac host.

    HTTPClient

    HTTPClientResponse

    The Status structure within the response JSON denotes the success of the database call. The status code value follows the HTTP status code standards, with anything higher than 399 is an error.

    Note: Tarmac will provide a 200 status code if the HTTP request was successfully made, check the code value to validate the HTTP server return code.

    Response Body Size Limiting

    HTTP responses that exceed the configured maximum body size will be truncated to the limit. If the response body is larger than the configured limit, only the first bytes up to the limit will be included in the response. This behavior applies to both successful and error responses to ensure consistent resource management.

    Key:Value Datastore

    Store and Retrieve data from a Key:Value datastore

    The Key:Value Store capability provides WASM function developers the ability to store and retrieve data from Key:Value datastores. At the moment, Tarmac supports multiple Key:Value stores which can be enabled/disabled in the host configuration settings.

    Get

    The Get function provides users with the ability to fetch data using the specified key. To avoid conflicts, the data key within the response, JSON, will be base64 encoded.

    Logger

    Standard logging capabilities

    The Logger capability provides WASM functions with the ability to log arbitrary data. Much like a traditional logger framework, this capability offers multiple log levels.

    By default Debug and Trace level logs are disabled. To enable these log levels to consult the configuration options for Tarmac.

    Error

    Critical errors within the system.

    tarmac

    httpclient

    call

    HTTPClient

    HTTPClientResponse

    Interface Details
    Namespace
    Capability
    Function
    Input
    Output

    tarmac

    kvstore

    get

    KVStoreGet

    KVStoreGetResponse

    Example JSON

    This callback uses JSON messages as input and output to facilitate communications between WASM functions and the Tarmac host.

    KVStoreGet

    KVStoreGetResponse

    The Status structure within the response JSON denotes the success of the database call. The status code value follows the HTTP status code standards, with anything higher than 399 is an error.

    Set

    The Set function provides users with the ability to store data within the Key:Value datastore. The data key within the request JSON must be base64 encoded.

    Interface Details

    Namespace
    Capability
    Function
    Input
    Output

    tarmac

    kvstore

    set

    KVStoreSet

    KVStoreSetResponse

    Example JSON

    This callback uses JSON messages as input and output to facilitate communications between WASM functions and the Tarmac host.

    KVStoreSet

    KVStoreSetResponse

    The Status structure within the response JSON denotes the success of the database call. The status code value follows the HTTP status code standards, with anything higher than 399 is an error.

    Delete

    The Delete function provides users with the ability to delete data stored within the Key:Value datastore.

    Interface Details

    Namespace
    Capability
    Function
    Input
    Output

    tarmac

    kvstore

    delete

    KVStoreDelete

    KVStoreDeleteResponse

    Example JSON

    This callback uses JSON messages as input and output to facilitate communications between WASM functions and the Tarmac host.

    KVStoreDelete

    KVStoreDeleteResponse

    The Status structure within the response JSON denotes the success of the database call. The status code value follows the HTTP status code standards, with anything higher than 399 is an error.

    Keys

    The Keys function provides users with the ability to fetch a list of all keys available within the Key:Value datastore.

    Note: This callback requires no input JSON. However, the callback function will require users to provide a byte slice.

    Interface Details

    Namespace
    Capability
    Function
    Input
    Output

    tarmac

    kvstore

    keys

    EmptyByteSlice

    KVStoreKeysResponse

    Example JSON

    This callback uses JSON messages as input and output to facilitate communications between WASM functions and the Tarmac host.

    KVStoreKeysResponse

    The Status structure within the response JSON denotes the success of the database call. The status code value follows the HTTP status code standards, with anything higher than 399 is an error.

    Interface Details
    Namespace
    Capability
    Function
    Input
    Output

    tarmac

    logger

    error

    Log Message

    nil

    Warn

    Non-critical errors within the system.

    Interface Details

    Namespace
    Capability
    Function
    Input
    Output

    tarmac

    logger

    warn

    Log Message

    nil

    Info

    Informational logs.

    Interface Details

    Namespace
    Capability
    Function
    Input
    Output

    tarmac

    logger

    info

    Log Message

    nil

    Debug

    Request level errors & informational logs. Disabled by default, calls to Debug logging are ignored unless debug is enabled for the Tarmac host.

    Interface Details

    Namespace
    Capability
    Function
    Input
    Output

    tarmac

    logger

    debug

    Log Message

    nil

    Trace

    Low-level details of execution. Disabled by default, calls to Trace logging are ignored unless trace is enabled for the Tarmac host.

    Interface Details

    Namespace
    Capability
    Function
    Input
    Output

    tarmac

    logger

    trace

    Log Message

    nil

    _, err := wapc.HostCall("tarmac", "httpclient", "call", HTTPClientJSON)
    {
    	"method": "POST",
    	"headers": {
    		"content-type": "application/json"
    	},
    	"insecure": true,
    	"url": "http://example.com",
    	"body": "ewoJIm1lIjogewoJCSJ0ZWFwb3QiOiB0cnVlCgl9Cn0="
    }
    {
    	"code": 400,
    	"headers": {
    		"key": "value"
    	},
    	"body": "dGlwIG1lIG92ZXIgYW5kIHBvdXIgbWUgb3V0",
    	"status": {
    		"code": 200,
    		"status": "OK"
    	}
    }
    _, err := wapc.HostCall("tarmac", "kvstore", "get", KVStoreGetJSON)
    {
    	"key": "myKey"
    }
    {
    	"data": "VHdlZXQgYWJvdXQgVGFybWFjIGlmIHlvdSB0aGluayBpdCdzIGF3ZXNvbWUu",
    	"status": {
    		"code": 200,
    		"status": "OK"
    	}
    }
    _, err := wapc.HostCall("tarmac", "kvstore", "set", KVStoreSetJSON)
    {
      "data": "VHdlZXQgYWJvdXQgVGFybWFjIGlmIHlvdSB0aGluayBpdCdzIGF3ZXNvbWUu",
      "key": "myKey"
    }
    {
      "status": {
        "code": 200,
        "status": "OK"
      }
    }
    _, err := wapc.HostCall("tarmac", "kvstore", "delete", KVStoreDeleteJSON)
    {
      "key": "myKey"
    }
    {
      "status": {
        "code": 200,
        "status": "OK"
      }
    }
    _, err := wapc.HostCall("tarmac", "kvstore", "keys", []byte())
    {
    	"keys": ["key1", "key2"],
    	"status": {
    		"code": 200,
    		"status": "OK"
    	}
    }
    _, err := wapc.HostCall("tarmac", "logger", "error", []byte("This is the data that should be logged"))
    _, err := wapc.HostCall("tarmac", "logger", "warn", []byte("This is the data that should be logged"))
    _, err := wapc.HostCall("tarmac", "logger", "info", []byte("This is the data that should be logged"))
    _, err := wapc.HostCall("tarmac", "logger", "debug", []byte("This is the data that should be logged"))
    _, err := wapc.HostCall("tarmac", "logger", "trace", []byte("This is the data that should be logged"))
    PkgGoDev
    Documentation

    BoltDB

    Configuring Tarmac with BoltDB

    This page contains BoltDB specific configuration to utilize BoltDB with Tarmac.

    Tarmac supports multiple configuration sources such as Environment Variables, JSON files, or using HashiCorp Consul. All of these configuration options can also exist together to provide both static and dynamic configurations.

    When using Environment Variables, all configurations are prefixed with APP_. The list below will show both Environment and Consul/JSON format for configuration.

    Environment Variable
    Consul/JSON
    Type
    Description

    Consul Format

    When using Consul the consul_keys_prefix should be the path to a key with a JSON string as the value. For example, a key of tarmac/config will have a value of {"from_consul":true}.

    Cassandra

    Configuring Tarmac with Cassandra

    This page contains Cassandra specific configuration to utilize Cassandra with Tarmac.

    Tarmac supports multiple configuration sources such as Environment Variables, JSON files, or using HashiCorp Consul. All of these configuration options can also exist together to provide both static and dynamic configurations.

    When using Environment Variables, all configurations are prefixed with APP_. The list below will show both Environment and Consul/JSON format for configuration.

    Environment Variable
    Consul/JSON
    Type
    Description

    APP_BOLTDB_FILENAME

    boltdb_filename

    string

    The full path and filename of the BoltDB file. If the file does not exist, it will be created.

    APP_BOLTDB_BUCKET

    boltdb_bucket

    string

    The name of the BoltDB bucket to use. If the bucket does not exist, it will be created.

    APP_BOLTDB_PERMISSIONS

    boltdb_permissions

    int

    The permissions to use when creating the BoltDB file. This is an octal value.

    APP_BOLTDB_TIMEOUT

    boltdb_timeout

    int

    The timeout in seconds to wait for BoltDB to open.

    cassandra_hosts

    []string

    Cassandra node addresses

    APP_CASSANDRA_PORT

    cassandra_port

    int

    Cassandra node port

    APP_CASSANDRA_KEYSPACE

    cassandra_keyspace

    string

    Cassandra Keyspace name

    APP_CASSANDRA_CONSISTENCY

    cassandra_consistency

    string

    Desired Consistency (Default: Quorum)

    APP_CASSANDRA_REPL_STRATEGY

    cassandra_repl_strategy

    string

    Replication Strategy for Cluster (Default: SimpleStrategy)

    APP_CASSANDRA_REPLICAS

    cassandra_replicas

    int

    Default number of replicas for data (Default: 1)

    APP_CASSANDRA_USER

    cassandra_user

    string

    Username to authenticate with

    APP_CASSANDRA_PASSWORD

    cassandra_password

    string

    Password to authenticate with

    APP_CASSANDRA_HOSTNAME_VERIFY

    cassandra_hostname_verify

    bool

    Enable/Disable hostname verification for TLS

    Consul Format

    When using Consul the consul_keys_prefix should be the path to a key with a JSON string as the value. For example, a key of tarmac/config will have a value of {"from_consul":true}.

    APP_CASSANDRA_HOSTS

    Key:Value

    Selecting a KV Store

    Tarmac has support for multiple Key:Value datastore storage systems. These datastores can change with basic configuration options within Tarmac. As a WASM Function developer, you do not need to know the underlying datastore when writing the function. Callbacks for accessing the Key:Value datastore are generic across all supported datastores.

    To start using a Key:Value datastore, set the enable_kvstore configuration to true and specify which supported platform to use with the kvstore_type variable.

    The below table outlines the different available options.

    Datastore
    Type option
    Description
    Useful for

    For more detailed configuration options, check out the documentation.

    SQL Datastore

    Store and Retrieve data from a SQL datastore

    The SQL Datastore capability provides WASM function developers the ability to store and retrieve data from SQL datastores. At the moment, Tarmac supports multiple SQL stores which can be enabled/disabled in the host configuration settings.

    Query

    The Query function provides users with the ability to execute custom SQL queries against the database service. The returned data is in JSON format and base64 encoded to avoid format conflicts.

    Interface Details

    Namespace
    Capability
    Function
    Input
    Output

    Example JSON

    This callback uses JSON messages as input and output to facilitate communications between WASM functions and the Tarmac host.

    SQLQuery

    To avoid format and data conflicts the query itself must be base64 encoded.

    SQLQueryResponse

    To avoid format and data conflicts the data returned is base64 encoded.

    The Status structure within the response JSON denotes the success of the database call. The status code value follows the HTTP status code standards, with anything higher than 399 is an error.

    _, err := wapc.HostCall("tarmac", "sql", "query", `SQLQueryJSON`)

    Datastores

    In-Memory

    in-memory

    In-Memory key/value store

    Testing, Development, Non-Persistent Caching

    BoltDB

    boltdb

    BoltDB Embedded key/value store

    Strong Consistency, Persistent Storage

    Redis

    redis

    Redis including Sentinel and Enterprise capabilities

    Strong Consistency, Fast Reads and Writes, Non-Persistent storage

    Cassandra

    cassandra

    Cassandra including TLS connectivity

    Configuration

    Eventual Consistency, Persistent Storage, Large sets of data

    tarmac

    sql

    query

    SQLQuery

    SQLQueryResponse

    {
    	"query": "c2VsZWN0ICogZnJvbSBleGFtcGxlOw=="
    }
    {
    	"data": "W3siaWQiOjEsIm5hbWUiOiJKb2huIFNtaXRoIn0seyJpZCI6MSwibmFtZSI6IkphbmUgU21pdGgifV0=",
    	"status": {
    		"code": 200,
    		"status": "OK"
    	}
    }

    SQL

    Selecting a SQL Datastore

    Tarmac has support for multiple SQL datastore storage systems. These datastores can change with basic configuration options within Tarmac. As a WASM Function developer, you do not need to know the underlying datastore when writing the function. Callbacks for accessing the SQL datastore are generic across all supported datastores.

    To start using a SQL datastore, set the enable_sql configuration to true and specify which supported platform to use with the sqlstore_type variable.

    The below table outlines the different available options.

    Datastore
    Type option
    Description
    Useful for

    For more detailed configuration options, check out the documentation.

    Redis

    Configuring Tarmac with Redis

    This page contains Redis specific configuration to utilize Redis with Tarmac.

    Tarmac supports multiple configuration sources such as Environment Variables, JSON files, or using HashiCorp Consul. All of these configuration options can also exist together to provide both static and dynamic configurations.

    When using Environment Variables, all configurations are prefixed with APP_. The list below will show both Environment and Consul/JSON format for configuration.

    Environment Variable
    Consul/JSON
    Type
    Description

    Monitoring

    Monitoring Tarmac with Prometheus Metrics

    Tarmac exposes several metrics to facilitate monitoring services. Metrics are available via the /metrics end-point in the Prometheus format.

    These metrics include internal Tarmac system metrics such as the number of goroutines, memory utilization, and WASM function-specific metrics such as counters for Callbacks and WASM function execution time.

    Some valuable metrics to monitor are in the below table.

    Metric Name
    Metric Type
    Description

    MySQL

    mysql

    MySQL a widely used, open-source RDBMS

    Strong Consistency, Well Known, Persistent Storage, Scales Well

    PostgreSQL

    postgres

    PostgreSQL a widely used, open-source RDBMS

    Strong Consistency, Well Known, Persistent Storage, Scales Well

    Configuration

    Summary of HTTP Server requests

    scheduled_tasks

    Summary

    Summary of user defined scheduled task WASM function executions

    wasm_callbacks

    Summary

    Summary of Tarmac callback function executions

    wasm_functions

    Summary

    Summary of wasm function executions

    These metrics do not need to be enabled and are "on by default".

    http_server

    Summary

    redis_server

    string

    Redis server address

    APP_REDIS_DATABASE

    redis_database

    int

    Redis Database (default: 0)

    APP_REDIS_PASSWORD

    redis_password

    string

    Redis password

    APP_REDIS_SENTINEL_SERVERS

    redis_sentinel_servers

    []string

    Redis Sentinel Server Addresses

    APP_REDIS_SENTINEL_MASTER

    redis_sentinel_master

    string

    Redis Sentinel Master Instance Name

    APP_REDIS_CONNECT_TIMEOUT

    redis_connect_timeout

    int

    Redis Connection Timeout in seconds

    APP_REDIS_HOSTNAME_VERIFY

    redis_hostname_verify

    bool

    Skip hostname verification for TLS

    APP_REDIS_KEEPALIVE

    redis_keepalive

    int

    TCP Keepalive Interval in seconds (Default: 300)

    APP_REDIS_MAX_ACTIVE

    redis_max_active

    int

    Max Active Connections

    APP_REDIS_READ_TIMEOUT

    redis_read_timeout

    int

    Read timeout in seconds

    APP_REDIS_WRITE_TIMEOUT

    redis_write_timeout

    int

    Write timeout in seconds

    Consul Format

    When using Consul the consul_keys_prefix should be the path to a key with a JSON string as the value. For example, a key of tarmac/config will have a value of {"from_consul":true}.

    APP_REDIS_SERVER

    Configuration

    Configuring Tarmac

    Tarmac supports multiple configuration sources such as Environment Variables, JSON files, or using HashiCorp Consul. All of these configuration options can also exist together to provide both static and dynamic configurations.

    When using Environment Variables, all configurations are prefixed with APP_. The list below will show both Environment and Consul/JSON format for configuration.

    Environment Variable
    Consul/JSON
    Type
    Description

    APP_ENABLE_TLS

    enable_tls

    Consul Format

    When using Consul the consul_keys_prefix should be the path to a key with a JSON string as the value. For example, a key of tarmac/config will have a value of {"from_consul":true}.

    bool

    Enable the HTTPS Listener (default: True)

    APP_LISTEN_ADDR

    listen_addr

    string

    Define the HTTP/HTTPS Listener address (default: 0.0.0.0:8443)

    APP_CONFIG_WATCH_INTERVAL

    config_watch_interval

    int

    Frequency in seconds which Consul configuration will be refreshed (default: 15)

    APP_USE_CONSUL

    use_consul

    bool

    Enable Consul based configuration (default: False)

    APP_CONSUL_ADDR

    consul_addr

    string

    Consul address (i.e. consul.example.com:8500)

    APP_CONSUL_KEYS_PREFIX

    consul_keys_prefix

    string

    Key path for app specific consul configuration

    from_consul

    bool

    Indicator to reflect whether Consul config was loaded

    APP_DEBUG

    debug

    bool

    Enable debug logging

    APP_TRACE

    trace

    bool

    Enable trace logging

    APP_DISABLE_LOGGING

    disable_logging

    bool

    Disable all logging

    APP_TEXT_LOG_FORMAT

    text_log_format

    bool

    Use text format for logs instead of JSON (default: False)

    APP_CERT_FILE

    cert_file

    string

    Certificate File Path (i.e. /some/path/cert.crt)

    APP_KEY_FILE

    key_file

    string

    Key File Path (i.e. /some/path/cert.key)

    APP_CA_FILE

    ca_file

    string

    Certificate Authority Bundle File Path (i.e /some/path/ca.pem). When defined, enables mutual-TLS authentication

    APP_IGNORE_CLIENT_CERT

    ignore_client_cert

    string

    When defined will disable Client Cert validation for m-TLS authentication

    APP_WASM_FUNCTION

    wasm_function

    string

    Path and Filename of the WASM Function to execute (Default: /functions/tarmac.wasm)

    APP_WASM_FUNCTION_CONFIG

    wasm_function_config

    string

    Path to Service configuration for multi-function services (Default: /functions/tarmac.json)

    APP_WASM_POOL_SIZE

    wasm_pool_size

    int

    Number of WASM function instances to create (Default: 100). Only applicable when wasm_function is used.

    APP_ENABLE_PPROF

    enable_pprof

    bool

    Enable PProf Collection HTTP end-points

    APP_ENABLE_KVSTORE

    enable_kvstore

    bool

    Enable the KV Store

    APP_KVSTORE_TYPE

    kvstore_type

    string

    Select KV Store to use (Options: redis, cassandra, boltdb, in-memory, internal)

    APP_ENABLE_SQL

    enable_sql

    bool

    Enable the SQL Store

    APP_SQL_TYPE

    sql_type

    string

    Select SQL Store to use (Options: postgres, mysql)

    APP_RUN_MODE

    run_mode

    string

    Select the run mode for Tarmac (Options: daemon, job). Default: daemon. The job option will cause Tarmac to exit after init functions are executed.

    APP_ENABLE_MAINTENANCE_MODE

    enable_maintenance_mode

    bool

    Enable Maintenance Mode. When enabled, Tarmac will return a 503 for requests to /ready allowing the service to go into "maintenance mode".

    APP_HTTP_CLIENT_MAX_RESPONSE_BODY_SIZE

    http_client_max_response_body_size

    int

    Maximum size in bytes for HTTP response bodies from client requests (default: 10485760 - 10MB). Prevents DoS attacks and excessive memory usage.

    Go Report Card

    Logging

    Logging options of Tarmac

    Tarmac uses structured logging to provide detailed information about system operations. By default, logs are output in JSON format, which is ideal for automated log processing and analysis tools.

    Log Format

    Administrators can control the format of Tarmac's logs:

    • JSON Format (Default): Structured logging that's machine-readable and easily parsed by log aggregation tools

    • Text Format: Human-readable plain text format that's easier to read in the console or log files

    To use text format instead of JSON, set the text_log_format configuration option to true.

    Controlling Log Levels

    Administrators can control Tarmac's logging levels dynamically while using a distributed configuration service such as Consul. As a WASM Function developer, you can select which logging level you wish your log callbacks to use.

    As an Administrator, you can choose to enable or disable dynamically certain log levels such as Debug or Trace. To do this, modify the debug and trace configuration options within Consul.

    It is also possible to disable all logging by changing the disable_logging configuration option to true.

    For more information on connecting Tarmac with Consul, consult our documentation.

    Troubleshooting Performance

    Profiling a running Tarmac instance

    Troubleshooting Performance Issues or Memory leaks within running services can be a complex task. Luckily, Tarmac uses the native Go tooling to create profiling snapshots of a running instance.

    PProf is a Go tool for capturing and visualizing profiling data. Tarmac uses the net/http/pprof package to make PProf available via HTTP end-points.

    By default, all PProf end-points are disabled, preventing unauthorized use of PProf (which itself can affect performance). To enable PProf, set the Configuration value of enable_pprof to true. Using a distributed configuration service such as Consul, users can change this value live without restarting the application instance.

    Follow the Configuration guide for more details on configuring Tarmac.

    Once enabled, users can use the following end-points to capture profiling data.

    URI
    Description

    More information about PProf can be found via the .

    Configuration

    /debug/pprof/mutex

    Stack traces of holders of contended mutexes

    /debug/pprof/profile

    CPU Profile

    /debug/pprof/threadcreate

    Stack traces that led to the creation of new OS threads

    /debug/pprof/trace

    A trace of execution of the current program

    /debug/pprof

    PProf Index linking to individual profiling pages

    /debug/pprof/allocs

    A sampling of all past memory allocations

    /debug/pprof/block

    Stack traces that led to blocking on synchronization primitives

    /debug/pprof/cmdline

    The command line invocation of the current program

    /debug/pprof/goroutine

    Stack traces of all current goroutines

    /debug/pprof/heap

    official documentation

    A sampling of memory allocations of live objects