docs(examples): Go example reads typed struct returns

Echo/Complex/Schedule now return typed Go structs (EchoResponse,
ComplexResponse, ScheduleResult); print their fields instead of an "ok" line.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Ivan FB 2026-05-31 12:14:39 +02:00
parent 0a8b53a06d
commit 0bba42d2a2
No known key found for this signature in database
GPG Key ID: DF0C67A04C543270
2 changed files with 21 additions and 17 deletions

View File

@ -29,8 +29,9 @@ overwritten each time and `gofmt`-finalized.
Each call deep-copies its arguments across the FFI thread, so the Go-side C
allocations are freed (via `defer`) as soon as the call returns. String-returning
methods give back a Go `string`; struct-returning methods deliver their CBOR
encoding (decode it with a Go CBOR library if needed).
methods give back a Go `string`; **struct-returning methods give back a typed Go
struct** — the C-POD return is read into Go inside the result callback (delivered
via a `runtime/cgo.Handle`), so the caller never touches C memory.
## Build & run
@ -44,14 +45,15 @@ Expected output:
```
created timer
version: nim-timer v0.1.0
echo: ok (struct param round-tripped)
complex: ok (seq/option graph deep-copied)
schedule: ok (three struct params in one call)
echo: echoed="hello from Go" timerName="go-native-demo"
complex: itemCount=2 hasNote=true summary="received 2 messages, note=a note, retries=3"
schedule: jobId="go-native-demo:nightly" willRunCount=12
done
```
`Echo`, `Complex` and `Schedule` take `{.ffi.}` structs, slices and optionals
directly — previously these procs were skipped by the Go generator.
directly and return typed Go structs — previously these procs were skipped by
the Go generator.
For the cross-process / cross-machine path (CBOR over a socket), see
[`../ipc`](../ipc); a Go client could speak the same wire protocol using any Go

View File

@ -3,8 +3,8 @@
// The generated cgo package marshals each {.ffi.} struct param into its flat
// C-POD form and passes it to the native ABI by value — so methods that take
// structs, sequences and optionals (Echo, Complex, Schedule) are now callable
// directly with idiomatic Go types. String-returning calls (Version) come back
// as a Go string; struct-returning calls deliver their CBOR encoding.
// directly with idiomatic Go types. Struct-returning calls hand back a typed Go
// struct too (read out of the C-POD inside the result callback).
package main
import (
@ -31,15 +31,16 @@ func main() {
fmt.Printf("version: %s\n", v)
}
// Struct param: EchoRequest { Message string; DelayMs int64 }.
if _, err := node.Echo(timer.EchoRequest{Message: "hello from Go", DelayMs: 5}); err != nil {
// Struct param + typed struct return: EchoResponse { Echoed; TimerName }.
if resp, err := node.Echo(timer.EchoRequest{Message: "hello from Go", DelayMs: 5}); err != nil {
log.Printf("echo: %v", err)
} else {
fmt.Println("echo: ok (struct param round-tripped)")
fmt.Printf("echo: echoed=%q timerName=%q\n", resp.Echoed, resp.TimerName)
}
// Deeply nested: slice of structs, slice of strings, two optionals.
_, err = node.Complex(timer.ComplexRequest{
// Deeply nested param + typed return: slice of structs, slice of strings,
// two optionals in; ComplexResponse { Summary; ItemCount; HasNote } out.
cresp, err := node.Complex(timer.ComplexRequest{
Messages: []timer.EchoRequest{
{Message: "one", DelayMs: 0},
{Message: "two", DelayMs: 0},
@ -51,11 +52,12 @@ func main() {
if err != nil {
log.Printf("complex: %v", err)
} else {
fmt.Println("complex: ok (seq/option graph deep-copied)")
fmt.Printf("complex: itemCount=%d hasNote=%v summary=%q\n",
cresp.ItemCount, cresp.HasNote, cresp.Summary)
}
// Multiple struct params at once.
_, err = node.Schedule(
// Multiple struct params at once; ScheduleResult out.
sresp, err := node.Schedule(
timer.JobSpec{Name: "nightly", Payload: []string{"x"}, Priority: 5},
timer.RetryPolicy{MaxAttempts: 3, BackoffMs: 100, RetryOn: []string{"timeout"}},
timer.ScheduleConfig{StartAtMs: 1000, IntervalMs: 5000, Jitter: intp(50)},
@ -63,7 +65,7 @@ func main() {
if err != nil {
log.Printf("schedule: %v", err)
} else {
fmt.Println("schedule: ok (three struct params in one call)")
fmt.Printf("schedule: jobId=%q willRunCount=%d\n", sresp.JobId, sresp.WillRunCount)
}
fmt.Println("done")