Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor TinyGo API into separate packages #183

Merged
merged 6 commits into from Dec 14, 2021
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/sanity.yml
Expand Up @@ -25,7 +25,7 @@ jobs:
run: |
gh repo clone suborbital/subo
cd subo
gh pr checkout 120
gh pr checkout 130
make subo
cd ../
rm -rf subo
Expand All @@ -45,9 +45,9 @@ jobs:
- name: Run test
run: |
export GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }}
go test -v ./...
make test

- name: Run test with Wasmtime
run: |
export GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }}
go test -v --tags wasmtime ./...
make test/multi
2 changes: 1 addition & 1 deletion Makefile
Expand Up @@ -29,4 +29,4 @@ npm/publish:
deps:
go get -u -d ./...

.PHONY: test testdata crate/check crate/publish deps
.PHONY: test testdata crate/check crate/publish deps
13 changes: 13 additions & 0 deletions api/tinygo/runnable/cache/cache.go
@@ -0,0 +1,13 @@
package cache

import (
"github.com/suborbital/reactr/api/tinygo/runnable/internal/ffi"
)

func Get(key string) ([]byte, error) {
return ffi.CacheGet(key)
}

func Set(key, val string, ttl int) {
ffi.CacheSet(key, val, ttl)
}
41 changes: 0 additions & 41 deletions api/tinygo/runnable/ffi.go

This file was deleted.

31 changes: 13 additions & 18 deletions api/tinygo/runnable/http.go → api/tinygo/runnable/http/http.go
@@ -1,44 +1,44 @@
//go:build tinygo.wasm

package runnable
package http

// #include <reactr.h>
import "C"
import (
"github.com/suborbital/reactr/api/tinygo/runnable/method"
"github.com/suborbital/reactr/api/tinygo/runnable/internal/ffi"

"github.com/suborbital/reactr/api/tinygo/runnable/http/method"
)

func GET(url string, headers map[string]string) ([]byte, error) {
return doRequest(method.GET, url, nil, headers)
return do(method.GET, url, nil, headers)
}

func HEAD(url string, headers map[string]string) ([]byte, error) {
return doRequest(method.HEAD, url, nil, headers)
return do(method.HEAD, url, nil, headers)
}

func OPTIONS(url string, headers map[string]string) ([]byte, error) {
return doRequest(method.OPTIONS, url, nil, headers)
return do(method.OPTIONS, url, nil, headers)
}

func POST(url string, body []byte, headers map[string]string) ([]byte, error) {
return doRequest(method.POST, url, body, headers)
return do(method.POST, url, body, headers)
}

func PUT(url string, body []byte, headers map[string]string) ([]byte, error) {
return doRequest(method.PUT, url, body, headers)
return do(method.PUT, url, body, headers)
}

func PATCH(url string, body []byte, headers map[string]string) ([]byte, error) {
return doRequest(method.PATCH, url, body, headers)
return do(method.PATCH, url, body, headers)
}

func DELETE(url string, headers map[string]string) ([]byte, error) {
return doRequest(method.DELETE, url, nil, headers)
return do(method.DELETE, url, nil, headers)
}

