diff options
Diffstat (limited to 'system/api/analytics/backup.go')
-rw-r--r-- | system/api/analytics/backup.go | 35 |
1 files changed, 23 insertions, 12 deletions
diff --git a/system/api/analytics/backup.go b/system/api/analytics/backup.go index 07b1a46..46261a1 100644 --- a/system/api/analytics/backup.go +++ b/system/api/analytics/backup.go @@ -1,6 +1,7 @@ package analytics import ( + "context" "fmt" "net/http" "time" @@ -8,19 +9,29 @@ import ( "github.com/boltdb/bolt" ) -// Backup writes a snapshot of the analytics.db database to an HTTP response -func Backup(res http.ResponseWriter) error { - err := store.View(func(tx *bolt.Tx) error { - ts := time.Now().Unix() - disposition := `attachment; filename="analytics-%d.db.bak"` +// Backup writes a snapshot of the system.db database to an HTTP response. The +// output is discarded if we get a cancellation signal. +func Backup(ctx context.Context, res http.ResponseWriter) error { + errChan := make(chan error, 1) - res.Header().Set("Content-Type", "application/octet-stream") - res.Header().Set("Content-Disposition", fmt.Sprintf(disposition, ts)) - res.Header().Set("Content-Length", fmt.Sprintf("%d", int(tx.Size()))) + go func() { + errChan <- store.View(func(tx *bolt.Tx) error { + ts := time.Now().Unix() + disposition := `attachment; filename="analytics-%d.db.bak"` - _, err := tx.WriteTo(res) - return err - }) + res.Header().Set("Content-Type", "application/octet-stream") + res.Header().Set("Content-Disposition", fmt.Sprintf(disposition, ts)) + res.Header().Set("Content-Length", fmt.Sprintf("%d", int(tx.Size()))) + + _, err := tx.WriteTo(res) + return err + }) + }() - return err + select { + case <-ctx.Done(): + return ctx.Err() + case err := <-errChan: + return err + } } |