Pola Server

Konvensi cache backend yang cocok dengan Tide.

Tide adalah library sisi-klien dan bekerja dengan backend apa pun. Pola sisi-server ini memaksimalkan performa Tide.

Respons ETag / 304

Ketika Tide mengirim If-None-Match, respons 304 jika data tak berubah. Tanpa bandwidth pada poll tanpa data baru.

go
// Go/Fiber example
func handler(c *fiber.Ctx) error {
data := getCachedData()
etag := fmt.Sprintf("\"%x\"", sha256.Sum256(data))

if c.Get("If-None-Match") == etag {
return c.SendStatus(304)
}
c.Set("ETag", etag)
return c.Send(data)
}

Cache pre-computed (serve tanpa proses)

Marshal JSON sekali di loop background (WS broadcast, scheduler). Handler HTTP serve raw bytes — tanpa serialisasi per request.

go
var cachedBytes atomic.Value // []byte

// Background loop (every 3-5s)
func updateCache(snapshot any) {
bytes, _ := json.Marshal(snapshot)
cachedBytes.Store(bytes)
}

// HTTP handler — instant serve
func handler(c *fiber.Ctx) error {
data := cachedBytes.Load().([]byte)
c.Set("Content-Type", "application/json")
return c.Send(data)
}

Pengayaan broadcast WebSocket

Perkaya broadcast WS dengan semua field yang dibutuhkan frontend. Data WS yang sparse memaksa Tide fallback ke HTTP polling.

go
// Good — WS delivers complete data, Tide stops polling
hub.Broadcast(map[string]any{
"type": "dashboard",
"data": map[string]any{
"stack": enrichedStackSnapshot,
"scheduler": schedulerSnapshot,
},
})

// Bad — sparse data causes flicker, Tide can't use it
hub.Broadcast(map[string]any{
"type": "update",
"id": "stack",
"pid": 1234, // missing most fields
})
Aturan praktis: jika pesan WS punya lebih sedikit field dari respons HTTP, kembalikan null dari handler ws dan biarkan Tide pakai HTTP polling.