diff options
| author | Xe Iaso <me@xeiaso.net> | 2023-06-15 15:14:10 -0400 |
|---|---|---|
| committer | Xe Iaso <me@xeiaso.net> | 2023-06-15 15:14:10 -0400 |
| commit | 5781e2c5ad539c9d488e7b9a3f28f555fc2b918e (patch) | |
| tree | 47f198b02812ca3d291436eb3c6d4991c913fbe8 /wasm | |
| parent | a6c11eb8e407898e83251c202d4b82702812c6f9 (diff) | |
| download | x-5781e2c5ad539c9d488e7b9a3f28f555fc2b918e.tar.xz x-5781e2c5ad539c9d488e7b9a3f28f555fc2b918e.zip | |
wasm: example code for my gophercon EU talk
Signed-off-by: Xe Iaso <me@xeiaso.net>
Diffstat (limited to 'wasm')
| -rw-r--r-- | wasm/cmd/aiyou/main.go | 84 | ||||
| -rw-r--r-- | wasm/cmd/tensei/main.go | 94 | ||||
| -rw-r--r-- | wasm/wasip1/echoclient.rs | 24 | ||||
| -rw-r--r-- | wasm/wasip1/hello.rs | 3 | ||||
| -rw-r--r-- | wasm/wasip1/promptreply.rs | 9 |
5 files changed, 214 insertions, 0 deletions
diff --git a/wasm/cmd/aiyou/main.go b/wasm/cmd/aiyou/main.go new file mode 100644 index 0000000..45e9a46 --- /dev/null +++ b/wasm/cmd/aiyou/main.go @@ -0,0 +1,84 @@ +package main + +import ( + "context" + "flag" + "io/fs" + "math/rand" + "net" + "os" + "strconv" + "time" + + "github.com/tetratelabs/wazero" + "github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1" + "within.website/ln" + "within.website/ln/opname" + "within.website/x/internal" +) + +var ( + r wazero.Runtime + code wazero.CompiledModule + + binary = flag.String("wasm-binary", "./bin.wasm", "binary to run against every line of input from connections") +) + +func main() { + internal.HandleStartup() + ctx := opname.With(context.Background(), "tensei") + + data, err := os.ReadFile(*binary) + if err != nil { + ln.FatalErr(ctx, err) + } + + r = wazero.NewRuntime(ctx) + + wasi_snapshot_preview1.MustInstantiate(ctx, r) + + code, err = r.CompileModule(ctx, data) + if err != nil { + ln.FatalErr(ctx, err) + } + + name := strconv.Itoa(rand.Int()) + config := wazero.NewModuleConfig().WithStdout(os.Stdout).WithStdin(os.Stdin).WithStderr(os.Stderr).WithArgs("aiyou").WithName(name).WithFS(ConnFS{}) + + mod, err := r.InstantiateModule(ctx, code, config) + if err != nil { + ln.Error(ctx, err) + return + } + defer mod.Close(ctx) +} + +type ConnFS struct{} + +func (ConnFS) Open(name string) (fs.File, error) { + conn, err := net.Dial("tcp", name) + if err != nil { + return nil, err + } + + return ConnFile{Conn: conn}, nil +} + +type ConnFile struct { + net.Conn +} + +func (c ConnFile) Stat() (fs.FileInfo, error) { + return ConnFileInfo{c.Conn}, nil +} + +type ConnFileInfo struct { + conn net.Conn +} + +func (c ConnFileInfo) Name() string { return c.conn.RemoteAddr().String() } // base name of the file +func (c ConnFileInfo) Size() int64 { return 0 } // length in bytes for regular files; system-dependent for others +func (c ConnFileInfo) Mode() fs.FileMode { return 0 } // file mode bits +func (c ConnFileInfo) ModTime() time.Time { return time.Now() } // modification time +func (c ConnFileInfo) IsDir() bool { return false } // abbreviation for Mode().IsDir() +func (c ConnFileInfo) Sys() any { return c.conn } // underlying data source (can return nil) diff --git a/wasm/cmd/tensei/main.go b/wasm/cmd/tensei/main.go new file mode 100644 index 0000000..987ff48 --- /dev/null +++ b/wasm/cmd/tensei/main.go @@ -0,0 +1,94 @@ +package main + +import ( + "bufio" + "bytes" + "context" + "flag" + "fmt" + "log" + "math/rand" + "net" + "os" + "strconv" + + "github.com/tetratelabs/wazero" + "github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1" + "within.website/ln" + "within.website/ln/opname" + "within.website/x/internal" +) + +var ( + r wazero.Runtime + code wazero.CompiledModule + + binary = flag.String("wasm-binary", "./bin.wasm", "binary to run against every line of input from connections") + bind = flag.String("bind", ":1997", "TCP host:port to bind on") +) + +func main() { + internal.HandleStartup() + ctx := opname.With(context.Background(), "tensei") + + data, err := os.ReadFile(*binary) + if err != nil { + ln.FatalErr(ctx, err) + } + + r = wazero.NewRuntime(ctx) + + wasi_snapshot_preview1.MustInstantiate(ctx, r) + + code, err = r.CompileModule(ctx, data) + if err != nil { + ln.FatalErr(ctx, err) + } + + server, err := net.Listen("tcp", *bind) + if err != nil { + ln.FatalErr(ctx, err) + } + + for { + conn, err := server.Accept() + if err != nil { + log.Println("Failed to accept conn.", err) + continue + } + + fmt.Println(conn.RemoteAddr().String()) + + go func(conn net.Conn) { + defer func() { + fmt.Println("disconnect") + conn.Close() + }() + + scn := bufio.NewScanner(conn) + scn.Split(bufio.ScanLines) + + for scn.Scan() { + fout := &bytes.Buffer{} + fin := bytes.NewBuffer(scn.Bytes()) + + fmt.Println("<", fin.String()) + + name := strconv.Itoa(rand.Int()) + config := wazero.NewModuleConfig().WithStdout(fout).WithStdin(fin).WithArgs("mastosan").WithName(name) + + mod, err := r.InstantiateModule(ctx, code, config) + if err != nil { + ln.Error(ctx, err, ln.F{"remote_host": conn.RemoteAddr().String()}) + return + } + defer mod.Close(ctx) + + fmt.Print(">", fout.String()) + + conn.Write(fout.Bytes()) + conn.Close() + } + }(conn) + } +} diff --git a/wasm/wasip1/echoclient.rs b/wasm/wasip1/echoclient.rs new file mode 100644 index 0000000..8f8e1ed --- /dev/null +++ b/wasm/wasip1/echoclient.rs @@ -0,0 +1,24 @@ +use std::{io, fs::File, str, thread, time}; +use std::io::prelude::*; + +fn main() -> io::Result<()> { + let stdin = io::stdin(); // We get `Stdin` here. + let mut fout = File::create("localhost:1997")?; + + print!("input> "); + io::stdout().lock().flush()?; + let mut buf = String::new(); + stdin.read_line(&mut buf)?; + write!(fout, "{}", buf)?; + + let ten_millis = time::Duration::from_millis(10); + thread::sleep(ten_millis); + + let mut buf = Vec::new(); + fout.read_to_end(&mut buf)?; + let buf = unsafe { str::from_utf8_unchecked(&buf) }; + print!("{}", buf); + io::stdout().lock().flush()?; + + Ok(()) +} diff --git a/wasm/wasip1/hello.rs b/wasm/wasip1/hello.rs new file mode 100644 index 0000000..b4998a8 --- /dev/null +++ b/wasm/wasip1/hello.rs @@ -0,0 +1,3 @@ +fn main() { + println!("hello, world!") +} diff --git a/wasm/wasip1/promptreply.rs b/wasm/wasip1/promptreply.rs new file mode 100644 index 0000000..09d29db --- /dev/null +++ b/wasm/wasip1/promptreply.rs @@ -0,0 +1,9 @@ +use std::io; + +fn main() -> io::Result<()> { + let mut buffer = String::new(); + let stdin = io::stdin(); // We get `Stdin` here. + stdin.read_line(&mut buffer)?; + println!("{}", buffer.trim()); + Ok(()) +} |
