Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
_, err := wapc.HostCall("tarmac", "logger", "debug", payload)main.rsfn main() {}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:8080What languages are known to work with Tarmac.
methodsGETPOSTPUTDELETEfrequency (required): The frequency in seconds to execute the 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"
}
]
}
}
}{
"type": "http",
"path": "/",
"methods": ["GET"],
"function": "default"
}
{
"type": "scheduled_task",
"function": "default",
"frequency": 15
}{
"type": "init",
"function": "default"
}{
"type": "function",
"function": "function1"
}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
}
Custom Metrics for WASM Functions
Store and Retrieve data from a Key:Value datastore
Standard logging capabilities
Configuring Tarmac with Cassandra
// 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_, err := wapc.HostCall("tarmac", "metrics", "counter", MetricsCounterJSON)_, err := wapc.HostCall("tarmac", "kvstore", "get", KVStoreGetJSON)_, err := wapc.HostCall("tarmac", "logger", "error", []byte("This is the data that should be logged"))_, err := wapc.HostCall("tarmac", "sql", "query", `SQLQueryJSON`){
"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
}{
"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", "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")){
"query": "c2VsZWN0ICogZnJvbSBleGFtcGxlOw=="
}{
"data": "W3siaWQiOjEsIm5hbWUiOiJKb2huIFNtaXRoIn0seyJpZCI6MSwibmFtZSI6IkphbmUgU21pdGgifV0=",
"status": {
"code": 200,
"status": "OK"
}
}_, 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"
}
}Selecting a KV Store
Selecting a SQL Datastore
Profiling a running Tarmac instance




Monitoring Tarmac with Prometheus Metrics