-
Notifications
You must be signed in to change notification settings - Fork 573
compiler: use hash calculation for determining archive staleness #805
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: master
Are you sure you want to change the base?
Changes from 1 commit
e807fdb
e615455
69257f7
f6baa10
41c38df
d73d4bb
9c06cba
82f8b60
2e40249
3d5665a
5c358e3
1ed4e6a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -30,6 +30,25 @@ import ( | |
| "golang.org/x/tools/go/buildutil" | ||
| ) | ||
|
|
||
| const ( | ||
| hashDebug = false | ||
| ) | ||
|
|
||
| var ( | ||
| compilerBinaryHash string | ||
| ) | ||
|
|
||
| func init() { | ||
| // We do this here because it will only fail in truly bad situations, i.e. | ||
| // machine running out of resources. We also panic if there is a problem | ||
| // because it's unlikely anything else will be useful/work | ||
| h, err := hashCompilerBinary() | ||
| if err != nil { | ||
| panic(err) | ||
| } | ||
| compilerBinaryHash = h | ||
| } | ||
|
|
||
| type ImportCError struct { | ||
| pkgPath string | ||
| } | ||
|
|
@@ -592,17 +611,9 @@ func (s *Session) buildImportPathWithSrcDir(path string, srcDir string) (*Packag | |
| return pkg, archive, nil | ||
| } | ||
|
|
||
| const ( | ||
| hashDebug = false | ||
| ) | ||
|
|
||
| var ( | ||
| gopherJsBinaryHash string | ||
| ) | ||
|
|
||
| func hashGopherJsBinary() (string, error) { | ||
| if gopherJsBinaryHash != "" { | ||
| return gopherJsBinaryHash, nil | ||
| func hashCompilerBinary() (string, error) { | ||
| if compilerBinaryHash != "" { | ||
| return compilerBinaryHash, nil | ||
| } | ||
|
|
||
| binHash := sha256.New() | ||
|
|
@@ -618,8 +629,8 @@ func hashGopherJsBinary() (string, error) { | |
| if _, err := io.Copy(binHash, binFile); err != nil { | ||
| return "", fmt.Errorf("failed to hash %v: %v", binPath, err) | ||
| } | ||
| gopherJsBinaryHash = fmt.Sprintf("%#x", binHash.Sum(nil)) | ||
| return gopherJsBinaryHash, nil | ||
| compilerBinaryHash = fmt.Sprintf("%#x", binHash.Sum(nil)) | ||
| return compilerBinaryHash, nil | ||
| } | ||
|
|
||
| func (s *Session) BuildPackage(pkg *PackageData) (*compiler.Archive, error) { | ||
|
|
@@ -630,14 +641,14 @@ func (s *Session) BuildPackage(pkg *PackageData) (*compiler.Archive, error) { | |
| // For non-main and test packages we build up a hash that will help | ||
| // determine staleness. Set hashDebug to see this in action. The format is: | ||
| // | ||
| // ## sync | ||
| // gopherjs binary hash: 0x519d22c6ab65a950f5b6278e4d65cb75dbd3a7eb1cf16e976a40b9f1febc0446 | ||
| // build tags: | ||
| // import: internal/race | ||
| // ## <package> | ||
| // compiler binary hash: 0x519d22c6ab65a950f5b6278e4d65cb75dbd3a7eb1cf16e976a40b9f1febc0446 | ||
| // build tags: <list of build tags> | ||
| // import: <import path> | ||
| // hash: 0xb966d7680c1c8ca75026f993c153aff0102dc9551f314e5352043187b5f9c9a6 | ||
| // ... | ||
| // | ||
| // file: /home/myitcv/gos/src/sync/cond.go | ||
| // file: <file path> | ||
| // <file contents> | ||
| // N bytes | ||
|
Member
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. Hmm, I feel like this format is a little bit arbitrary. Can we use JSON or YAML or something formatted? I don't have a strong opinion though...
Member
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. A possible problem with JSON/YAML is that it's not inherently ordered. While we could find a way to ensure constant ordering, it wouldn't necessarily happen by default, which could lead to false negative cache hits.
Member
Author
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. The goal here is to create a hash as quickly as possible in order to determine whether we have a cache miss or not. So yes, whilst the format is arbitrary, it is simple. And requires no additional processing in order to write to the hash. Using JSON/YAML adds more overhead in the middle, overhead that is unnecessary because ultimately the output is a 256 bit value. Humans will only ever read this whilst debugging (which itself will be a rare occurrence) with |
||
| // ... | ||
|
|
@@ -652,13 +663,7 @@ func (s *Session) BuildPackage(pkg *PackageData) (*compiler.Archive, error) { | |
|
|
||
| if pkg.PkgObj != "" { | ||
| fmt.Fprintf(hw, "## %v\n", pkg.ImportPath) | ||
|
|
||
| binHash, err := hashGopherJsBinary() | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
|
|
||
| fmt.Fprintf(hw, "gopherjs binary hash: %v\n", binHash) | ||
| fmt.Fprintf(hw, "compiler binary hash: %v\n", compilerBinaryHash) | ||
|
|
||
| orderedBuildTags := append([]string{}, s.options.BuildTags...) | ||
| sort.Strings(orderedBuildTags) | ||
|
|
||
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.
Rather than panicking here, would it be useful to fallback to a cache-disabled state?
Maybe that would allow running the gopherjs compiler in unusual environments (such as within a browser?)? (That may already be impossible for other reasons, idk).
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.
That's a fair point. I think I'd like to understand that situation a bit better; because a whole load of logic in
builddepends on the OS being available (writing archives etc).The compiler is run within the browser by the playground, but that does not import
build, justcompiler.