serve restic: implement accounting for uploads and downloads
This means the bandwidth stats will be correct and the bandwidth throttling will work correctly. This was forgotten as a previous iteration of the code was using the higher level operations.Rcat which took care of this.
This commit is contained in:
parent
38d9475a34
commit
fa867a9a4c
1 changed files with 35 additions and 5 deletions
|
@ -6,6 +6,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
@ -18,6 +19,7 @@ import (
|
||||||
"github.com/ncw/rclone/cmd/serve/httplib"
|
"github.com/ncw/rclone/cmd/serve/httplib"
|
||||||
"github.com/ncw/rclone/cmd/serve/httplib/httpflags"
|
"github.com/ncw/rclone/cmd/serve/httplib/httpflags"
|
||||||
"github.com/ncw/rclone/fs"
|
"github.com/ncw/rclone/fs"
|
||||||
|
"github.com/ncw/rclone/fs/accounting"
|
||||||
"github.com/ncw/rclone/fs/fserrors"
|
"github.com/ncw/rclone/fs/fserrors"
|
||||||
"github.com/ncw/rclone/fs/object"
|
"github.com/ncw/rclone/fs/object"
|
||||||
"github.com/ncw/rclone/fs/operations"
|
"github.com/ncw/rclone/fs/operations"
|
||||||
|
@ -284,16 +286,26 @@ func (s *server) getObject(w http.ResponseWriter, r *http.Request, remote string
|
||||||
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
|
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
accounting.Stats.Transferring(o.Remote())
|
||||||
|
in := accounting.NewAccount(file, o) // account the transfer (no buffering)
|
||||||
defer func() {
|
defer func() {
|
||||||
err := file.Close()
|
closeErr := in.Close()
|
||||||
if err != nil {
|
if closeErr != nil {
|
||||||
fs.Errorf(remote, "Get request: close failed: %v", err)
|
fs.Errorf(remote, "Get request: close failed: %v", closeErr)
|
||||||
|
if err == nil {
|
||||||
|
err = closeErr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ok := err == nil
|
||||||
|
accounting.Stats.DoneTransferring(o.Remote(), ok)
|
||||||
|
if !ok {
|
||||||
|
accounting.Stats.Error(err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
w.WriteHeader(code)
|
w.WriteHeader(code)
|
||||||
|
|
||||||
n, err := io.Copy(w, file)
|
n, err := io.Copy(w, in)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fs.Errorf(remote, "Didn't finish writing GET request (wrote %d/%d bytes): %v", n, size, err)
|
fs.Errorf(remote, "Didn't finish writing GET request (wrote %d/%d bytes): %v", n, size, err)
|
||||||
return
|
return
|
||||||
|
@ -305,8 +317,26 @@ func (s *server) postObject(w http.ResponseWriter, r *http.Request, remote strin
|
||||||
// fs.Debugf(s.f, "content length = %d", r.ContentLength)
|
// fs.Debugf(s.f, "content length = %d", r.ContentLength)
|
||||||
if r.ContentLength >= 0 {
|
if r.ContentLength >= 0 {
|
||||||
// Size known use Put
|
// Size known use Put
|
||||||
|
accounting.Stats.Transferring(remote)
|
||||||
|
body := ioutil.NopCloser(r.Body) // we let the server close the body
|
||||||
|
in := accounting.NewAccountSizeName(body, r.ContentLength, remote) // account the transfer (no buffering)
|
||||||
|
var err error
|
||||||
|
defer func() {
|
||||||
|
closeErr := in.Close()
|
||||||
|
if closeErr != nil {
|
||||||
|
fs.Errorf(remote, "Post request: close failed: %v", closeErr)
|
||||||
|
if err == nil {
|
||||||
|
err = closeErr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ok := err == nil
|
||||||
|
accounting.Stats.DoneTransferring(remote, err == nil)
|
||||||
|
if !ok {
|
||||||
|
accounting.Stats.Error(err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
info := object.NewStaticObjectInfo(remote, time.Now(), r.ContentLength, true, nil, s.f)
|
info := object.NewStaticObjectInfo(remote, time.Now(), r.ContentLength, true, nil, s.f)
|
||||||
_, err := s.f.Put(r.Body, info)
|
_, err = s.f.Put(in, info)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fs.Errorf(remote, "Post request put error: %v", err)
|
fs.Errorf(remote, "Post request put error: %v", err)
|
||||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||||
|
|
Loading…
Reference in a new issue