opentofu/internal/streamapi/main_loop.go
Martin Atkins ac651e861c streamapi: Initial wasip1 stub
Signed-off-by: Martin Atkins <mart@degeneration.co.uk>
2026-05-19 18:15:28 -07:00

56 lines
1.3 KiB
Go

package streamapi
import (
"context"
"encoding/json"
"io"
"sync"
)
// MainLoop is the main entrypoint to the streaming API.
//
// Pass the reader and writer to use for communication with the calling program.
// The protocol in each direction involves a series of minified JSON objects
// separated by newline ("\n"), with the reader and writer running
// asynchronously from one another so both caller and callee are expected to
// keep a table of active requests.
//
// This function does not return. The caller is expected to terminate the
// process using a signal once all the work is finished.
func MainLoop(ctx context.Context, in io.Reader, out io.Writer) {
dec := json.NewDecoder(in)
enc := json.NewEncoder(out)
inst := &Instance{
in: dec,
out: enc,
}
inst.runLoop(ctx)
}
type Instance struct {
in *json.Decoder
out *json.Encoder
// We must hold outMu whenever writing to "out" to ensure that
// concurrently-written messages are not interleaved.
outMu sync.Mutex
}
func (inst *Instance) runLoop(_ context.Context) {
for {
var msg any
err := inst.in.Decode(&msg)
if err != nil {
// TODO: something better
panic(err)
}
inst.outMu.Lock()
err = inst.out.Encode(msg)
inst.outMu.Unlock()
if err != nil {
// TODO: something better
panic(err)
}
}
}