Skip to content

Commit

Permalink
update: rearrange doc structure and add WATM Spec in Go (#8)
Browse files Browse the repository at this point in the history
* update: add spec in Go representation

Signed-off-by: Gaukas Wang <[email protected]>

* update: Go runtime doc in subdirectory

Signed-off-by: Gaukas Wang <[email protected]>

* update: remove unnecessary indentation

Signed-off-by: Gaukas Wang <[email protected]>

---------

Signed-off-by: Gaukas Wang <[email protected]>
  • Loading branch information
gaukas authored Mar 13, 2024
1 parent 559d7bc commit 49cf319
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 85 deletions.
76 changes: 1 addition & 75 deletions runtime/go/go.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,78 +13,4 @@ permalink: /runtime/go.html
`water` (a.k.a. `water-go` in contrast to `water-rs`) is a WATER Runtime Library build in Go. It uses the WebAssembly runtime with WASI support from [wazero](https://github.com/tetratelabs/wazero), and implements an abstracted network programming interface that roughly ressembles the standard `net` package in Go.

## Cross-platform Support
Project WATER is designed to be cross-platform and cross-architecture. See [Cross-platform Compatibility (Go)](./go/cross-platform.html) for more details.

## Usage

### Importing `water`
To use `water` in a Go project, simply import it as a module.

By default, `water` does not recognize any transport modules as there can be many different
specifications of transport modules. To use a specific transport module, import its implementation
as well.

```go
import (
"github.com/refraction-networking/water"
_ "github.com/refraction-networking/water/transport/v0" // import the v0 transport module spec
)
```

### Working Mode: Dialer
Dialer acts like a client. It actively creates connections to a remote server (and usually is the one who sends the first message).

```go
// ...

// Load the WebAssembly binary into wasm as []byte.
// The rest of the code on this page assumes that wasm is already loaded.
wasm, _ := os.ReadFile("./examples/v0/plain/plain.wasm")

config := &water.Config{
TransportModuleBin: wasm,
}

dialer, _ := water.NewDialerWithContext(context.Background(), config)
conn, _ := dialer.DialContext(context.Background(),"tcp", remoteAddr)

// ...
```

### Working Mode: Listener
Listener acts like a server. It listens on a network address and wait for
incoming connections to accept.

```go
lis, _ := config.ListenContext(context.Background(), "tcp", localAddr)
defer lis.Close()
log.Printf("Listening on %s", lis.Addr().String())

for {
conn, err := lis.Accept()
handleConn(conn)
}
```

### Working Mode: Relay
A relay combines the functionalities of both a dialer and a listener. It works
like a forward proxy, accepting connections from a client and forwarding them to a
remote server by dialing a connection to the remote server.

```go
relay, _ := water.NewRelayWithContext(context.Background(), config)

relay.ListenAndRelayTo("tcp", localAddr, "tcp", remoteAddr) // blocking
```

## Troubleshooting

### Enable `wazero` debug logs

`wazero` is the WebAssembly runtime with WASI support that `water` uses. To enable debug logs from `wazero`, pass the values below via the `context.Context`

```go
// example of enabling FileSystem, Poll, and Sock logging scopes of wazero
ctx = context.WithValue(ctx, experimental.FunctionListenerFactoryKey{},
logging.NewHostLoggingListenerFactory(os.Stderr, logging.LogScopeFilesystem|logging.LogScopePoll|logging.LogScopeSock))
```
Project WATER is designed to be cross-platform and cross-architecture. See [Cross-platform Compatibility (Go)](./go/cross-platform.html) for more details.
18 changes: 18 additions & 0 deletions runtime/go/troubleshoot.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
layout: default
title: Troubleshooting (Go)
grand_parent: Runtime Library
parent: Runtime Library in Go
nav_order: 2
---
# Troubleshooting

## Enable `wazero` debug logs

`wazero` is the WebAssembly runtime with WASI support that `water` uses. To enable debug logs from `wazero`, pass the values below via the `context.Context`

```go
// example of enabling FileSystem, Poll, and Sock logging scopes of wazero
ctx = context.WithValue(ctx, experimental.FunctionListenerFactoryKey{},
logging.NewHostLoggingListenerFactory(os.Stderr, logging.LogScopeFilesystem|logging.LogScopePoll|logging.LogScopeSock))
```
65 changes: 65 additions & 0 deletions runtime/go/usage.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
---
layout: default
title: Usage (Go)
grand_parent: Runtime Library
parent: Runtime Library in Go
nav_order: 3
---
# Usage

## Importing `water`
To use `water` in a Go project, simply import it as a module.

By default, `water` does not recognize any transport modules as there can be many different
specifications of transport modules. To use a specific transport module, import its implementation
as well.

```go
import (
"github.com/refraction-networking/water"
_ "github.com/refraction-networking/water/transport/v0" // import the v0 transport module spec
)
```

## Working Modes

### Dialer
Dialer acts like a client. It actively creates connections to a remote server (and usually is the one who sends the first message).

```go
// Load the WebAssembly binary into wasm as []byte.
// The rest of the code on this page assumes that wasm is already loaded.
wasm, _ := os.ReadFile("./examples/v0/plain/plain.wasm")

config := &water.Config{
TransportModuleBin: wasm,
}

dialer, _ := water.NewDialerWithContext(context.Background(), config)
conn, _ := dialer.DialContext(context.Background(),"tcp", remoteAddr)
```

### Listener
Listener acts like a server. It listens on a network address and wait for
incoming connections to accept.

```go
lis, _ := config.ListenContext(context.Background(), "tcp", localAddr)
defer lis.Close()
log.Printf("Listening on %s", lis.Addr().String())

for {
conn, err := lis.Accept()
handleConn(conn)
}
```

### Relay
A relay combines the functionalities of both a dialer and a listener. It works
like a forward proxy, accepting connections from a client and forwarding them to a
remote server by dialing a connection to the remote server.

```go
relay, _ := water.NewRelayWithContext(context.Background(), config)
relay.ListenAndRelayTo("tcp", localAddr, "tcp", remoteAddr) // blocking
```
78 changes: 68 additions & 10 deletions transport-module/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,18 @@ WATM imports the following functions from the host environment:
| --- | --- | --- | --- |
|`host_dial` | - | `net_fd: s32` | Ask the host to connect to a remote server. |
| `host_accept` | - | `net_fd: s32` | Ask the host to accept an incoming connection. |
| ~~`host_defer`~~ | - | - | ~~Ask the host to defer the execution of the current function.~~ Deprecated: this function is equal to `NOP`. |
| `pull_config`* | - | `conf_fd: s32` | Ask the host to provide the configuration file. |
| ~~`host_defer`~~ | - | - | ~~Ask the host to defer the execution of the current function.~~ Deprecated: this function is equal to `NOP`. |

### Exports

WATM exports the following functions to the host environment:

| Function Signature | Parameters | Results | Description |
| --- | --- | --- | --- |
| `_water_v0` | - | - | Version 0 identifier. |
| `_water_init` | - | `errno: s32` | Initialize the transport module. |
| `_water_cancel_with` | `cancel_fd: s32` | `errno: s32` | Cancel the operation with the given file descriptor. |
| `_water_dial` | `internal_fd: s32` | `net_fd: s32` | Connect to a remote server. |
| `_water_accept` | `internal_fd: s32` | `net_fd: s32` | Accept an incoming connection. |
| `_water_associate` | - | `errno: s32` | Associate the transport module with the host environment. |
Expand All @@ -41,7 +43,55 @@ To help developers understand the API, we provide the following representations
(planned feature)

### Go representation
(to be added)

<details>
<summary>Imports</summary>

```go
//go:wasmimport env host_dial
//go:noescape
func _import_host_dial() (fd int32)

//go:wasmimport env host_accept
//go:noescape
func _import_host_accept() (fd int32)

//go:wasmimport env pull_config
//go:noescape
func _import_pull_config() (fd int32)

//go:wasmimport env host_defer
//go:noescape
func _import_host_defer()
```
</details>

<details>
<summary>Exports</summary>

```go
//export _water_v0
func _water_v0()

//export _water_init
func _water_init()

//export _water_cancel_with
func _water_cancel_with(cancelFd int32) int32

//export _water_dial
func _water_dial(internalFd int32) (networkFd int32)

//export _water_accept
func _water_accept(internalFd int32) (networkFd int32)

//export _water_associate
func _water_associate() int32

//export _water_worker
func _water_worker() int32
```
</details>

### Rust representation
(to be added)
Expand All @@ -51,35 +101,43 @@ Similarly, such API can be represented in WIT.

_Note that the following is a simplified example and may not strictly follow the WIT syntax. In other words, we do not guarantee the following code to be compilable._

#### Imported Functions
<details>
<summary>Imports</summary>

```wit
// imports.wit
package env;

interface host {
host_dial: func() -> (net_fd: s32);
host_accept: func() -> (net_fd: s32);
host_defer: func(); // deprecated
pull_config: func() -> (conf_fd: s32);
host_defer: func(); // deprecated
}

world host-world {
import host;
}
```
</details>

<details>
<summary>Exports</summary>

#### Exported Functions
```wit
// exports.wit
interface wasm {
_water_init: func() -> (errno: s32)
_water_dial: func(internal_fd: s32) -> (net_fd: s32);
_water_accept: func(internal_fd: s32) -> (net_fd: s32);
_water_v0: func(); // version 0 identifier
_water_init: func() -> (errno: s32);
_water_cancel_with(cancel_fd: s32) -> (errno: s32);
_water_dial: func(internal_fd: s32) -> (net_fd: s32);
_water_accept: func(internal_fd: s32) -> (net_fd: s32);
_water_associate: func() -> (errno: s32);
_water_worker: func() -> (errno: s32);
_water_worker: func() -> (errno: s32);
}
world wasm-world {
export wasm;
}
```
```
</details>

0 comments on commit 49cf319

Please sign in to comment.