Skip to content
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

Reintroduce the fsNotify trigger #1562

Merged
merged 2 commits into from
Jan 31, 2019

Conversation

dgageot
Copy link
Contributor

@dgageot dgageot commented Jan 30, 2019

To make sure we don't require CGO, I've added the kqueue tag at build time.
We should test if it behaves as well as the cgo version on OSX

Fixes #1513

cc @ltouati

@codecov-io
Copy link

codecov-io commented Jan 30, 2019

Codecov Report

Merging #1562 into master will decrease coverage by 0.07%.
The diff coverage is 30.76%.

Impacted file tree graph

@@            Coverage Diff            @@
##           master   #1562      +/-   ##
=========================================
- Coverage   46.18%   46.1%   -0.08%     
=========================================
  Files         118     118              
  Lines        4961    4986      +25     
=========================================
+ Hits         2291    2299       +8     
- Misses       2439    2456      +17     
  Partials      231     231
Impacted Files Coverage Δ
cmd/skaffold/app/cmd/dev.go 0% <0%> (ø) ⬆️
pkg/skaffold/watch/triggers.go 52.11% <32%> (-10.94%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update b62bfbb...c58ccb9. Read the comment docs.

@@ -38,7 +38,7 @@ func NewCmdDev(out io.Writer) *cobra.Command {
}
AddRunDevFlags(cmd)
cmd.Flags().BoolVar(&opts.TailDev, "tail", true, "Stream logs from deployed objects")
cmd.Flags().StringVar(&opts.Trigger, "trigger", "polling", "How are changes detected? (polling or manual)")
cmd.Flags().StringVar(&opts.Trigger, "trigger", "polling", "How are changes detected? (polling, manual or notify)")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"notify" is rather specific to Go and Linux. I can't think of a better term, but perhaps we can add some more text to describe it? It's also odd that we use "trigger" here but the related options are "watch".

How are changes detected? (polling, manual or notify) polling periodically looks for new files (see --watch-poll-interval), whereas notify leverages OS filesystem notifications (more efficient). manual waits for keyboard input to trigger a new build.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some documentation would be good, yes.

The idea is that Skaffold knows all the dependencies for an artifact and can compute a "snapshot" of those dependencies (mostly last mod time). Now, to actually recompute a snapshot, do a diff and maybe trigger a rebuild/redeploy, it needs a trigger.
That trigger can be either:

  • a timer, that runs by default every 500ms. but then Skaffold has to compute the list of deps and the mod times every 500ms
  • a manual trigger. The user presses a key when they want Skaffold to compute the diff
  • a inotify based file watcher that watches the workspace as a whole and tells Skaffold.

iNotify based watchers are not good at watching folders and files that might be disapear. but it's quite good at recursively watching a top level folder that's always there.

By combining the snapshot mechanism and a inotify trigger, we get the best of both world.

IDE integration would work the same: The IDE would detect changes, notify Skaffold that "something" changed, no details. Then Skaffold would run a diff

I all cases, Skaffold is capable of debouncing rapid streams of triggers so that it behaves well when a lot of files are changed in a short period of time.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to see this documented so users know what the expected behavior is for each option

@briandealwis
Copy link
Member

briandealwis commented Jan 31, 2019

I've tried this on examples/jib and this doesn't seem to be working: modifying src/main/java/hello/HelloController.java doesn't trigger a rebuild.

What is odd is that touch skaffold.yaml triggers a rebuild and redeploy, and then skaffold consumes 100% CPU. But it's not calling out to Jib.

luser error: I used the wrong command-line flag 🤦‍♂️

Copy link
Contributor

@nkubala nkubala left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a few nits but otherwise LGTM


// Start Listening for file system changes
func (t *fsNotifyTrigger) Start(ctx context.Context) (<-chan bool, error) {
// TODO(@dgageot): If file changes happen too quickly, events might be lost
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we could compute the number of files in the watch directory at start up time and use that for the buffer size. just a thought

@@ -38,7 +38,7 @@ func NewCmdDev(out io.Writer) *cobra.Command {
}
AddRunDevFlags(cmd)
cmd.Flags().BoolVar(&opts.TailDev, "tail", true, "Stream logs from deployed objects")
cmd.Flags().StringVar(&opts.Trigger, "trigger", "polling", "How are changes detected? (polling or manual)")
cmd.Flags().StringVar(&opts.Trigger, "trigger", "polling", "How are changes detected? (polling, manual or notify)")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to see this documented so users know what the expected behavior is for each option

@nkubala nkubala merged commit f0f28e3 into GoogleContainerTools:master Jan 31, 2019
@ltouati
Copy link
Contributor

ltouati commented Feb 2, 2019

Hi @dgageot ,

Unfortunately this does not work for very large projects. Here's the error message I get when working on my project ( multiple maven modules + angular frontend)

Deploy complete in 5.965024794s
Cleaning up...
WARN[0163] cleanup: reading manifests: kubectl create: pipe: too many open files
FATA[0163] unable to start trigger: open /Users/ltouati/Documents/perso/cloud-diagram/frontend/node_modules/rxjs-compat/_esm5/add/operator: too many open files

@briandealwis
Copy link
Member

Could you try doing some digging with lsof and see what process has lots of open files?

@ltouati
Copy link
Contributor

ltouati commented Feb 9, 2019

@briandealwis Given that skaffold dies printing this message I don't see how I can do a lsof on a dead command.
This change behaves the same way as if we were listening files by files which is unworkable on very large repos

@briandealwis
Copy link
Member

Sorry @ltouati! I missed the Cleaning up… part.

@ltouati
Copy link
Contributor

ltouati commented Feb 11, 2019

@briandealwis no worries :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants