Skip to content

Commit 937ad8d

Browse files
author
Qingping Hou
committed
fix: make file download atomic from filesystem point of view
fix #3
1 parent c4e9001 commit 937ad8d

1 file changed

Lines changed: 11 additions & 6 deletions

File tree

pkg/sync/pull.go

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package sync
33
import (
44
"fmt"
55
"io"
6+
"io/ioutil"
67
"os"
78
"path/filepath"
89
"strings"
@@ -98,20 +99,24 @@ func (self *Puller) downloadHandler(task DownloadTask, downloader GenericDownloa
9899
}
99100

100101
// create file
101-
file, err := os.OpenFile(task.LocalPath, os.O_WRONLY|os.O_CREATE, 0666)
102+
tmpfile, err := ioutil.TempFile(os.TempDir(), "objinsync-download-")
102103
if err != nil {
103-
self.errMsgQueue <- fmt.Sprintf("Failed to create file %s for download: %v", task.LocalPath, err)
104+
self.errMsgQueue <- fmt.Sprintf("Failed to create file %s for download: %v", tmpfile.Name(), err)
104105
return
105106
}
106-
defer file.Close()
107-
file.Truncate(0)
108-
file.Seek(0, 0)
109107

110-
downloader.Download(file, &s3.GetObjectInput{
108+
downloader.Download(tmpfile, &s3.GetObjectInput{
111109
Bucket: aws.String(bucket),
112110
Key: aws.String(key),
113111
})
114112

113+
// use rename to make file update atomic
114+
err = os.Rename(tmpfile.Name(), task.LocalPath)
115+
if err != nil {
116+
self.errMsgQueue <- fmt.Sprintf("Failed to replace file %s for download: %v", task.LocalPath, err)
117+
return
118+
}
119+
115120
// update cache with new object ID
116121
self.uidLock.Lock()
117122
l.Debugw("Updaing uid cache", "key", task.Uri, "val", task.Uid)

0 commit comments

Comments
 (0)