// Remark: The URL gets encoded with headers added on the end, seperated by ::
// eg. https://google.com/somepage::authorization:bearer qdouwrnvgoquwnrg::anotherheader:nicetomeetyou
func doRequest(method method.MethodType, url string, body []byte, headers map[string]string) ([]byte, error) {
func do(method method.MethodType, url string, body []byte, headers map[string]string) ([]byte, error) {
urlStr := url

if headers != nil {
Expand All @@ -48,12 +48,7 @@ func doRequest(method method.MethodType, url string, body []byte, headers map[st
}
}

urlPtr, urlSize := rawSlicePointer([]byte(urlStr))
bodyPtr, bodySize := rawSlicePointer(body)

size := C.fetch_url(int32(method), urlPtr, urlSize, bodyPtr, bodySize, ident())

return result(size)
return ffi.DoHTTPRequest(int32(method), urlStr, body, headers)
}

func renderHeaderString(headers map[string]string) string {
Expand Down
@@ -1,20 +1,20 @@
//go:build tinygo.wasm

package runnable
package ffi

// #include <reactr.h>
import "C"

func CacheGet(key string) ([]byte, error) {
ptr, size := rawSlicePointer([]byte(key))

return result(C.cache_get(ptr, size, ident()))
return result(C.cache_get(ptr, size, Ident()))
}

func CacheSet(key, val string, ttl int) {
keyPtr, keySize := rawSlicePointer([]byte(key))
valPtr, valSize := rawSlicePointer([]byte(val))

C.cache_set(keyPtr, keySize, valPtr, valSize, int32(ttl), ident())
C.cache_set(keyPtr, keySize, valPtr, valSize, int32(ttl), Ident())
return
}
18 changes: 18 additions & 0 deletions api/tinygo/runnable/internal/ffi/globals.go
@@ -0,0 +1,18 @@
//go:build tinygo.wasm

package ffi

import (
"github.com/suborbital/reactr/api/tinygo/runnable/runnable"
)

var runnable_ runnable.Runnable
var ident_ int32

func Ident() int32 {
return ident_
}

func Use(runnable runnable.Runnable) {
runnable_ = runnable
}
15 changes: 15 additions & 0 deletions api/tinygo/runnable/internal/ffi/http.go
@@ -0,0 +1,15 @@
//go:build tinygo.wasm

package ffi

// #include <reactr.h>
import "C"

func DoHTTPRequest(method int32, urlStr string, body []byte, headers map[string]string) ([]byte, error) {
urlPtr, urlSize := rawSlicePointer([]byte(urlStr))
bodyPtr, bodySize := rawSlicePointer(body)

size := C.fetch_url(method, urlPtr, urlSize, bodyPtr, bodySize, Ident())

return result(size)
}
12 changes: 12 additions & 0 deletions api/tinygo/runnable/internal/ffi/log.go
@@ -0,0 +1,12 @@
//go:build tinygo.wasm

package ffi

// #include <reactr.h>
import "C"

func LogAtLevel(message string, level int32) {
msgPtr, size := rawSlicePointer([]byte(message))

C.log_msg(msgPtr, size, level, Ident())
}
File renamed without changes.
23 changes: 23 additions & 0 deletions api/tinygo/runnable/internal/ffi/req.go
@@ -0,0 +1,23 @@
//go:build tinygo.wasm

package ffi

// #include <reactr.h>
import "C"

func ReqGetField(fieldType int32, key string) []byte {
ptr, size := rawSlicePointer([]byte(key))

res, err := result(C.request_get_field(fieldType, ptr, size, Ident()))
if err != nil {
return []byte{}
}
return res
}

func ReqSetField(fieldType int32, key string, value string) ([]byte, error) {
keyPtr, keySize := rawSlicePointer([]byte(key))
valPtr, valSize := rawSlicePointer([]byte(value))

return result(C.request_set_field(fieldType, keyPtr, keySize, valPtr, valSize, Ident()))
}
34 changes: 34 additions & 0 deletions api/tinygo/runnable/internal/ffi/result.go
@@ -0,0 +1,34 @@
//go:build tinygo.wasm

package ffi

// #include <reactr.h>
import "C"
import (
"github.com/suborbital/reactr/api/tinygo/runnable/runnable"
)

func result(size int32) ([]byte, runnable.HostErr) {
allocSize := size

if size < 0 {
if size == -1 {
return nil, runnable.NewHostError("unknown error returned from host")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do the other languages return here? I'm wondering because not calling get_ffi_result can cause the host to retain that data in the buffer and can cause issues for subsequent host calls. Can't remember if a -1 error from the host means it never filled the buffer at all.

}

allocSize = -size
}

result := make([]byte, allocSize)
resultPtr, _ := rawSlicePointer(result)

if code := C.get_ffi_result(resultPtr, Ident()); code != 0 {
return nil, runnable.NewHostError("unknown error returned from host")
}

if size < 0 {
return nil, runnable.NewHostError(string(result))
}

return result, nil
}
@@ -1,20 +1,15 @@
//go:build tinygo.wasm

package runnable
package ffi

// #include <reactr.h>
import "C"
import (
"reflect"
"unsafe"
)

var runnable_ Runnable
var ident_ int32

func ident() int32 {
return ident_
}
"github.com/suborbital/reactr/api/tinygo/runnable/runnable"
)

//export run_e
func run_e(rawdata uintptr, size int32, ident int32) {
Expand Down Expand Up @@ -47,7 +42,7 @@ func returnError(err error, ident int32) {
}

switch e := err.(type) {
case RunErr:
case runnable.RunErr:
code = int32(e.Code)
}

Expand Down
@@ -1,6 +1,6 @@
//go:build tinygo.wasm

package runnable
package ffi

import (
"reflect"
Expand Down
14 changes: 6 additions & 8 deletions api/tinygo/runnable/log.go → api/tinygo/runnable/log/log.go
@@ -1,21 +1,19 @@
//go:build tinygo.wasm

package runnable
package log

// #include <reactr.h>
import "C"
import (
"fmt"

"github.com/suborbital/reactr/api/tinygo/runnable/internal/ffi"
)

func logAtLevel(message string, level LogLevel) {
msgPtr, size := rawSlicePointer([]byte(message))
type LogLevel int32

C.log_msg(msgPtr, size, int32(level), ident())
func logAtLevel(message string, level LogLevel) {
ffi.LogAtLevel(message, int32(level))
}

type LogLevel int32

const (
LogLevelError LogLevel = iota + 1
LogLevelWarn
Expand Down
20 changes: 6 additions & 14 deletions api/tinygo/runnable/req.go → api/tinygo/runnable/req/req.go
@@ -1,9 +1,10 @@
//go:build tinygo.wasm

package runnable
package req

// #include <reactr.h>
import "C"
import (
"github.com/suborbital/reactr/api/tinygo/runnable/internal/ffi"
)

type FieldType int32

Expand All @@ -16,20 +17,11 @@ const (
)

func getField(fieldType FieldType, key string) []byte {
ptr, size := rawSlicePointer([]byte(key))

res, err := result(C.request_get_field(int32(fieldType), ptr, size, ident()))
if err != nil {
return []byte{}
}
return res
return ffi.ReqGetField(int32(fieldType), key)
}

func setField(fieldType FieldType, key string, value string) ([]byte, error) {
keyPtr, keySize := rawSlicePointer([]byte(key))
valPtr, valSize := rawSlicePointer([]byte(value))

return result(C.request_set_field(int32(fieldType), keyPtr, keySize, valPtr, valSize, ident()))
return ffi.ReqSetField(int32(fieldType), key, value)
}

func Method() string {
Expand Down