yandex: add --yandex-upload-wait to fix 500 errors when uploading
In this commit we attempted to wait for the success report of an
upload to fix the 500 error:
fe78b559d1 yandex: fix 500 errors by waiting for uploads to complete before setting modtime
However Yandex Disk finalizes an upload asynchronously on its servers.
Waiting for the upload operation to report success is not enough -
under load the server reports the operation as successful slightly
before the file is fully finalized, so setting the modification time
straight after an upload can still fail with 500 Internal Server
Error.
Yandex support recommend waiting 1.5s - 3s after the upload before
modifying the file's metadata, so add an --yandex-upload-wait option
(default off) to insert a delay between the upload completing and the
modification time being set.
This commit is contained in:
@@ -85,6 +85,21 @@ func init() {
|
||||
Default: true,
|
||||
Advanced: true,
|
||||
Hide: fs.OptionHideConfigurator,
|
||||
}, {
|
||||
Name: "upload_wait",
|
||||
Help: `Wait this long after an upload before setting the modification time.
|
||||
|
||||
Yandex Disk finalizes an upload asynchronously on its servers after
|
||||
the upload has completed. If the modification time is set while this
|
||||
finalization is still in progress the server returns 500 Internal
|
||||
Server Error errors.
|
||||
|
||||
If you are getting 500 errors on upload then setting this to 2s is
|
||||
normally enough to stop them, at the cost of slowing down uploads.
|
||||
|
||||
Yandex support recommend a value of 1.5s - 3s.`,
|
||||
Default: fs.Duration(0),
|
||||
Advanced: true,
|
||||
}}...),
|
||||
})
|
||||
}
|
||||
@@ -95,6 +110,7 @@ type Options struct {
|
||||
HardDelete bool `config:"hard_delete"`
|
||||
Enc encoder.MultiEncoder `config:"encoding"`
|
||||
SpoofUserAgent bool `config:"spoof_ua"`
|
||||
UploadWait fs.Duration `config:"upload_wait"`
|
||||
}
|
||||
|
||||
// Fs represents a remote yandex
|
||||
@@ -1131,9 +1147,24 @@ func (o *Object) upload(ctx context.Context, in io.Reader, overwrite bool, mimeT
|
||||
// Wait for PUT to be committed
|
||||
if ur.OperationID != "" {
|
||||
err = o.fs.waitForJob(ctx, rootURL+"/operations/"+ur.OperationID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
// Wait for the server to finalize the upload before the file's
|
||||
// metadata is accessed. The operation status above can report
|
||||
// success before the finalization has completed, so give the
|
||||
// server some extra time if configured.
|
||||
if o.fs.opt.UploadWait > 0 {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
case <-time.After(time.Duration(o.fs.opt.UploadWait)):
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Update the already existing object
|
||||
|
||||
Reference in New Issue
Block a user