-
Notifications
You must be signed in to change notification settings - Fork 405
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
support go modules projects #50
Conversation
@jonjohnsonjr I think I have addressed all your last requests. About the test project that is copied to the If you think that duplicating these files is not the way to go I can try it again. |
One thing to mention is that there is a lot of code duplication on the tests. I have changed it, but I think it would make this PR too overwhelming. So I'm making it to another PR as a follow-up. |
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 think it would be better to simply duplicate it, as it allows this two tests projects be independent
Sounds good to me.
I just built this and tried it on knative/serving -- it slows things down pretty tremendously... 30 seconds became 560 seconds 😿
This ends up shelling out to go list
several thousand times -- I'm not sure if it's causing the scheduler to thrash or just eating up CPU, but I think it's too much of a performance regression to merge as is :/
Ideally, this is something we can fix, but if it's not we might have to make some more drastic changes to support go modules (by making it easier to detect when we should do a build, e.g. #9
cc @mattmoor
@@ -86,19 +86,41 @@ func NewGo(options ...Option) (Interface, error) { | |||
return gbo.Open() | |||
} | |||
|
|||
// findImportPath uses the go list command to find the full import path from a package. | |||
func (g *gobuild) findImportPath(importPath, format string) (string, 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.
Can these calls be stored in a cache and then flushed each time a file change is detected? This will likely provide an enormous speedup.
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.
Maybe -- we still have to call that once per unique string in the input yaml, so this would help a bit but not that much.
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.
Hmmm - could calling go list once at the top level work? That way you could avoid having to deal with lots of go list calls.
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.
We could do this in batch, go list accepts multiples packages as argument, would need to try this out. @jonjohnsonjr can you share to me how to reproduce the ko resolve from knative that you tried?
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'm also trying to figure someway to prune some of these unique strings on the input yaml, because not every string are actually valid packages names right?
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 share to me how to reproduce the ko resolve from knative that you tried?
Clone https://github.com/knative/serving and run ko resolve -f config/
.
not every string are actually valid packages names right
Yeah we could do some filtering, but I think most strings are going to be potentially valid packages.
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 think I got it to a time that is fine. The biggest culprit for this slow down was that the method isSupportedReference
was being called a lot of times.
I have done two things:
- Pruned some invalid package names (found a way based on the internal load packing from the Go command);
- Cached the result of this method for each import path;
We sure could try to batch go list
calls, but that would make it require a lot more effort and I think that should be done in the future.
Also I have some doubts of which strings we do try to build and replace on the YAML, currently we try check every string from the YAML, such as: normal strings, map keys, map values and array, do we actually need them all?
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.
@jonjohnsonjr I tested out on the knative's serving repo and it was down to 35~40 seconds on my machine, can you run this test on your side as well?
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.
Friendly ping @jonjohnsonjr.
Also @clrprod as you pointed out to cache the results.
@@ -65,15 +69,42 @@ func (c *Caching) Build(ip string) (v1.Image, error) { | |||
return f.Get() | |||
} | |||
|
|||
// SafeArg is used to check if the import path is valid. | |||
// Copy of github.com/golang/go/blob/master/src/cmd/go/internal/load/pkg.go | |||
func SafeArg(name string) bool { |
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'd move this into gobuild.go
Going to think out loud a bit here, let me know if I'm misunderstanding something about go modules or have missed something: In a world with just GOPATH, there was a single namespace for packages. They were all rooted at GOPATH, and you could simply read from the filesystem to find the package. With go modules, there is a second namespace introduced by the So here's what I'm thinking: We call If Some things I'm not sure about: Should we still fall back to looking in GOPATH for packages if a project is using go modules? Or do we only expect to build/reference packages that are within a single project? Is it okay that we only look in the current directory for |
@jonjohnsonjr as for I know, in I think the build process is same for regular projects located in It is fair to expect only to build/reference packages that are within a single project/monorepo, anyway if The flow you stated above should work. e.g., # go-module enabled projects (truncation prefix from importpaths)
go build -o bin/account-srv ./srv/account
go build -o bin/emailer-srv ./srv/emailer
# non go-module projects (no truncation for importpaths)
go build -o bin/account-srv github.com/xmlking/micro-starter-kit/srv/account
go build -o bin/emailer-srv github.com/xmlking/micro-starter-kit/srv/emailer
you can use my repo for testing as it is monorepo and using go-module |
This is the continuation of #19, I made some bad pushes and the PR was closed, so I'm opening this again.
Fixes #7