Skip to content

Commit

Permalink
Merge pull request #65 from tarmac-project/initfunc
Browse files Browse the repository at this point in the history
Adding support for Init Functions
  • Loading branch information
madflojo authored Oct 1, 2023
2 parents fc714c7 + 2edd8f8 commit 673fb94
Show file tree
Hide file tree
Showing 11 changed files with 130 additions and 1 deletion.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ build: build-testdata

build-testdata:
$(MAKE) -C testdata/default build
$(MAKE) -C testdata/fail build
$(MAKE) -C testdata/kv build
$(MAKE) -C testdata/sql build
$(MAKE) -C testdata/logger build
Expand Down
20 changes: 20 additions & 0 deletions docs/wasm-functions/multi-function-services.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,26 @@ Here is an example of a route object that defines a scheduled task that executes

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.

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

```json
{
"type": "init",
"function": "default"
}
```

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.
Expand Down
19 changes: 18 additions & 1 deletion pkg/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,14 @@ func (srv *Server) Run() error {
// Register Routes
srv.log.Infof("Registering Routes from Service %s", svcName)
funcRoutes := make(map[string]string)
initRoutes := []string{}
for _, r := range svcCfg.Routes {
// Copy init functions for later execution
if r.Type == "init" {
initRoutes = append(initRoutes, r.Function)
}

// Register HTTP based functions with the HTTP router
if r.Type == "http" {
for _, m := range r.Methods {
key := fmt.Sprintf("%s:%s:%s", r.Type, m, r.Path)
Expand All @@ -464,6 +471,7 @@ func (srv *Server) Run() error {
}
}

// Schedule tasks for scheduled functions
if r.Type == "scheduled_task" {
srv.log.Infof("Scheduling custom task for function %s with interval of %d", r.Function, r.Frequency)
id, err := srv.scheduler.Add(&tasks.Task{
Expand All @@ -488,15 +496,24 @@ func (srv *Server) Run() error {
defer srv.scheduler.Del(id)
}

// Setup callbacks for function to function calls
if r.Type == "function" {
srv.log.Infof("Registering Function to Function callback for %s", r.Function)
router.RegisterCallback("function", r.Function, func(b []byte) ([]byte, error) {
return srv.runWASM(r.Function, "handler", b)
})
}
}
}

// Execute init functions
for _, f := range initRoutes {
srv.log.Infof("Executing Init Function %s", f)
_, err := srv.runWASM(f, "handler", []byte(""))
if err != nil {
return fmt.Errorf("error executing init function %s - %s", f, err)
}
}
}
}

// Register Metrics Handler
Expand Down
9 changes: 9 additions & 0 deletions pkg/app/app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,15 @@ func TestBadConfigs(t *testing.T) {
v.Set("wasm_function", "something-that-does-not-exist")
cfgs["invalid WASM path"] = v

// Failing init function
v = viper.New()
v.Set("enable_tls", false)
v.Set("listen_addr", "0.0.0.0:8443")
v.Set("disable_logging", true)
v.Set("enable_kvstore", false)
v.Set("wasm_function_config", "/testdata/tarmac-fail.json")
cfgs["failing init function"] = v

// Loop through bad configs, creating sub-tests as we go
for k, v := range cfgs {
t.Run("Testing "+k, func(t *testing.T) {
Expand Down
10 changes: 10 additions & 0 deletions testdata/fail/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
## Makefile for Go example for Tarmac WASM functions

build:
## Run TinyGo build via Docker because its easier
docker run --rm -v `pwd`:/build -w /build tinygo/tinygo:0.25.0 tinygo build -o /build/tarmac.wasm -target wasi /build/main.go

docker-compose:
docker compose up

run: build docker-compose
12 changes: 12 additions & 0 deletions testdata/fail/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
version: '3.8'
services:
tarmac-example:
image: madflojo/tarmac
ports:
- 80:8080
environment:
- "APP_ENABLE_TLS=false"
- "APP_LISTEN_ADDR=0.0.0.0:8080"
- "APP_DEBUG=true"
volumes:
- "./:/functions"
10 changes: 10 additions & 0 deletions testdata/fail/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module github.com/tarmac-project/tarmac/testdata/fail

go 1.21

require github.com/tarmac-project/tarmac/pkg/sdk v0.5.0

require (
github.com/valyala/fastjson v1.6.4 // indirect
github.com/wapc/wapc-guest-tinygo v0.3.3 // indirect
)
8 changes: 8 additions & 0 deletions testdata/fail/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
github.com/pquerna/ffjson v0.0.0-20190930134022-aa0246cd15f7 h1:xoIK0ctDddBMnc74udxJYBqlo9Ylnsp1waqjLsnef20=
github.com/pquerna/ffjson v0.0.0-20190930134022-aa0246cd15f7/go.mod h1:YARuvh7BUWHNhzDq2OM5tzR2RiCcN2D7sapiKyCel/M=
github.com/tarmac-project/tarmac/pkg/sdk v0.5.0 h1:QKsEf6SXTYrJM9/B4cNoM4RS3/rzuViJaiutEcdSRZQ=
github.com/tarmac-project/tarmac/pkg/sdk v0.5.0/go.mod h1:UTKYV0QFdkJDgV2sJcnuCujVy49MCd8bgi2JmwviJ6E=
github.com/valyala/fastjson v1.6.4 h1:uAUNq9Z6ymTgGhcm0UynUAB6tlbakBrz6CQFax3BXVQ=
github.com/valyala/fastjson v1.6.4/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY=
github.com/wapc/wapc-guest-tinygo v0.3.3 h1:jLebiwjVSHLGnS+BRabQ6+XOV7oihVWAc05Hf1SbeR0=
github.com/wapc/wapc-guest-tinygo v0.3.3/go.mod h1:mzM3CnsdSYktfPkaBdZ8v88ZlfUDEy5Jh5XBOV3fYcw=
20 changes: 20 additions & 0 deletions testdata/fail/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// This program is a test program used to facilitate unit testing with Tarmac.
package main

import (
"fmt"
"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(""), fmt.Errorf("This is a test error")
}
18 changes: 18 additions & 0 deletions testdata/tarmac-fail.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"services": {
"test-service": {
"name": "test-service",
"functions": {
"fail": {
"filepath": "/testdata/fail/tarmac.wasm"
}
},
"routes": [
{
"type": "init",
"function": "fail"
}
]
}
}
}
4 changes: 4 additions & 0 deletions testdata/tarmac.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@
}
},
"routes": [
{
"type": "init",
"function": "default"
},
{
"type": "http",
"path": "/",
Expand Down

0 comments on commit 673fb94

Please sign in to comment.