-
Notifications
You must be signed in to change notification settings - Fork 1.7k
fix: Avoid sync retry if file/directory was not found #9721
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
base: main
Are you sure you want to change the base?
Conversation
|
@plumpy hi! Could you please check it? |
pkg/skaffold/runner/dev.go
Outdated
| func() error { | ||
| return syncHandler(s) | ||
| err := syncHandler(s) | ||
| if err == nil || strings.Contains(err.Error(), "no such file or directory") { |
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.
Can you use os.IsNotExist instead of string matching?
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.
Good idea, thank you! pushed change
Signed-off-by: Suleiman Dibirov <idsulik@gmail.com>
Signed-off-by: Suleiman Dibirov <idsulik@gmail.com>
pkg/skaffold/runner/dev.go
Outdated
| func() error { | ||
| return syncHandler(s) | ||
| err := syncHandler(s) | ||
| if err == nil || os.IsNotExist(err) { |
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.
So this essentially swallows the NotExist error entirely, treats it as though it wasn't an error at all. Is that the correct thing to do here?
The other option is to wrap it in PermanentError which will stop the retries, but still return it from backoff.Retry, and eventually it'll get returned from doDev on line 112.
But maybe that's not the right thing to do because a deleted file is intended and not an error?
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.
Improved the logic. This approach ensures that:
- Deleted files stop retrying immediately and log an informative message
- Other transient errors get retried (up to 3 times as configured)
- Persistent errors are logged, but don't stop the entire dev loop
- The dev loop continues processing other sync items even if one fails
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.
I guess this just feels like the wrong place for this. We're way too high up in the stack.
The syncHandler handles syncing every file in s.Copy and s.Delete. There could be dozens of files there. If one of them ends in a IsNotExist error, we didn't actually necessarily finish syncing all the files, right? We just gave up halfway through. There could be other errors we don't know about and other files we never got around to syncing.
So it feels like the syncer is going to have to be the one who decides if an IsNotExist error is relevant or not? If it's not relevant it shouldn't even return the error.
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.
If you mean this part:
if err != nil {
log.Entry(ctx).Warnf("Sync failed after retries for %s: %v", s.Image, err)
continue
}
Then yes, probably you're right, I can rollback the "return" statement
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.
No, I mean something like this:
- syncHandler calls
Sync()with a list of (for example) 50 files Sync()starts looping through those files- on the third file, it can't find the file and returns a file-not-found error
- notice: Files 4-50 are never synced!
- your retry code gets this error, calls
IsNotExiston it, stops the retry and returnsnil, forever hiding the fact that there was an errorif os.IsNotExist(err) { log.Entry(ctx).Infof("Skipping sync for %s: file no longer exists", s.Image) return nil } - the caller thinks the files are synced, but most of them are not!
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.
Thank you for the clarification, you're right, it's not a good idea to swallow the error. Pushed commit where I wrapped not found error in Permanent error, as you suggested before, now it prints the error and continues syncing other files
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.
And, it is correct now, because it doesn't stop syncing other change sets if something happened with 1 change set.
Instead of return in case of error, it uses continue now
Signed-off-by: Suleiman Dibirov <idsulik@gmail.com>
Signed-off-by: Suleiman Dibirov <idsulik@gmail.com>
Description
This PR prevents sync retry if the
erris related to a missing file/folder. For example - if you use npm to develop, it removes old files and generates new, and if you change files a lot, then the skaffold will try to sync old files several times, but they're deleted.User facing changes (remove if N/A)
Before: Retry sync if a file/folder wasn't found.
After: No retry if a file/folder wasn't found.