Files
core/test/performance/fixtures/api-json/peer.go
T
2026-11-03 03:32:07 +00:00

116 lines
2.6 KiB
Go

package main
import (
"context"
"encoding/json"
"errors"
"fmt"
"io"
"net"
"net/http"
"os"
"os/signal"
"runtime"
"syscall"
"time"
)
type row struct {
ID int64 `json:"id"`
Text string `json:"text"`
Weight float64 `json:"weight"`
Note *string `json:"note"`
}
type payload struct {
Rows []row `json:"rows"`
Raw json.RawMessage `json:"raw"`
}
type envelope struct {
Code int `json:"code"`
Message string `json:"message"`
Data any `json:"data"`
}
func handle(writer http.ResponseWriter, request *http.Request) {
typed := request.URL.Path == "/benchmark/echo/echo"
if request.Method != http.MethodPost || (!typed && request.URL.Path != "/benchmark/echo/raw") {
http.NotFound(writer, request)
return
}
body := http.MaxBytesReader(writer, request.Body, 16*1024*1024)
defer body.Close()
decoder := json.NewDecoder(body)
decoder.DisallowUnknownFields()
var result any
var err error
if typed {
var input struct {
Payload payload `json:"payload"`
}
err = decoder.Decode(&input)
result = input.Payload
} else {
var input struct {
Source json.RawMessage `json:"source"`
}
err = decoder.Decode(&input)
result = input.Source
}
var extra any
if err != nil || decoder.Decode(&extra) != io.EOF {
http.Error(writer, "invalid JSON", http.StatusBadRequest)
return
}
encoded, err := json.Marshal(envelope{0, "ok", result})
if err != nil {
http.Error(writer, "invalid response", http.StatusInternalServerError)
return
}
writer.Header().Set("Content-Type", "application/json")
writer.Write(encoded)
}
func run() error {
runtime.GOMAXPROCS(1)
content, err := os.ReadFile("config/setting.json")
if err != nil {
return err
}
var settings struct {
HTTP struct {
Port uint16 `json:"port"`
} `json:"http"`
}
if err := json.Unmarshal(content, &settings); err != nil {
return err
}
listener, err := net.Listen("tcp", fmt.Sprintf("127.0.0.1:%d", settings.HTTP.Port))
if err != nil {
return err
}
server := &http.Server{Handler: http.HandlerFunc(handle), ReadHeaderTimeout: 10 * time.Second, IdleTimeout: 10 * time.Second}
stopping := make(chan os.Signal, 1)
signal.Notify(stopping, syscall.SIGTERM)
defer signal.Stop(stopping)
closed := make(chan error, 1)
go func() {
<-stopping
context, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
closed <- server.Shutdown(context)
}()
if err := server.Serve(listener); !errors.Is(err, http.ErrServerClosed) {
return err
}
return <-closed
}
func main() {
if err := run(); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}