Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ea7bc75fac |
@@ -37,7 +37,8 @@ type ExtendedRelayInfo struct {
|
|||||||
// Informer interface implementation or predefined server configuration. It
|
// Informer interface implementation or predefined server configuration. It
|
||||||
// returns this document as a JSON response to the client.
|
// returns this document as a JSON response to the client.
|
||||||
func (s *Server) HandleRelayInfo(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) HandleRelayInfo(w http.ResponseWriter, r *http.Request) {
|
||||||
r.Header.Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.Header().Set("Vary", "Accept")
|
||||||
log.D.Ln("handling relay information document")
|
log.D.Ln("handling relay information document")
|
||||||
var info *relayinfo.T
|
var info *relayinfo.T
|
||||||
nips := []relayinfo.NIP{
|
nips := []relayinfo.NIP{
|
||||||
|
|||||||
@@ -738,6 +738,12 @@ func (s *Server) handleExport(w http.ResponseWriter, r *http.Request) {
|
|||||||
w.Header().Set(
|
w.Header().Set(
|
||||||
"Content-Disposition", "attachment; filename=\""+filename+"\"",
|
"Content-Disposition", "attachment; filename=\""+filename+"\"",
|
||||||
)
|
)
|
||||||
|
w.Header().Set("X-Content-Type-Options", "nosniff")
|
||||||
|
|
||||||
|
// Flush headers to start streaming immediately
|
||||||
|
if flusher, ok := w.(http.Flusher); ok {
|
||||||
|
flusher.Flush()
|
||||||
|
}
|
||||||
|
|
||||||
// Stream export
|
// Stream export
|
||||||
s.DB.Export(s.Ctx, w, pks...)
|
s.DB.Export(s.Ctx, w, pks...)
|
||||||
|
|||||||
@@ -17,6 +17,11 @@ import (
|
|||||||
"git.mleku.dev/mleku/nostr/utils/units"
|
"git.mleku.dev/mleku/nostr/utils/units"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Flusher interface for HTTP streaming
|
||||||
|
type flusher interface {
|
||||||
|
Flush()
|
||||||
|
}
|
||||||
|
|
||||||
// Export the complete database of stored events to an io.Writer in line structured minified
|
// Export the complete database of stored events to an io.Writer in line structured minified
|
||||||
// JSON. Supports both legacy and compact event formats.
|
// JSON. Supports both legacy and compact event formats.
|
||||||
func (d *D) Export(c context.Context, w io.Writer, pubkeys ...[]byte) {
|
func (d *D) Export(c context.Context, w io.Writer, pubkeys ...[]byte) {
|
||||||
@@ -24,11 +29,18 @@ func (d *D) Export(c context.Context, w io.Writer, pubkeys ...[]byte) {
|
|||||||
evB := make([]byte, 0, units.Mb)
|
evB := make([]byte, 0, units.Mb)
|
||||||
evBuf := bytes.NewBuffer(evB)
|
evBuf := bytes.NewBuffer(evB)
|
||||||
|
|
||||||
|
// Get flusher for HTTP streaming if available
|
||||||
|
var f flusher
|
||||||
|
if fl, ok := w.(flusher); ok {
|
||||||
|
f = fl
|
||||||
|
}
|
||||||
|
|
||||||
// Performance tracking
|
// Performance tracking
|
||||||
startTime := time.Now()
|
startTime := time.Now()
|
||||||
var eventCount, bytesWritten int64
|
var eventCount, bytesWritten int64
|
||||||
lastLogTime := startTime
|
lastLogTime := startTime
|
||||||
const logInterval = 5 * time.Second
|
const logInterval = 5 * time.Second
|
||||||
|
const flushInterval = 100 // Flush every N events
|
||||||
|
|
||||||
log.I.F("export: starting export operation")
|
log.I.F("export: starting export operation")
|
||||||
|
|
||||||
@@ -109,6 +121,11 @@ func (d *D) Export(c context.Context, w io.Writer, pubkeys ...[]byte) {
|
|||||||
eventCount++
|
eventCount++
|
||||||
ev.Free()
|
ev.Free()
|
||||||
|
|
||||||
|
// Flush periodically for HTTP streaming
|
||||||
|
if f != nil && eventCount%flushInterval == 0 {
|
||||||
|
f.Flush()
|
||||||
|
}
|
||||||
|
|
||||||
// Progress logging every logInterval
|
// Progress logging every logInterval
|
||||||
if time.Since(lastLogTime) >= logInterval {
|
if time.Since(lastLogTime) >= logInterval {
|
||||||
elapsed := time.Since(startTime)
|
elapsed := time.Since(startTime)
|
||||||
@@ -169,6 +186,11 @@ func (d *D) Export(c context.Context, w io.Writer, pubkeys ...[]byte) {
|
|||||||
eventCount++
|
eventCount++
|
||||||
ev.Free()
|
ev.Free()
|
||||||
|
|
||||||
|
// Flush periodically for HTTP streaming
|
||||||
|
if f != nil && eventCount%flushInterval == 0 {
|
||||||
|
f.Flush()
|
||||||
|
}
|
||||||
|
|
||||||
// Progress logging every logInterval
|
// Progress logging every logInterval
|
||||||
if time.Since(lastLogTime) >= logInterval {
|
if time.Since(lastLogTime) >= logInterval {
|
||||||
elapsed := time.Since(startTime)
|
elapsed := time.Since(startTime)
|
||||||
@@ -186,6 +208,11 @@ func (d *D) Export(c context.Context, w io.Writer, pubkeys ...[]byte) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Final flush
|
||||||
|
if f != nil {
|
||||||
|
f.Flush()
|
||||||
|
}
|
||||||
|
|
||||||
// Final export summary
|
// Final export summary
|
||||||
elapsed := time.Since(startTime)
|
elapsed := time.Since(startTime)
|
||||||
eventsPerSec := float64(eventCount) / elapsed.Seconds()
|
eventsPerSec := float64(eventCount) / elapsed.Seconds()
|
||||||
@@ -244,6 +271,11 @@ func (d *D) Export(c context.Context, w io.Writer, pubkeys ...[]byte) {
|
|||||||
eventCount++
|
eventCount++
|
||||||
ev.Free()
|
ev.Free()
|
||||||
|
|
||||||
|
// Flush periodically for HTTP streaming
|
||||||
|
if f != nil && eventCount%flushInterval == 0 {
|
||||||
|
f.Flush()
|
||||||
|
}
|
||||||
|
|
||||||
// Progress logging every logInterval
|
// Progress logging every logInterval
|
||||||
if time.Since(lastLogTime) >= logInterval {
|
if time.Since(lastLogTime) >= logInterval {
|
||||||
elapsed := time.Since(startTime)
|
elapsed := time.Since(startTime)
|
||||||
@@ -261,6 +293,11 @@ func (d *D) Export(c context.Context, w io.Writer, pubkeys ...[]byte) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Final flush
|
||||||
|
if f != nil {
|
||||||
|
f.Flush()
|
||||||
|
}
|
||||||
|
|
||||||
// Final export summary for pubkey export
|
// Final export summary for pubkey export
|
||||||
elapsed := time.Since(startTime)
|
elapsed := time.Since(startTime)
|
||||||
eventsPerSec := float64(eventCount) / elapsed.Seconds()
|
eventsPerSec := float64(eventCount) / elapsed.Seconds()
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
v0.46.1
|
v0.46.2
|
||||||
|
|||||||
Reference in New Issue
Block a user