Machine mount sync package - initial version - #10332
Conversation
| // SaveIndex atomically saves the provided index under a given path. | ||
| func SaveIndex(idx *Index, path string) (err error) { | ||
| dir, name := filepath.Split(path) | ||
| f, err := ioutil.TempFile(dir, name+"_") |
There was a problem hiding this comment.
Why do you need name+"_", the file is going to be suffixed either way?
f, err := ioutil.TempFile(filepath.Split(path))|
@ppknap Please rebase. |
| if opts.Log != nil { | ||
| s.log = opts.Log.New("sync") | ||
| } else { | ||
| s.log = machine.DefaultLogger.New("sync") |
There was a problem hiding this comment.
This could be a global var.
There was a problem hiding this comment.
Sorry but I can't see any advantages of this approach. However, I see one big disadvantage which is an introduction of global variable used only in one place as a fallback to incomplete options(used in tests) inside the type that is meant to be used as singleton.
There was a problem hiding this comment.
I do not quite follow, since you're using a global variable either way (machine.DefaultLogger) - I just commented to do the same here - use a global variable instead of allocating new default logger each time.
There was a problem hiding this comment.
The root logger machine.DefaultLogger is a parent for other loggers and it uses config.Konfig.Debug variable during its initialization.
Actually, I'm avoiding unnecessary allocation by not defining global variable. Please note, that this branch is a fallback which normally will not be executed.
| sd, ok := s.syncs[id] | ||
| s.mu.RUnlock() | ||
|
|
||
| if ok { |
There was a problem hiding this comment.
I'm not sure these fine-grained locks are correct. Two different threads can simultaneously pass this check and both can assign a new *synced value with the same id to the map. While if the whole body was protected with a single lock, the second thread would fail here.
There was a problem hiding this comment.
the funny fact is that we don't care.. even if IDs are the same (which is not possible in valid logic), the only inconsistency will be that we fetch index twice (or just load it from cache) and swap the file atomically.
This is a trade off I had to make if I want to add mounts concurrently (during kd initialization). newSync may be slow and I want to avoid synchronous initialization process.
I will add:
s.mu.Lock()
if _, ok := s.syncs[id]; ok {
s.mu.Unlock()
return //some fancy error here
}
s.syncs[id] = sd
s.mu.Unlock()97268ee to
2643921
Compare
|
@rjeczalik done |
| // mktree ensures that synced working directory is created. | ||
| func (s *synced) mktree() error { | ||
| dataPath := filepath.Join(s.wd, "data") | ||
| info, err := os.Stat(dataPath) |
There was a problem hiding this comment.
prob MkdirAll is enough, it already handles Stat as fast path https://golang.org/src/os/path.go?s=537:766
Depends on:
#10306Code coverage: 81.8% of statements
Architecture
How Has This Been Tested?
Unit tests.
Screenshots (if appropriate):
none
Types of changes