Skip to content

Commit ab8a201

Browse files
authored
Merge pull request #74 from netlify/too-many-open-files
Do not keep all file handles open at the same time
2 parents 85c5c69 + 4301a1b commit ab8a201

File tree

1 file changed

+31
-43
lines changed

1 file changed

+31
-43
lines changed

go/porcelain/deploy.go

Lines changed: 31 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import (
77
"crypto/sha256"
88
"encoding/hex"
99
"fmt"
10-
"hash"
1110
"io"
1211
"io/ioutil"
1312
"os"
@@ -78,39 +77,25 @@ type uploadError struct {
7877

7978
type FileBundle struct {
8079
Name string
81-
SHA hash.Hash
80+
Sum string
8281

82+
// Path OR Buffer should be populated
83+
Path string
8384
Buffer io.ReadSeeker
8485
}
8586

86-
func (f *FileBundle) Sum() string {
87-
return hex.EncodeToString(f.SHA.Sum(nil))
88-
}
89-
9087
func (f *FileBundle) Read(p []byte) (n int, err error) {
9188
return f.Buffer.Read(p)
9289
}
9390

94-
func (f *FileBundle) Close() error {
95-
return nil
91+
func (f *FileBundle) Seek(offset int64, whence int) (int64, error) {
92+
return f.Buffer.Seek(offset, whence)
9693
}
9794

98-
// We're mocking up a closer, to make sure the underlying file handle
99-
// doesn't get closed during an upload, but can be rewinded for retries
100-
// This method closes the file handle for real.
101-
func (f *FileBundle) CloseForReal() error {
102-
closer, ok := f.Buffer.(io.Closer)
103-
if ok {
104-
return closer.Close()
105-
}
95+
func (f *FileBundle) Close() error {
10696
return nil
10797
}
10898

109-
func (f *FileBundle) Rewind() error {
110-
_, err := f.Buffer.Seek(0, 0)
111-
return err
112-
}
113-
11499
type deployFiles struct {
115100
Files map[string]*FileBundle
116101
Sums map[string]string
@@ -126,12 +111,10 @@ func newDeployFiles() *deployFiles {
126111
}
127112

128113
func (d *deployFiles) Add(p string, f *FileBundle) {
129-
sum := f.Sum()
130-
131114
d.Files[p] = f
132-
d.Sums[p] = sum
133-
list, _ := d.Hashed[sum]
134-
d.Hashed[sum] = append(list, f)
115+
d.Sums[p] = f.Sum
116+
list, _ := d.Hashed[f.Sum]
117+
d.Hashed[f.Sum] = append(list, f)
135118
}
136119

137120
func (n *Netlify) overCommitted(d *deployFiles) bool {
@@ -374,7 +357,7 @@ func (n *Netlify) uploadFile(ctx context.Context, d *models.Deploy, f *FileBundl
374357
context.GetLogger(ctx).WithFields(logrus.Fields{
375358
"deploy_id": d.ID,
376359
"file_path": f.Name,
377-
"file_sum": f.Sum(),
360+
"file_sum": f.Sum,
378361
}).Debug("Uploading file")
379362

380363
b := backoff.NewExponentialBackOff()
@@ -404,21 +387,28 @@ func (n *Netlify) uploadFile(ctx context.Context, d *models.Deploy, f *FileBundl
404387

405388
switch t {
406389
case fileUpload:
407-
params := operations.NewUploadDeployFileParams().WithDeployID(d.ID).WithPath(f.Name).WithFileBody(f)
408-
if timeout != 0 {
409-
params.SetTimeout(timeout)
390+
var body io.ReadCloser
391+
body, operationError = os.Open(f.Path)
392+
if operationError == nil {
393+
defer body.Close()
394+
params := operations.NewUploadDeployFileParams().WithDeployID(d.ID).WithPath(f.Name).WithFileBody(body)
395+
if timeout != 0 {
396+
params.SetTimeout(timeout)
397+
}
398+
_, operationError = n.Operations.UploadDeployFile(params, authInfo)
410399
}
411-
_, operationError = n.Operations.UploadDeployFile(params, authInfo)
412400
case functionUpload:
413401
params := operations.NewUploadDeployFunctionParams().WithDeployID(d.ID).WithName(f.Name).WithFileBody(f)
414402
if timeout != 0 {
415403
params.SetTimeout(timeout)
416404
}
417405
_, operationError = n.Operations.UploadDeployFunction(params, authInfo)
406+
if operationError != nil {
407+
f.Buffer.Seek(0, 0)
408+
}
418409
}
419410

420411
if operationError != nil {
421-
f.Rewind()
422412
context.GetLogger(ctx).WithError(operationError).Errorf("Failed to upload file %v", f.Name)
423413
apiErr, ok := operationError.(errors.Error)
424414

@@ -427,10 +417,7 @@ func (n *Netlify) uploadFile(ctx context.Context, d *models.Deploy, f *FileBundl
427417
sharedErr.err = operationError
428418
sharedErr.mutex.Unlock()
429419
}
430-
} else {
431-
f.CloseForReal()
432420
}
433-
434421
return operationError
435422
}, b)
436423

@@ -475,18 +462,19 @@ func walk(dir string, observer DeployObserver) (*deployFiles, error) {
475462
if err != nil {
476463
return err
477464
}
465+
defer o.Close()
478466

479467
file := &FileBundle{
480468
Name: rel,
481-
SHA: sha1.New(),
469+
Path: path,
482470
}
483471

484-
if _, err := io.Copy(file.SHA, o); err != nil {
472+
s := sha1.New()
473+
if _, err := io.Copy(s, o); err != nil {
485474
return err
486475
}
476+
file.Sum = hex.EncodeToString(s.Sum(nil))
487477

488-
o.Seek(0, 0)
489-
file.Buffer = o
490478
files.Add(rel, file)
491479

492480
if observer != nil {
@@ -517,9 +505,9 @@ func bundle(functionDir string, observer DeployObserver) (*deployFiles, error) {
517505
case ".js":
518506
file := &FileBundle{
519507
Name: strings.TrimSuffix(i.Name(), filepath.Ext(i.Name())),
520-
SHA: sha256.New(),
521508
}
522509

510+
s := sha256.New()
523511
buf := new(bytes.Buffer)
524512
archive := zip.NewWriter(buf)
525513
fileHeader, err := archive.Create(i.Name())
@@ -530,6 +518,7 @@ func bundle(functionDir string, observer DeployObserver) (*deployFiles, error) {
530518
if err != nil {
531519
return nil, err
532520
}
521+
defer fileEntry.Close()
533522
if _, err = io.Copy(fileHeader, fileEntry); err != nil {
534523
return nil, err
535524
}
@@ -539,13 +528,12 @@ func bundle(functionDir string, observer DeployObserver) (*deployFiles, error) {
539528
}
540529

541530
fileBuffer := new(bytes.Buffer)
542-
m := io.MultiWriter(file.SHA, fileBuffer)
531+
m := io.MultiWriter(s, fileBuffer)
543532

544533
if _, err := io.Copy(m, buf); err != nil {
545534
return nil, err
546535
}
547-
548-
fileEntry.Seek(0, 0)
536+
file.Sum = hex.EncodeToString(s.Sum(nil))
549537
file.Buffer = bytes.NewReader(fileBuffer.Bytes())
550538
functions.Add(file.Name, file)
551539

0 commit comments

Comments
 (0)