Skip to content

Commit

Permalink
chore: add example Golang component
Browse files Browse the repository at this point in the history
Signed-off-by: Brooks Townsend <brooksmtownsend@gmail.com>
  • Loading branch information
brooksmtownsend committed Sep 30, 2024
1 parent 5878c52 commit 61dc885
Show file tree
Hide file tree
Showing 49 changed files with 4,494 additions and 4 deletions.
2 changes: 2 additions & 0 deletions components/golang/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
gen/*
build/*
3 changes: 3 additions & 0 deletions components/golang/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module github.com/wasmcloud/wasmcloud/examples/golang/components/http-hello-world

go 1.21
66 changes: 66 additions & 0 deletions components/golang/hello.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package main

import (
"strings"

gen "github.com/wasmcloud/wasmcloud/examples/golang/components/http-hello-world/gen"
)

// Helper type aliases to make code more readable
type HttpRequest = gen.ExportsWasiHttp0_2_0_IncomingHandlerIncomingRequest
type HttpResponseWriter = gen.ExportsWasiHttp0_2_0_IncomingHandlerResponseOutparam
type HttpOutgoingResponse = gen.WasiHttp0_2_0_TypesOutgoingResponse
type HttpError = gen.WasiHttp0_2_0_TypesErrorCode

type Document = gen.WasmcloudCouchbase0_1_0_draft_DocumentDocument

type HttpServer struct{}

func init() {
httpserver := HttpServer{}
// Set the incoming handler struct to HttpServer
gen.SetExportsWasiHttp0_2_0_IncomingHandler(httpserver)
}

func (h HttpServer) Handle(request HttpRequest, responseWriter HttpResponseWriter) {
// Construct HttpResponse to send back
headers := gen.NewFields()
httpResponse := gen.NewOutgoingResponse(headers)
httpResponse.SetStatusCode(200)
body := httpResponse.Body().Unwrap()
bodyWrite := body.Write().Unwrap()

// Get document body & id
documentContents := request.Consume().Unwrap().Stream().Unwrap().BlockingRead(99999).Unwrap()
var documentId string
if request.PathWithQuery().IsSome() {
trimmed := strings.TrimLeft(request.PathWithQuery().Unwrap(), "/")
if trimmed == "" {
documentId = "demodoc"
} else {
documentId = trimmed
}
} else {
documentId = "demodoc"
}

// Upsert and get the document
document := gen.WasmcloudCouchbase0_1_0_draft_TypesDocumentRaw(string(documentContents))
gen.WasmcloudCouchbase0_1_0_draft_DocumentUpsert(documentId, document, gen.None[gen.WasmcloudCouchbase0_1_0_draft_DocumentDocumentUpsertOptions]())
res := gen.WasmcloudCouchbase0_1_0_draft_DocumentGet(documentId, gen.None[gen.WasmcloudCouchbase0_1_0_draft_DocumentDocumentGetOptions]())

// Send HTTP response
okResponse := gen.Ok[HttpOutgoingResponse, HttpError](httpResponse)
gen.StaticResponseOutparamSet(responseWriter, okResponse)
if res.IsOk() {
document := res.Unwrap()
bodyWrite.BlockingWriteAndFlush([]uint8(document.Document.GetRaw())).Unwrap()
} else {
bodyWrite.BlockingWriteAndFlush([]uint8("Document not found")).Unwrap()
}
bodyWrite.Drop()
gen.StaticOutgoingBodyFinish(body, gen.None[gen.WasiHttp0_2_0_TypesTrailers]())
}

//go:generate wit-bindgen tiny-go wit --out-dir=gen --gofmt
func main() {}
9 changes: 9 additions & 0 deletions components/golang/wasmcloud.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
name = "Go Couchbase"
language = "tinygo"
type = "component"
version = "0.1.0"

[component]
wit_world = "hello"
wasm_target = "wasm32-wasi-preview2"
destination = "build/golang_s.wasm"
34 changes: 34 additions & 0 deletions components/golang/wit/deps.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
[cli]
sha256 = "285865a31d777181b075f39e92bcfe59c89cd6bacce660be1b9a627646956258"
sha512 = "da2622210a9e3eea82b99f1a5b8a44ce5443d009cb943f7bca0bf9cf4360829b289913d7ee727c011f0f72994ea7dc8e661ebcc0a6b34b587297d80cd9b3f7e8"

[clocks]
sha256 = "468b4d12892fe926b8eb5d398dbf579d566c93231fa44f415440572c695b7613"
sha512 = "e6b53a07221f1413953c9797c68f08b815fdaebf66419bbc1ea3e8b7dece73731062693634731f311a03957b268cf9cc509c518bd15e513c318aa04a8459b93a"

[couchbase]
path = "../../../wit/couchbase"
sha256 = "1c4502722fe222e4c4ca9fe94afde60e10e90808b615a2d11c6380c28bda4a1f"
sha512 = "d530a661e4727a36de87dd354cc82e9f32b3dc2ca985c946afe618930a9b2794e9ed344c0142592a16ad4a0e10d7916b2c5741d935ff49deef5f4cf8bf3735c9"

[filesystem]
sha256 = "498c465cfd04587db40f970fff2185daa597d074c20b68a8bcbae558f261499b"
sha512 = "ead452f9b7bfb88593a502ec00d76d4228003d51c40fd0408aebc32d35c94673551b00230d730873361567cc209ec218c41fb4e95bad194268592c49e7964347"

[http]
url = "https://github.com/WebAssembly/wasi-http/archive/v0.2.0.tar.gz"
sha256 = "8f44402bde16c48e28c47dc53eab0b26af5b3b3482a1852cf77673e0880ba1c1"
sha512 = "760695f9a25c25bf75a25b731cb21c3bda9e288e450edda823324ecbc73d5d798bbb5de2edad999566980836f037463ee9e57d61789d04b3f3e381475b1a9a0f"
deps = ["cli", "clocks", "filesystem", "io", "random", "sockets"]

[io]
sha256 = "7210e5653539a15478f894d4da24cc69d61924cbcba21d2804d69314a88e5a4c"
sha512 = "49184a1b0945a889abd52d25271172ed3dc2db6968fcdddb1bab7ee0081f4a3eeee0977ad2291126a37631c0d86eeea75d822fa8af224c422134500bf9f0f2bb"

[random]
sha256 = "7371d03c037d924caba2587fb2e7c5773a0d3c5fcecbf7971e0e0ba57973c53d"
sha512 = "964c4e8925a53078e4d94ba907b54f89a0b7e154f46823a505391471466c17f53c8692682e5c85771712acd88b348686173fc07c53a3cfe3d301b8cd8ddd0de4"

[sockets]
sha256 = "622bd28bbeb43736375dc02bd003fd3a016ff8ee91e14bab488325c6b38bf966"
sha512 = "5a63c1f36de0c4548e1d2297bdbededb28721cbad94ef7825c469eae29d7451c97e00b4c1d6730ee1ec0c4a5aac922961a2795762d4a0c3bb54e30a391a84bae"
2 changes: 2 additions & 0 deletions components/golang/wit/deps.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
http = "https://github.com/WebAssembly/wasi-http/archive/v0.2.0.tar.gz"
couchbase = "../../../wit/couchbase"
7 changes: 7 additions & 0 deletions components/golang/wit/deps/cli/command.wit
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package wasi:cli@0.2.0;

world command {
include imports;

export run;
}
18 changes: 18 additions & 0 deletions components/golang/wit/deps/cli/environment.wit
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
interface environment {
/// Get the POSIX-style environment variables.
///
/// Each environment variable is provided as a pair of string variable names
/// and string value.
///
/// Morally, these are a value import, but until value imports are available
/// in the component model, this import function should return the same
/// values each time it is called.
get-environment: func() -> list<tuple<string, string>>;

/// Get the POSIX-style arguments to the program.
get-arguments: func() -> list<string>;

/// Return a path that programs should use as their initial current working
/// directory, interpreting `.` as shorthand for this.
initial-cwd: func() -> option<string>;
}
4 changes: 4 additions & 0 deletions components/golang/wit/deps/cli/exit.wit
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
interface exit {
/// Exit the current instance and any linked instances.
exit: func(status: result);
}
20 changes: 20 additions & 0 deletions components/golang/wit/deps/cli/imports.wit
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package wasi:cli@0.2.0;

world imports {
include wasi:clocks/imports@0.2.0;
include wasi:filesystem/imports@0.2.0;
include wasi:sockets/imports@0.2.0;
include wasi:random/imports@0.2.0;
include wasi:io/imports@0.2.0;

import environment;
import exit;
import stdin;
import stdout;
import stderr;
import terminal-input;
import terminal-output;
import terminal-stdin;
import terminal-stdout;
import terminal-stderr;
}
4 changes: 4 additions & 0 deletions components/golang/wit/deps/cli/run.wit
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
interface run {
/// Run the program.
run: func() -> result;
}
17 changes: 17 additions & 0 deletions components/golang/wit/deps/cli/stdio.wit
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
interface stdin {
use wasi:io/streams@0.2.0.{input-stream};

get-stdin: func() -> input-stream;
}

interface stdout {
use wasi:io/streams@0.2.0.{output-stream};

get-stdout: func() -> output-stream;
}

interface stderr {
use wasi:io/streams@0.2.0.{output-stream};

get-stderr: func() -> output-stream;
}
49 changes: 49 additions & 0 deletions components/golang/wit/deps/cli/terminal.wit
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/// Terminal input.
///
/// In the future, this may include functions for disabling echoing,
/// disabling input buffering so that keyboard events are sent through
/// immediately, querying supported features, and so on.
interface terminal-input {
/// The input side of a terminal.
resource terminal-input;
}

/// Terminal output.
///
/// In the future, this may include functions for querying the terminal
/// size, being notified of terminal size changes, querying supported
/// features, and so on.
interface terminal-output {
/// The output side of a terminal.
resource terminal-output;
}

/// An interface providing an optional `terminal-input` for stdin as a
/// link-time authority.
interface terminal-stdin {
use terminal-input.{terminal-input};

/// If stdin is connected to a terminal, return a `terminal-input` handle
/// allowing further interaction with it.
get-terminal-stdin: func() -> option<terminal-input>;
}

/// An interface providing an optional `terminal-output` for stdout as a
/// link-time authority.
interface terminal-stdout {
use terminal-output.{terminal-output};

/// If stdout is connected to a terminal, return a `terminal-output` handle
/// allowing further interaction with it.
get-terminal-stdout: func() -> option<terminal-output>;
}

/// An interface providing an optional `terminal-output` for stderr as a
/// link-time authority.
interface terminal-stderr {
use terminal-output.{terminal-output};

/// If stderr is connected to a terminal, return a `terminal-output` handle
/// allowing further interaction with it.
get-terminal-stderr: func() -> option<terminal-output>;
}
45 changes: 45 additions & 0 deletions components/golang/wit/deps/clocks/monotonic-clock.wit
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package wasi:clocks@0.2.0;
/// WASI Monotonic Clock is a clock API intended to let users measure elapsed
/// time.
///
/// It is intended to be portable at least between Unix-family platforms and
/// Windows.
///
/// A monotonic clock is a clock which has an unspecified initial value, and
/// successive reads of the clock will produce non-decreasing values.
///
/// It is intended for measuring elapsed time.
interface monotonic-clock {
use wasi:io/poll@0.2.0.{pollable};

/// An instant in time, in nanoseconds. An instant is relative to an
/// unspecified initial value, and can only be compared to instances from
/// the same monotonic-clock.
type instant = u64;

/// A duration of time, in nanoseconds.
type duration = u64;

/// Read the current value of the clock.
///
/// The clock is monotonic, therefore calling this function repeatedly will
/// produce a sequence of non-decreasing values.
now: func() -> instant;

/// Query the resolution of the clock. Returns the duration of time
/// corresponding to a clock tick.
resolution: func() -> duration;

/// Create a `pollable` which will resolve once the specified instant
/// occured.
subscribe-instant: func(
when: instant,
) -> pollable;

/// Create a `pollable` which will resolve once the given duration has
/// elapsed, starting at the time at which this function was called.
/// occured.
subscribe-duration: func(
when: duration,
) -> pollable;
}
42 changes: 42 additions & 0 deletions components/golang/wit/deps/clocks/wall-clock.wit
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package wasi:clocks@0.2.0;
/// WASI Wall Clock is a clock API intended to let users query the current
/// time. The name "wall" makes an analogy to a "clock on the wall", which
/// is not necessarily monotonic as it may be reset.
///
/// It is intended to be portable at least between Unix-family platforms and
/// Windows.
///
/// A wall clock is a clock which measures the date and time according to
/// some external reference.
///
/// External references may be reset, so this clock is not necessarily
/// monotonic, making it unsuitable for measuring elapsed time.
///
/// It is intended for reporting the current date and time for humans.
interface wall-clock {
/// A time and date in seconds plus nanoseconds.
record datetime {
seconds: u64,
nanoseconds: u32,
}

/// Read the current value of the clock.
///
/// This clock is not monotonic, therefore calling this function repeatedly
/// will not necessarily produce a sequence of non-decreasing values.
///
/// The returned timestamps represent the number of seconds since
/// 1970-01-01T00:00:00Z, also known as [POSIX's Seconds Since the Epoch],
/// also known as [Unix Time].
///
/// The nanoseconds field of the output is always less than 1000000000.
///
/// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16
/// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time
now: func() -> datetime;

/// Query the resolution of the clock.
///
/// The nanoseconds field of the output is always less than 1000000000.
resolution: func() -> datetime;
}
6 changes: 6 additions & 0 deletions components/golang/wit/deps/clocks/world.wit
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package wasi:clocks@0.2.0;

world imports {
import monotonic-clock;
import wall-clock;
}
Loading

0 comments on commit 61dc885

Please sign in to comment.