Performance improvements by using a smaller buffer size
This commit is contained in:
parent
999947e387
commit
09826fc7ad
|
@ -357,7 +357,7 @@ func configureLogging(logDir string, debug bool) error {
|
||||||
p := filepath.Join(logDir, "/wings.log")
|
p := filepath.Join(logDir, "/wings.log")
|
||||||
w, err := logrotate.NewFile(p)
|
w, err := logrotate.NewFile(p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(errors.WithMessage(err, "failed to open process log file"))
|
panic(errors.Wrap(err, "failed to open process log file"))
|
||||||
}
|
}
|
||||||
|
|
||||||
log.SetLevel(log.DebugLevel)
|
log.SetLevel(log.DebugLevel)
|
||||||
|
|
|
@ -220,7 +220,8 @@ func postTransfer(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy the file.
|
// Copy the file.
|
||||||
_, err = io.Copy(file, res.Body)
|
buf := make([]byte, 1024 * 4)
|
||||||
|
_, err = io.CopyBuffer(file, res.Body, buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
zap.S().Errorw("failed to copy file to disk", zap.Error(err))
|
zap.S().Errorw("failed to copy file to disk", zap.Error(err))
|
||||||
return
|
return
|
||||||
|
@ -242,7 +243,8 @@ func postTransfer(c *gin.Context) {
|
||||||
|
|
||||||
// Compute the sha256 checksum of the file.
|
// Compute the sha256 checksum of the file.
|
||||||
hash := sha256.New()
|
hash := sha256.New()
|
||||||
if _, err := io.Copy(hash, file); err != nil {
|
buf = make([]byte, 1024 * 4)
|
||||||
|
if _, err := io.CopyBuffer(hash, file, buf); err != nil {
|
||||||
zap.S().Errorw("failed to copy file for checksum verification", zap.Error(err))
|
zap.S().Errorw("failed to copy file for checksum verification", zap.Error(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,7 +101,9 @@ func (a *Archiver) Checksum() (string, error) {
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
|
|
||||||
hash := sha256.New()
|
hash := sha256.New()
|
||||||
if _, err := io.Copy(hash, file); err != nil {
|
|
||||||
|
buf := make([]byte, 1024*4)
|
||||||
|
if _, err := io.CopyBuffer(hash, file, buf); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,9 +29,11 @@ func (a *Archive) Create(dst string, ctx context.Context) (os.FileInfo, error) {
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
|
|
||||||
gzw := gzip.NewWriter(f)
|
gzw := gzip.NewWriter(f)
|
||||||
|
defer gzw.Flush()
|
||||||
defer gzw.Close()
|
defer gzw.Close()
|
||||||
|
|
||||||
tw := tar.NewWriter(gzw)
|
tw := tar.NewWriter(gzw)
|
||||||
|
defer tw.Flush()
|
||||||
defer tw.Close()
|
defer tw.Close()
|
||||||
|
|
||||||
wg := sizedwaitgroup.New(10)
|
wg := sizedwaitgroup.New(10)
|
||||||
|
@ -108,7 +110,8 @@ func (a *Archive) addToArchive(p string, s *os.FileInfo, w *tar.Writer) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := io.Copy(w, f); err != nil {
|
buf := make([]byte, 4*1024)
|
||||||
|
if _, err := io.CopyBuffer(w, f, buf); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -97,12 +97,13 @@ func (b *Backup) Checksum() ([]byte, error) {
|
||||||
|
|
||||||
f, err := os.Open(b.Path())
|
f, err := os.Open(b.Path())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return []byte{}, errors.WithStack(err)
|
return nil, errors.WithStack(err)
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
|
|
||||||
if _, err := io.Copy(h, f); err != nil {
|
buf := make([]byte, 1024*4)
|
||||||
return []byte{}, errors.WithStack(err)
|
if _, err := io.CopyBuffer(h, f, buf); err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return h.Sum(nil), nil
|
return h.Sum(nil), nil
|
||||||
|
@ -123,7 +124,7 @@ func (b *Backup) Details() *ArchiveDetails {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithFields(log.Fields{
|
log.WithFields(log.Fields{
|
||||||
"backup": b.Identifier(),
|
"backup": b.Identifier(),
|
||||||
"error": err,
|
"error": err,
|
||||||
}).Error("failed to calculate checksum for backup")
|
}).Error("failed to calculate checksum for backup")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
@ -343,36 +342,11 @@ func (fs *Filesystem) Writefile(p string, r io.Reader) error {
|
||||||
}
|
}
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
|
|
||||||
// Create a new buffered writer that will write to the file we just opened
|
buf := make([]byte, 1024*4)
|
||||||
// and stream in the contents from the reader.
|
sz, err := io.CopyBuffer(file, r, buf)
|
||||||
w := bufio.NewWriter(file)
|
|
||||||
buf := make([]byte, 1024)
|
|
||||||
|
|
||||||
var sizeWritten int
|
|
||||||
|
|
||||||
for {
|
|
||||||
n, err := r.Read(buf)
|
|
||||||
if err != nil && err != io.EOF {
|
|
||||||
return errors.WithStack(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if n == 0 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
if sz, err := w.Write(buf[:n]); err != nil {
|
|
||||||
return errors.WithStack(err)
|
|
||||||
} else {
|
|
||||||
sizeWritten += sz
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := w.Flush(); err != nil {
|
|
||||||
return errors.WithStack(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Adjust the disk usage to account for the old size and the new size of the file.
|
// Adjust the disk usage to account for the old size and the new size of the file.
|
||||||
atomic.AddInt64(&fs.diskUsage, int64(sizeWritten) - currentSize)
|
atomic.AddInt64(&fs.diskUsage, sz-currentSize)
|
||||||
|
|
||||||
// Finally, chown the file to ensure the permissions don't end up out-of-whack
|
// Finally, chown the file to ensure the permissions don't end up out-of-whack
|
||||||
// if we had just created it.
|
// if we had just created it.
|
||||||
|
|
|
@ -7,11 +7,9 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/mholt/archiver/v3"
|
"github.com/mholt/archiver/v3"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"io"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
)
|
)
|
||||||
|
@ -88,53 +86,19 @@ func (fs *Filesystem) DecompressFile(dir string, file string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return fs.extractFileFromArchive(f)
|
var name string
|
||||||
|
|
||||||
|
switch s := f.Sys().(type) {
|
||||||
|
case *tar.Header:
|
||||||
|
name = s.Name
|
||||||
|
case *gzip.Header:
|
||||||
|
name = s.Name
|
||||||
|
case *zip.FileHeader:
|
||||||
|
name = s.Name
|
||||||
|
default:
|
||||||
|
return errors.New(fmt.Sprintf("could not parse underlying data source with type %s", reflect.TypeOf(s).String()))
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors.Wrap(fs.Writefile(name, f), "could not extract file from archive")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extracts a single file from the archive and writes it to the disk after verifying that it will end
|
|
||||||
// up in the server data directory.
|
|
||||||
func (fs *Filesystem) extractFileFromArchive(f archiver.File) error {
|
|
||||||
var name string
|
|
||||||
|
|
||||||
switch s := f.Sys().(type) {
|
|
||||||
case *tar.Header:
|
|
||||||
name = s.Name
|
|
||||||
case *gzip.Header:
|
|
||||||
name = s.Name
|
|
||||||
case *zip.FileHeader:
|
|
||||||
name = s.Name
|
|
||||||
default:
|
|
||||||
return errors.New(fmt.Sprintf("could not parse underlying data source with type %s", reflect.TypeOf(s).String()))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Guard against a zip-slip attack and prevent writing a file to a destination outside of
|
|
||||||
// the server root directory.
|
|
||||||
p, err := fs.SafePath(name)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure the directory structure for this file exists before trying to write the file
|
|
||||||
// to the disk, otherwise we'll have some unexpected fun.
|
|
||||||
if err := os.MkdirAll(strings.TrimSuffix(p, filepath.Base(p)), 0755); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Open the file and truncate it if it already exists.
|
|
||||||
o, err := os.OpenFile(p, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
defer o.Close()
|
|
||||||
|
|
||||||
sz, cerr := io.Copy(o, f)
|
|
||||||
if cerr != nil {
|
|
||||||
return errors.WithStack(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
atomic.AddInt64(&fs.diskUsage, sz)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -295,11 +295,11 @@ func (ip *InstallationProcess) pullInstallationImage() error {
|
||||||
func (ip *InstallationProcess) BeforeExecute() (string, error) {
|
func (ip *InstallationProcess) BeforeExecute() (string, error) {
|
||||||
fileName, err := ip.writeScriptToDisk()
|
fileName, err := ip.writeScriptToDisk()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.WithMessage(err, "failed to write installation script to disk")
|
return "", errors.Wrap(err, "failed to write installation script to disk")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := ip.pullInstallationImage(); err != nil {
|
if err := ip.pullInstallationImage(); err != nil {
|
||||||
return "", errors.WithMessage(err, "failed to pull updated installation container image for server")
|
return "", errors.Wrap(err, "failed to pull updated installation container image for server")
|
||||||
}
|
}
|
||||||
|
|
||||||
opts := types.ContainerRemoveOptions{
|
opts := types.ContainerRemoveOptions{
|
||||||
|
@ -309,7 +309,7 @@ func (ip *InstallationProcess) BeforeExecute() (string, error) {
|
||||||
|
|
||||||
if err := ip.client.ContainerRemove(ip.context, ip.Server.Id()+"_installer", opts); err != nil {
|
if err := ip.client.ContainerRemove(ip.context, ip.Server.Id()+"_installer", opts); err != nil {
|
||||||
if !client.IsErrNotFound(err) {
|
if !client.IsErrNotFound(err) {
|
||||||
return "", errors.WithMessage(err, "failed to remove existing install container for server")
|
return "", errors.Wrap(err, "failed to remove existing install container for server")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -84,12 +84,12 @@ func LoadDirectory() error {
|
||||||
func FromConfiguration(data *api.ServerConfigurationResponse) (*Server, error) {
|
func FromConfiguration(data *api.ServerConfigurationResponse) (*Server, error) {
|
||||||
cfg := Configuration{}
|
cfg := Configuration{}
|
||||||
if err := defaults.Set(&cfg); err != nil {
|
if err := defaults.Set(&cfg); err != nil {
|
||||||
return nil, errors.WithMessage(err, "failed to set struct defaults for server configuration")
|
return nil, errors.Wrap(err, "failed to set struct defaults for server configuration")
|
||||||
}
|
}
|
||||||
|
|
||||||
s := new(Server)
|
s := new(Server)
|
||||||
if err := defaults.Set(s); err != nil {
|
if err := defaults.Set(s); err != nil {
|
||||||
return nil, errors.WithMessage(err, "failed to set struct defaults for server")
|
return nil, errors.Wrap(err, "failed to set struct defaults for server")
|
||||||
}
|
}
|
||||||
|
|
||||||
s.cfg = cfg
|
s.cfg = cfg
|
||||||
|
|
|
@ -62,13 +62,13 @@ func (s *Server) HandlePowerAction(action PowerAction, waitSeconds ...int) error
|
||||||
// time than that passes an error will be propagated back up the chain and this
|
// time than that passes an error will be propagated back up the chain and this
|
||||||
// request will be aborted.
|
// request will be aborted.
|
||||||
if err := s.powerLock.Acquire(ctx, 1); err != nil {
|
if err := s.powerLock.Acquire(ctx, 1); err != nil {
|
||||||
return errors.WithMessage(err, "could not acquire lock on power state")
|
return errors.Wrap(err, "could not acquire lock on power state")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// If no wait duration was provided we will attempt to immediately acquire the lock
|
// If no wait duration was provided we will attempt to immediately acquire the lock
|
||||||
// and bail out with a context deadline error if it is not acquired immediately.
|
// and bail out with a context deadline error if it is not acquired immediately.
|
||||||
if ok := s.powerLock.TryAcquire(1); !ok {
|
if ok := s.powerLock.TryAcquire(1); !ok {
|
||||||
return errors.WithMessage(context.DeadlineExceeded, "could not acquire lock on power state")
|
return errors.Wrap(context.DeadlineExceeded, "could not acquire lock on power state")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,7 +132,7 @@ func (s *Server) onBeforeStart() error {
|
||||||
|
|
||||||
s.Log().Info("syncing server configuration with panel")
|
s.Log().Info("syncing server configuration with panel")
|
||||||
if err := s.Sync(); err != nil {
|
if err := s.Sync(); err != nil {
|
||||||
return errors.WithMessage(err, "unable to sync server data from Panel instance")
|
return errors.Wrap(err, "unable to sync server data from Panel instance")
|
||||||
}
|
}
|
||||||
|
|
||||||
if !s.Filesystem.HasSpaceAvailable() {
|
if !s.Filesystem.HasSpaceAvailable() {
|
||||||
|
@ -150,7 +150,7 @@ func (s *Server) onBeforeStart() error {
|
||||||
s.PublishConsoleOutputFromDaemon("Ensuring file permissions are set correctly, this could take a few seconds...")
|
s.PublishConsoleOutputFromDaemon("Ensuring file permissions are set correctly, this could take a few seconds...")
|
||||||
// Ensure all of the server file permissions are set correctly before booting the process.
|
// Ensure all of the server file permissions are set correctly before booting the process.
|
||||||
if err := s.Filesystem.Chown("/"); err != nil {
|
if err := s.Filesystem.Chown("/"); err != nil {
|
||||||
return errors.WithMessage(err, "failed to chown root server directory during pre-boot process")
|
return errors.Wrap(err, "failed to chown root server directory during pre-boot process")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
Loading…
Reference in New Issue
Block a user