diff options
| author | Shulhan <ms@kilabit.info> | 2026-02-06 07:08:29 +0700 |
|---|---|---|
| committer | Shulhan <ms@kilabit.info> | 2026-02-06 07:08:29 +0700 |
| commit | 54d395f53e344a3cf3861c0e3d2f82ad14ecc602 (patch) | |
| tree | 9f19525f8b950ddd9d715d9abe71e5545df4d65e /exec_response.go | |
| parent | a3c27356bfe3e56809f579b617e02829a7ea0a68 (diff) | |
| download | awwan-54d395f53e344a3cf3861c0e3d2f82ad14ecc602.tar.xz | |
all: improve the Server-Sent Events (SSE) output
In the ExecResponse, store the event in the Output instead of message
data, so the server can iterate the Output directly and pass it to
WriteEvent directly.
The event ID now start at 1 with type "begin".
This is to minimize confusion when comparing empty Last-Event-ID from
client, which is equal to 0.
Diffstat (limited to 'exec_response.go')
| -rw-r--r-- | exec_response.go | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/exec_response.go b/exec_response.go index 92774cf..9f700a1 100644 --- a/exec_response.go +++ b/exec_response.go @@ -36,7 +36,9 @@ type ExecResponse struct { Error string `json:"error"` - Output []string `json:"output"` + Output []sseclient.Event `json:"output"` + + id int // mtxOutput protect read/write on Output. mtxOutput sync.Mutex @@ -53,10 +55,18 @@ func newExecResponse(req *ExecRequest) (execRes *ExecResponse) { ID: fmt.Sprintf(`%s:%s:%s:%d`, req.Mode, req.Script, req.LineRange, now.Unix()), BeginAt: now.Format(time.RFC3339), - Output: make([]string, 0, 8), + Output: make([]sseclient.Event, 0, 512), eventq: make(chan sseclient.Event, 512), } + execRes.id++ + var ev = sseclient.Event{ + Type: `begin`, + Data: execRes.BeginAt, + ID: strconv.Itoa(execRes.id), + } + execRes.Output = append(execRes.Output, ev) + // Use the ExecResponse itself as handler for output. req.registerLogWriter(`response`, execRes) @@ -71,18 +81,19 @@ func (execRes *ExecResponse) Write(out []byte) (n int, err error) { } execRes.mtxOutput.Lock() + defer execRes.mtxOutput.Unlock() + + execRes.id++ var ev = sseclient.Event{ Data: string(out), - ID: strconv.FormatInt(int64(len(execRes.Output)), 10), + ID: strconv.Itoa(execRes.id), } - - execRes.Output = append(execRes.Output, ev.Data) + execRes.Output = append(execRes.Output, ev) select { case execRes.eventq <- ev: default: } - execRes.mtxOutput.Unlock() return len(out), nil } @@ -106,8 +117,11 @@ func (execRes *ExecResponse) end(execErr error) { execRes.EndAt = timeNow().UTC().Format(time.RFC3339) + execRes.id++ ev.Type = `end` ev.Data = execRes.EndAt + ev.ID = strconv.Itoa(execRes.id) + execRes.Output = append(execRes.Output, ev) select { case execRes.eventq <- ev: |
