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 /http_server.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 'http_server.go')
| -rw-r--r-- | http_server.go | 43 |
1 files changed, 12 insertions, 31 deletions
diff --git a/http_server.go b/http_server.go index f2a35b4..e0935c5 100644 --- a/http_server.go +++ b/http_server.go @@ -714,6 +714,9 @@ func (httpd *httpServer) Execute(epr *libhttp.EndpointRequest) (resb []byte, err res.Code = http.StatusOK res.Data = execRes + execRes.mtxOutput.Lock() + defer execRes.mtxOutput.Unlock() + resb, err = json.Marshal(res) if err != nil { res.Message = fmt.Sprintf(`%s: %s`, logp, err) @@ -821,42 +824,24 @@ func (httpd *httpServer) ExecuteTail(sseconn *libhttp.SSEConn) { var ( lastEventIDStr = sseconn.HTTPRequest.Header.Get(libhttp.HeaderLastEventID) lastEventID int64 + ok bool ) if len(lastEventIDStr) != 0 { lastEventID, _ = strconv.ParseInt(lastEventIDStr, 10, 64) } - if lastEventID == 0 { - _ = sseconn.WriteEvent(`begin`, execRes.BeginAt, nil) - } execRes.mtxOutput.Lock() - if lastEventID < int64(len(execRes.Output)) { - // Send out the existing output based on request - // Last-Event-ID ... - var ( - idx int - out string - idstr string - ) - for idx, out = range execRes.Output[int(lastEventID):] { - idstr = strconv.FormatInt(int64(idx), 10) - _ = sseconn.WriteEvent(``, out, &idstr) - } - lastEventID = int64(idx) + // Send out the existing output based on request + // Last-Event-ID ... + var ev sseclient.Event + for lastEventID < int64(len(execRes.Output)) { + ev = execRes.Output[int(lastEventID)] + _ = sseconn.WriteEvent(ev.Type, ev.Data, &ev.ID) + lastEventID++ } - execRes.mtxOutput.Unlock() - - var ( - ok bool - ev sseclient.Event - evid int64 - ) - - execRes.mtxOutput.Lock() if len(execRes.EndAt) != 0 { // The execution has been completed. - _ = sseconn.WriteEvent(`end`, execRes.EndAt, nil) execRes.mtxOutput.Unlock() goto out } @@ -870,13 +855,9 @@ func (httpd *httpServer) ExecuteTail(sseconn *libhttp.SSEConn) { // Channel has been closed. break } - if len(ev.ID) == 0 { - _ = sseconn.WriteEvent(ev.Type, ev.Data, nil) - continue - } // Skip event where ID is less than last ID from output. - evid = ev.IDInt() + evid := ev.IDInt() if evid <= lastEventID { continue } |
