-j
There are almost no use cases that require syncing the file. The operating system is designed with a good buffering layer for a reason. If you do have such need, it is trivial to write your own version of WriteFile that does this.
On Thu, 21 Jul 2016 21:17:38 +0200
Manlio Perillo <manlio....@gmail.com> wrote:
> >> What is the reason why ioutil.WriteFile does not call File.Sync?
> >
> > I'd say that's because to inhibit this behaviour when needed you'd
> > need to implement ioutil.WriteFileNoSync() or have an option flag
> > as an argument (remember CreateFile() of Win32 API?).
>
> I'm curious to know why one wants to inhibit the durability behaviour.
> AFAIK, several design choices of Go and its standard library are
> designed to make program safe and robust.
> WriteFile does not follow these principles.
Well, I definitely sympathize your line of reasoning, but it's not that
simple. For instance, a WriteFile() truncates the file when it exists.
A well-written application which wants to _replace_ a file must go this
route:
II. "Robust" approach:
0) Open the directory entry containing the file.
1) Same as (1) above.
2) fsync() the new file's contents.
3) rename() the new file over the old one.
4) fsync() the directory entry containing the file.
Here, (4) is an oft-forgotten task, and it requires the openat()
/ renameat() and other whateverat() functions, and the step (0).
Now here comes another consideration: certain file operations are
atomic on a scale larger than a single file. Consider a package
management program: when it unpacks a package, it makes little sense
making sure each file it unpacks is fdsync()-ed right after it was
written -- simple because it unpacking is terminated, it doesn't matter
whether the files extracted so far actually hit the underlying medium.
So we can unpack and then issue syncfs(2) all them all at once.
What I'm leading to, is that WriteFile() is just a narrowly-scoped
utility function. For advances cases you will almost inevitably
a) think your strategy through; b) write complex custom code.
-j