v2.0.0: claims model - signed MMUR2 votes in a truth DB, merged view in a rebuildable cache DB; POST /api/claims, claims and merge routes, unsigned writes answer 410
Build and Push Docker Image / build (push) Successful in 5m1s
Build and Push Docker Image / build (push) Successful in 5m1s
This commit is contained in:
@@ -112,7 +112,15 @@ func (s *Server) streamSSE(w http.ResponseWriter, r *http.Request, stream string
|
||||
}
|
||||
cursor = head
|
||||
} else {
|
||||
cursor = resolveStartCursor(ctx, store, stream, lastID, w, flusher)
|
||||
if rebuilt := s.storage.RebuiltAt(); stream == storage.MetaEventsStream && lastID != "" && rebuilt != "" &&
|
||||
compareStreamIDs(lastID, rebuilt) < 0 {
|
||||
// The cache was rebuilt after this cursor: the rebuild published no
|
||||
// per-key events, so the consumer must take a snapshot.
|
||||
writeGap(w, flusher, lastID, rebuilt, "rebuild")
|
||||
cursor = "0"
|
||||
} else {
|
||||
cursor = resolveStartCursor(ctx, store, stream, lastID, w, flusher)
|
||||
}
|
||||
}
|
||||
|
||||
lastWrite := time.Now()
|
||||
@@ -256,14 +264,7 @@ func resolveStartCursor(ctx context.Context, store *kv.Store, stream, lastID str
|
||||
}
|
||||
|
||||
// Cursor was trimmed. Emit a gap event so consumers that care can react.
|
||||
gap := map[string]string{
|
||||
"requested": lastID,
|
||||
"resumeFrom": oldest,
|
||||
"reason": "retention",
|
||||
}
|
||||
payload, _ := json.Marshal(gap)
|
||||
fmt.Fprintf(w, "event: gap\ndata: %s\n\n", string(payload))
|
||||
flusher.Flush()
|
||||
writeGap(w, flusher, lastID, oldest, "retention")
|
||||
|
||||
// Return "0" so the next read picks up entries starting from the
|
||||
// stream's true minimum — including `oldest` itself.
|
||||
@@ -327,3 +328,15 @@ func parseStreamID(id string) (int64, int64) {
|
||||
}
|
||||
return ms, seq
|
||||
}
|
||||
|
||||
// writeGap emits the synthetic `gap` event: the consumer's cursor cannot be
|
||||
// resumed losslessly and it should take a snapshot (Last-Event-ID: 0).
|
||||
func writeGap(w http.ResponseWriter, flusher http.Flusher, requested, resumeFrom, reason string) {
|
||||
payload, _ := json.Marshal(map[string]string{
|
||||
"requested": requested,
|
||||
"resumeFrom": resumeFrom,
|
||||
"reason": reason,
|
||||
})
|
||||
fmt.Fprintf(w, "event: gap\ndata: %s\n\n", string(payload))
|
||||
flusher.Flush()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user