Skip to content

Commit 1a887d7

Browse files
committed
Enable retries by default on Windows
1 parent f4966f3 commit 1a887d7

File tree

5 files changed

+16
-13
lines changed

5 files changed

+16
-13
lines changed

file/helper_aix.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import (
2424

2525
// SafeFileRotate safely rotates an existing file under path and replaces it with the tempfile
2626
func SafeFileRotate(path, tempfile string, opts ...RotateOpt) error {
27-
options := rotateOpts{}
27+
options := rotateOpts{enableRetries: false}
2828
for _, opt := range opts {
2929
opt(&options)
3030
}

file/helper_common.go

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,30 +23,31 @@ import (
2323
"time"
2424
)
2525

26+
const renameRetryInterval = 50 * time.Millisecond
27+
const renameRetryDuration = 2 * time.Second
28+
2629
type rotateOpts struct {
27-
renameRetryDuration time.Duration
28-
renameRetryInterval time.Duration
30+
enableRetries bool
2931
}
3032

3133
type RotateOpt func(*rotateOpts)
3234

33-
func WithRenameRetries(duration, interval time.Duration) RotateOpt {
35+
func DisableRetries() RotateOpt {
3436
return func(opts *rotateOpts) {
35-
opts.renameRetryDuration = duration
36-
opts.renameRetryInterval = interval
37+
opts.enableRetries = false
3738
}
3839
}
3940

4041
func rename(src, dst string, options rotateOpts) error {
41-
// Perform a regular (non-retrying) rename unless all retry options are specified.
42-
if options.renameRetryDuration == 0 || options.renameRetryInterval == 0 {
42+
// Perform a regular (non-retrying) rename if retries are disabled.
43+
if !options.enableRetries {
4344
return os.Rename(src, dst)
4445
}
4546

4647
// Attempt rename with retries every options.RenameRetryInterval until options.RenameRetryDuration
4748
// has elapsed. This is useful in cases where the destination file may be locked or in use.
4849
var err error
49-
for start := time.Now(); time.Since(start) < options.renameRetryDuration; time.Sleep(options.renameRetryInterval) {
50+
for start := time.Now(); time.Since(start) < renameRetryDuration; time.Sleep(renameRetryInterval) {
5051
err = os.Rename(src, dst)
5152
if err == nil {
5253
// Rename succeeded; no more retries needed
@@ -55,7 +56,7 @@ func rename(src, dst string, options rotateOpts) error {
5556
}
5657

5758
if err != nil {
58-
return fmt.Errorf("failed to rename %s to %s after %v: %w", src, dst, options.renameRetryDuration, err)
59+
return fmt.Errorf("failed to rename %s to %s after %v: %w", src, dst, renameRetryDuration, err)
5960
}
6061

6162
return nil

file/helper_other.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import (
2626

2727
// SafeFileRotate safely rotates an existing file under path and replaces it with the tempfile
2828
func SafeFileRotate(path, tempfile string, opts ...RotateOpt) error {
29-
options := rotateOpts{}
29+
options := rotateOpts{enableRetries: false}
3030
for _, opt := range opts {
3131
opt(&options)
3232
}

file/helper_windows.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ import (
2424

2525
// SafeFileRotate safely rotates an existing file under path and replaces it with the tempfile
2626
func SafeFileRotate(path, tempfile string, opts ...RotateOpt) error {
27-
options := rotateOpts{}
27+
// Enable retries by default on Windows. This is useful in cases where path, the destination
28+
// file may be locked or in use.
29+
options := rotateOpts{enableRetries: true}
2830
for _, opt := range opts {
2931
opt(&options)
3032
}

file/helper_windows_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ func TestSafeFileRotate(t *testing.T) {
5252
defer destFile.Close()
5353

5454
// Try to replace dest with new
55-
err = SafeFileRotate(dest, src, WithRenameRetries(2*time.Second, 100*time.Millisecond))
55+
err = SafeFileRotate(dest, src, DisableRetries(2*time.Second, 100*time.Millisecond))
5656
require.NoError(t, err)
5757

5858
// Check that dest file has been replaced with new file

0 commit comments

Comments
 (0)