Giter Site home page Giter Site logo

tarmac-project / tarmac Goto Github PK

View Code? Open in Web Editor NEW
308.0 8.0 14.0 6.74 MB

Write as Functions, Deploy as a Monolith or Microservice with WebAssembly

Home Page: https://tarmac.gitbook.io/tarmac-framework/

License: Apache License 2.0

Dockerfile 0.45% Makefile 1.60% Go 97.48% Shell 0.20% Rust 0.27%
wasm microservice-framework golang functions-as-a-service serverless wasi hacktoberfest

tarmac's Introduction

Tarmac

PkgGoDev Documentation Build Status Go Report Card codecov

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.

// 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
}

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.

$ cd example/tac/go
$ make build

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

$ 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

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

$ curl -v --data "Tarmac Example" http://localhost:8080

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 developer guides.

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.

{
  "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"
        }
      ]
    }
  }
}

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).

{
  "type": "scheduled_task",
  "function": "function1",
  "frequency": 10
}

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.

Tarmac Architecture

Language waPC Client Tarmac SDK
AssemblyScript
Go
Rust
Swift
Zig

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.

tarmac's People

Contributors

codefromthecrypt avatar colineberhardt avatar dependabot[bot] avatar madflojo avatar odonnellryan32 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tarmac's Issues

Auth - authz

As far as I can see there is not any auth or authz in tarmac.

i generally use NATS for rerouting events into tarmac . Nats just wants a jwt to control Auth and Authz.
But even without NATS , Tarnac needs to assert who can do what.

https://github.com/pocketbase/pocketbase looks like a nice solution to this.
.Or at least to use as one way to add auth / authz. It’s probable that others might want a different solution and that’s why jwt is loose coupled.

the cool thing about pocketbaae is that it’s real time and simple.

have a look

GGO free wasm runner

Wazero is faster than the others due to less overhead

https://wazero.io/

It can run within envoy or alone
Config can be file based or off envoy.

It can also run wasi and wasm compiled golang .

Add ARM support

Hi! I tried to use Tarmac but had some issues due to the lack of ARM support in the official docker image. I noticed you're already using QEMU and buildx as steps in the pipeline, so I believe just a platforms: linux/amd64,linux/arm64 in the push-action could add this?

Multiple Init Functions and Scheduled Functions not working

When multiple init functions are defined, or scheduled tasks are defined within the configuration file during execution, only the last function defined will be executed. This appears to be due to a scoping issue with the closures and the for loop they are defined within.

WASI Module not instantiated error when running example

Running on WSL2 Ubuntu
Docker version 20.10.14, build a224086

The source was cloned and the example build instructions were followed

$ cd example/tac/go
$ make build
make build
mkdir -p functions
## Run TinyGo build via Docker because waPC requires a <0.18.0 version of TinyGo to work right
docker run -v `pwd`/:/build -w /build tinygo/tinygo:0.17.0 tinygo build -o /build/functions/tarmac.wasm -target wasi /build/main.go
go: downloading github.com/wapc/wapc-guest-tinygo v0.3.0

The tarmac wasm file is generated after running the build command:

$ ls -l functions/
total 220
-rwxr-xr-x 1 root root 221650 Jul 18 11:21 tarmac.wasm

Running the tarmac container:

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

time="2022-07-18T15:00:33Z" level=warning msg="No Config file found, loaded config from Environment - Default path ./conf"
time="2022-07-18T15:00:33Z" level=info msg="KV Store not configured, skipping"
time="2022-07-18T15:00:33Z" level=info msg="SQL DB not configured, skipping"
time="2022-07-18T15:00:33Z" level=fatal msg="Service stopped - unable to create module pool for wasm file /functions/tarmac.wasm - module[wasi_unstable] not instantiated"

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.