-
Notifications
You must be signed in to change notification settings - Fork 25.3k
Ensure config reload on ..data symlink switch for CSI driver support #127628
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
3cb7b59
1c0c99c
3850598
d68fbfb
ad870c6
a166ff0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
pr: 127628 | ||
summary: Ensure config reload on ..data symlink switch for CSI driver support | ||
area: Infra/Settings | ||
type: enhancement | ||
issues: [] |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,11 +27,11 @@ | |
import java.nio.file.attribute.BasicFileAttributes; | ||
import java.nio.file.attribute.FileTime; | ||
import java.util.HashMap; | ||
import java.util.HashSet; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.Set; | ||
import java.util.concurrent.ExecutionException; | ||
import java.util.stream.Collectors; | ||
import java.util.stream.Stream; | ||
|
||
/** | ||
|
@@ -237,14 +237,16 @@ protected final void watcherThread() { | |
key.reset(); | ||
|
||
if (key == settingsDirWatchKey) { | ||
// there may be multiple events for the same file - we only want to re-read once | ||
Set<Path> processedFiles = new HashSet<>(); | ||
for (WatchEvent<?> e : events) { | ||
Path fullFile = settingsDir.resolve(e.context().toString()); | ||
if (processedFiles.add(fullFile)) { | ||
if (fileChanged(fullFile)) { | ||
process(fullFile); | ||
} | ||
Set<Path> changedPaths = events.stream() | ||
.map(event -> settingsDir.resolve(event.context().toString())) | ||
.collect(Collectors.toSet()); | ||
for (var changedPath : changedPaths) { | ||
// If a symlinked dir changed in the settings dir, it could be linked to other symlinks, so reprocess all files | ||
if (filesIsDirectory(changedPath) && filesIsSymbolicLink(changedPath)) { | ||
reprocessAllChangedFilesInSettingsDir(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do we need to reprocess the entire settings dir, instead of just what the symbolic link points at? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that if we only want to reprocess what's in the This works under the assumption that the target file and symlink has the same name, which I think is acceptable in this case since it's a directory symlink. In practice (at least in serverless) all files in the settings directory ( |
||
break; | ||
} else if (fileChanged(changedPath)) { | ||
process(changedPath); | ||
} | ||
} | ||
} else if (key == configDirWatchKey) { | ||
|
@@ -257,14 +259,7 @@ protected final void watcherThread() { | |
settingsDirWatchKey = enableDirectoryWatcher(settingsDirWatchKey, settingsDir); | ||
|
||
// re-read the settings directory, and ping for any changes | ||
try (Stream<Path> files = filesList(settingsDir)) { | ||
for (var f = files.iterator(); f.hasNext();) { | ||
Path file = f.next(); | ||
if (fileChanged(file)) { | ||
process(file); | ||
} | ||
} | ||
} | ||
reprocessAllChangedFilesInSettingsDir(); | ||
} else if (settingsDirWatchKey != null) { | ||
settingsDirWatchKey.cancel(); | ||
} | ||
|
@@ -279,6 +274,17 @@ protected final void watcherThread() { | |
} | ||
} | ||
|
||
private void reprocessAllChangedFilesInSettingsDir() throws IOException, InterruptedException { | ||
try (Stream<Path> files = filesList(settingsDir)) { | ||
for (var f = files.iterator(); f.hasNext();) { | ||
Path file = f.next(); | ||
if (fileChanged(file)) { | ||
process(file); | ||
} | ||
} | ||
} | ||
} | ||
|
||
protected final synchronized void stopWatcher() { | ||
if (watching()) { | ||
logger.debug("stopping watcher ..."); | ||
|
@@ -378,6 +384,8 @@ private record FileUpdateState(long timestamp, String path, Object fileKey) {} | |
|
||
protected abstract boolean filesIsDirectory(Path path); | ||
|
||
protected abstract boolean filesIsSymbolicLink(Path path); | ||
|
||
protected abstract <A extends BasicFileAttributes> A filesReadAttributes(Path path, Class<A> clazz) throws IOException; | ||
|
||
protected abstract Stream<Path> filesList(Path dir) throws IOException; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test fails on linux without the changes to
AbstractFileWatchingService
.