feat: initialise project structure with core encoding queue, database models, and web management API
Build / Build and Push (push) Successful in 50s

This commit is contained in:
2026-06-05 19:53:31 +01:00
parent dceba72891
commit 07aa8e5ffe
33 changed files with 2911 additions and 1 deletions
+75
View File
@@ -0,0 +1,75 @@
package web
import (
"encoding/json"
"fmt"
"net/http"
"sync"
"time"
)
type SSEMessage struct {
Event string
Data interface{}
}
type SSEServer struct {
clients map[chan SSEMessage]bool
mu sync.Mutex
}
func NewSSEServer() *SSEServer {
return &SSEServer{
clients: make(map[chan SSEMessage]bool),
}
}
func (s *SSEServer) HandleSSE(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/event-stream")
w.Header().Set("Cache-Control", "no-cache")
w.Header().Set("Connection", "keep-alive")
clientChan := make(chan SSEMessage)
s.mu.Lock()
s.clients[clientChan] = true
s.mu.Unlock()
defer func() {
s.mu.Lock()
delete(s.clients, clientChan)
s.mu.Unlock()
close(clientChan)
}()
notify := r.Context().Done()
for {
select {
case <-notify:
return
case msg := <-clientChan:
dataBytes, err := json.Marshal(msg.Data)
if err != nil {
continue
}
fmt.Fprintf(w, "event: %s\ndata: %s\n\n", msg.Event, string(dataBytes))
w.(http.Flusher).Flush()
case <-time.After(30 * time.Second):
// Keepalive
fmt.Fprintf(w, "event: ping\ndata: {}\n\n")
w.(http.Flusher).Flush()
}
}
}
func (s *SSEServer) Broadcast(event string, data interface{}) {
msg := SSEMessage{Event: event, Data: data}
s.mu.Lock()
defer s.mu.Unlock()
for clientChan := range s.clients {
select {
case clientChan <- msg:
default:
}
}
}