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

Release v0.4.0 #106

Merged
merged 9 commits into from
Sep 20, 2023
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,19 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

## [v0.4.0] - 2023-09-20

### Features

- Added support for scale signatures
- Consolidated build pipeline into the `build` package
- Consolidated the compiler for golang, typescript, and rust guest functions into the `compile` package

### Changes

- Merged various signature repositories into this repository
- Added integration tests to the `scale` package

## [v0.3.19] - 2023-05-15

### Features
Expand Down Expand Up @@ -236,7 +249,8 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

- Initial release of the Scale Runtime library.

[unreleased]: https://github.com/loopholelabs/scale/compare/v0.3.19...HEAD
[unreleased]: https://github.com/loopholelabs/scale/compare/v0.4.0...HEAD
[v0.4.0]: https://github.com/loopholelabs/scale/compare/v0.4.0
[v0.3.19]: https://github.com/loopholelabs/scale/compare/v0.3.19
[v0.3.18]: https://github.com/loopholelabs/scale/compare/v0.3.18
[v0.3.17]: https://github.com/loopholelabs/scale/compare/v0.3.17
Expand Down
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
[package]
name = "scale_rs"
version = "0.3.20"
version = "0.4.0"
edition = "2021"
description = "A High-Performance WebAssembly Function Runtime"
description = "Scale is a framework for building high-performance plugin systems into any application, all powered by WebAssembly."
homepage = "https://scale.sh"
repository = "https://github.com/loopholelabs/scale"
license = "Apache-2.0"
Expand Down
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@
[![License: Apache 2.0](https://img.shields.io/badge/License-Apache%202.0-brightgreen.svg)](https://www.apache.org/licenses/LICENSE-2.0)
[![Discord](https://dcbadge.vercel.app/api/server/JYmFhtdPeu?style=flat)](https://loopholelabs.io/discord)

[Scale](https://scale.sh) is a highly-performant WebAssembly function runtime that enables composable, language-agnostic software development.
[Scale](https://scale.sh) is a framework for building high-performance plugin systems into any application, all powered by WebAssembly.

With Scale Functions you can write code in any language, then use it from any other language, environment, or runtime, with state-of-the-art sandboxing qualities, startup times, and overall performance. This initial release includes client support for [Golang](https://golang.org) and [Rust](https://www.rust-lang.org/), with runtimes for [Golang](https://golang.org) and [Typescript](https://www.typescriptlang.org/).
With Scale Functions your users can write fully typed plugins in any language they choose, and your application can easily and safely
run those plugins with the Scale Runtime, which provides state-of-the-art sandboxing, low startup times, and extremely high performance.

Currently, guest plugins can be written in [Golang](https://golang.org), [Rust](https://www.rust-lang.org/), and [Typescript](https://www.typescriptlang.org/), with the Runtime supporting [Golang](https://golang.org) and [Typescript](https://www.typescriptlang.org/) host applications.

## Usage and Documentation

Usage instructions and documentation for the Scale Runtime is available at [https://scale.sh/docs](https://scale.sh/docs).
Usage instructions and documentation for Scale is available at [https://scale.sh/docs](https://scale.sh/docs).

## Contributing

Expand Down
2 changes: 2 additions & 0 deletions compile/typescript/manifest_test.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//go:build !integration && !generate

/*
Copyright 2022 Loophole Labs

Expand Down
14 changes: 10 additions & 4 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,9 @@ type Config[T interfaces.Signature] struct {
newSignature interfaces.New[T]
functions []configFunction
context context.Context
Stdout io.Writer
Stderr io.Writer
stdout io.Writer
stderr io.Writer
rawOutput bool
}

// NewConfig returns a new Scale Runtime Config
Expand Down Expand Up @@ -115,12 +116,17 @@ func (c *Config[T]) WithContext(ctx context.Context) *Config[T] {
}

func (c *Config[T]) WithStdout(w io.Writer) *Config[T] {
c.Stdout = w
c.stdout = w
return c
}

func (c *Config[T]) WithStderr(w io.Writer) *Config[T] {
c.Stderr = w
c.stderr = w
return c
}

func (c *Config[T]) WithRawOutput(rawOutput bool) *Config[T] {
c.rawOutput = rawOutput
return c
}

Expand Down
6 changes: 6 additions & 0 deletions config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export class Config<T extends Signature> {
public functions: ConfigFunction[] = [];
stdout: Writer | undefined;
stderr: Writer | undefined;
rawOutput: boolean = false;

constructor(newSignature: New<T>) {
this.newSignature = newSignature;
Expand Down Expand Up @@ -95,6 +96,11 @@ export class Config<T extends Signature> {
this.stderr = writer
return this;
}

public WithRawOutput(rawOutput: boolean): Config<T> {
this.rawOutput = rawOutput
return this;
}
}

// Helper function
Expand Down
15 changes: 15 additions & 0 deletions integration/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ func compileTypescriptGuest(t *testing.T) *scalefunc.Schema {
}

func TestGolangHostGolangGuest(t *testing.T) {
t.Log("Starting TestGolangHostGolangGuest")
schema := compileGolangGuest(t)
cfg := scale.NewConfig(hostSignature.New).WithFunction(schema).WithStdout(os.Stdout).WithStderr(os.Stderr)
runtime, err := scale.New(cfg)
Expand All @@ -232,6 +233,7 @@ func TestGolangHostGolangGuest(t *testing.T) {
}

func TestGolangHostRustGuest(t *testing.T) {
t.Log("Starting TestGolangHostRustGuest")
schema := compileRustGuest(t)
cfg := scale.NewConfig(hostSignature.New).WithFunction(schema).WithStdout(os.Stdout).WithStderr(os.Stderr)
runtime, err := scale.New(cfg)
Expand All @@ -250,6 +252,7 @@ func TestGolangHostRustGuest(t *testing.T) {
}

func TestGolangHostTypescriptGuest(t *testing.T) {
t.Log("Starting TestGolangHostTypescriptGuest")
schema := compileTypescriptGuest(t)
cfg := scale.NewConfig(hostSignature.New).WithFunction(schema).WithStdout(os.Stdout).WithStderr(os.Stderr)
runtime, err := scale.New(cfg)
Expand All @@ -270,6 +273,7 @@ func TestGolangHostTypescriptGuest(t *testing.T) {
}

func TestTypescriptHostTypescriptGuest(t *testing.T) {
t.Log("Starting TestTypescriptHostTypescriptGuest")
wd, err := os.Getwd()
require.NoError(t, err)

Expand All @@ -289,6 +293,7 @@ func TestTypescriptHostTypescriptGuest(t *testing.T) {
}

func TestTypescriptHostGolangGuest(t *testing.T) {
t.Log("Starting TestTypescriptHostGolangGuest")
wd, err := os.Getwd()
require.NoError(t, err)

Expand All @@ -308,6 +313,7 @@ func TestTypescriptHostGolangGuest(t *testing.T) {
}

func TestTypescriptHostRustGuest(t *testing.T) {
t.Log("Starting TestTypescriptHostRustGuest")
wd, err := os.Getwd()
require.NoError(t, err)

Expand All @@ -327,6 +333,7 @@ func TestTypescriptHostRustGuest(t *testing.T) {
}

func TestGolangToGolang(t *testing.T) {
t.Log("Starting TestGolangToGolang")
wd, err := os.Getwd()
require.NoError(t, err)

Expand Down Expand Up @@ -355,6 +362,7 @@ func TestGolangToGolang(t *testing.T) {
}

func TestRustToRust(t *testing.T) {
t.Log("Starting TestRustToRust")
wd, err := os.Getwd()
require.NoError(t, err)

Expand All @@ -377,6 +385,7 @@ func TestRustToRust(t *testing.T) {
}

func TestTypescriptToTypescript(t *testing.T) {
t.Log("Starting TestTypescriptToTypescript")
wd, err := os.Getwd()
require.NoError(t, err)

Expand All @@ -399,6 +408,7 @@ func TestTypescriptToTypescript(t *testing.T) {
}

func TestGolangToRust(t *testing.T) {
t.Log("Starting TestGolangToRust")
wd, err := os.Getwd()
require.NoError(t, err)

Expand Down Expand Up @@ -435,6 +445,7 @@ func TestGolangToRust(t *testing.T) {
}

func TestGolangToTypescript(t *testing.T) {
t.Log("Starting TestGolangToTypescript")
wd, err := os.Getwd()
require.NoError(t, err)

Expand Down Expand Up @@ -470,6 +481,7 @@ func TestGolangToTypescript(t *testing.T) {
}

func TestRustToGolang(t *testing.T) {
t.Log("Starting TestRustToGolang")
wd, err := os.Getwd()
require.NoError(t, err)

Expand Down Expand Up @@ -506,6 +518,7 @@ func TestRustToGolang(t *testing.T) {
}

func TestRustToTypescript(t *testing.T) {
t.Log("Starting TestRustToTypescript")
wd, err := os.Getwd()
require.NoError(t, err)

Expand Down Expand Up @@ -541,6 +554,7 @@ func TestRustToTypescript(t *testing.T) {
}

func TestTypescriptToGolang(t *testing.T) {
t.Log("Starting TestTypescriptToGolang")
wd, err := os.Getwd()
require.NoError(t, err)

Expand Down Expand Up @@ -576,6 +590,7 @@ func TestTypescriptToGolang(t *testing.T) {
}

func TestTypescriptToRust(t *testing.T) {
t.Log("Starting TestTypescriptToRust")
wd, err := os.Getwd()
require.NoError(t, err)

Expand Down
44 changes: 44 additions & 0 deletions log/log.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
Copyright 2023 Loophole Labs

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package log

import (
"fmt"
"io"
)

var _ io.Writer = (*NamedLogger)(nil)

type NamedLogger struct {
nameTemplate string
nameTemplateBytes []byte
writer io.Writer
}

func NewNamedLogger(name string, writer io.Writer) *NamedLogger {
nameTemplate := fmt.Sprintf("%s: ", name)
return &NamedLogger{
nameTemplate: nameTemplate,
nameTemplateBytes: []byte(nameTemplate),
writer: writer,
}
}

func (l *NamedLogger) Write(p []byte) (int, error) {
_, err := l.writer.Write(append(append(l.nameTemplateBytes, p...), '\n'))
return len(p), err
}
23 changes: 23 additions & 0 deletions log/log.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
Copyright 2023 Loophole Labs

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

import {Writer} from "../config";

export function NamedLogger(name: string, writer: Writer): Writer {
return (message: string) => {
writer(`${name}: ${message}`);
}
}
13 changes: 12 additions & 1 deletion module.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import (
"context"
"fmt"

"github.com/loopholelabs/scale/log"

interfaces "github.com/loopholelabs/scale-signature-interfaces"

"github.com/loopholelabs/polyglot"
Expand Down Expand Up @@ -51,11 +53,20 @@ type module[T interfaces.Signature] struct {

// newModule creates a new module
func newModule[T interfaces.Signature](ctx context.Context, template *template[T]) (*module[T], error) {
config := template.runtime.moduleConfig.WithName(fmt.Sprintf("%s.%s", template.identifier, uuid.New().String()))
name := fmt.Sprintf("%s.%s", template.identifier, uuid.New().String())
config := template.runtime.moduleConfig.WithName(name)
for k, v := range template.env {
config = config.WithEnv(k, v)
}

if template.runtime.config.stdout != nil && !template.runtime.config.rawOutput {
config = config.WithStdout(log.NewNamedLogger(name, template.runtime.config.stdout))
}

if template.runtime.config.stderr != nil && !template.runtime.config.rawOutput {
config = config.WithStderr(log.NewNamedLogger(name, template.runtime.config.stderr))
}

instantiatedModule, err := template.runtime.runtime.InstantiateModule(ctx, template.compiled, config)
if err != nil {
return nil, fmt.Errorf("failed to instantiate module '%s': %w", template.identifier, err)
Expand Down
19 changes: 18 additions & 1 deletion module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,15 @@
See the License for the specific language governing permissions and
limitations under the License.
*/

import {Signature} from "@loopholelabs/scale-signature-interfaces";
import {Func} from "./function";
import {Template} from "./template";
import {UnpackUint32} from "./utils";
import {Decoder} from "@loopholelabs/polyglot";
import {DisabledWASI} from "./wasi";
import {v4 as uuid} from "uuid";
import {NamedLogger} from "./log/log";

export async function NewModule<T extends Signature>(template: Template<T>): Promise<Module<T>> {
const m = new Module(template);
Expand All @@ -45,7 +48,21 @@ export class Module<T extends Signature> {

constructor(template: Template<T>) {
this.template = template;
this.wasi = new DisabledWASI(this.template.env, this.template.runtime.config.stdout, this.template.runtime.config.stderr);

const name = `${this.template.identifier}.${uuid()}`

let stdout = this.template.runtime.config.stdout;
let stderr = this.template.runtime.config.stderr;

if (stdout !== undefined && !this.template.runtime.config.rawOutput) {
ShivanshVij marked this conversation as resolved.
Show resolved Hide resolved
stdout = NamedLogger(name, stdout);
}

if (stderr !== undefined && !this.template.runtime.config.rawOutput) {
stderr = NamedLogger(name, stderr);
}

this.wasi = new DisabledWASI(this.template.env, stdout, stderr);

const moduleConfig = {
wasi_snapshot_preview1: this.wasi.GetImports(),
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@loopholelabs/scale",
"version": "0.3.20",
"description": "A Framework for writing High-Performance WebAssembly Functions and Runtime",
"version": "0.4.0",
"description": "Scale is a framework for building high-performance plugin systems into any application, all powered by WebAssembly.",
"source": "scale.ts",
"types": "types.d.ts",
"license": "Apache-2.0",
Expand Down
Loading