Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 428efba

Browse filesBrowse files
Merge pull request #1354 from Workiva/archiveSerial
Archive serialization updates and DCE fix
2 parents a3e015c + 45e3712 commit 428efba
Copy full SHA for 428efba

File tree

8 files changed

+332
-99
lines changed
Filter options

8 files changed

+332
-99
lines changed

‎build/build.go

Copy file name to clipboardExpand all lines: build/build.go
+35-21Lines changed: 35 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"sort"
2222
"strconv"
2323
"strings"
24+
"sync"
2425
"time"
2526

2627
"github.com/fsnotify/fsnotify"
@@ -938,23 +939,40 @@ func (s *Session) buildImportPathWithSrcDir(path string, srcDir string) (*Packag
938939
return pkg, archive, nil
939940
}
940941

942+
// getExeModTime will determine the mod time of the GopherJS binary
943+
// the first time this is called and cache the result for subsequent calls.
944+
var getExeModTime = func() func() time.Time {
945+
var (
946+
once sync.Once
947+
result time.Time
948+
)
949+
getTime := func() {
950+
gopherjsBinary, err := os.Executable()
951+
if err == nil {
952+
var fileInfo os.FileInfo
953+
fileInfo, err = os.Stat(gopherjsBinary)
954+
if err == nil {
955+
result = fileInfo.ModTime()
956+
return
957+
}
958+
}
959+
os.Stderr.WriteString("Could not get GopherJS binary's modification timestamp. Please report issue.\n")
960+
result = time.Now()
961+
}
962+
return func() time.Time {
963+
once.Do(getTime)
964+
return result
965+
}
966+
}()
967+
941968
// BuildPackage compiles an already loaded package.
942969
func (s *Session) BuildPackage(pkg *PackageData) (*compiler.Archive, error) {
943970
if archive, ok := s.UpToDateArchives[pkg.ImportPath]; ok {
944971
return archive, nil
945972
}
946973

947-
var fileInfo os.FileInfo
948-
gopherjsBinary, err := os.Executable()
949-
if err == nil {
950-
fileInfo, err = os.Stat(gopherjsBinary)
951-
if err == nil && fileInfo.ModTime().After(pkg.SrcModTime) {
952-
pkg.SrcModTime = fileInfo.ModTime()
953-
}
954-
}
955-
if err != nil {
956-
os.Stderr.WriteString("Could not get GopherJS binary's modification timestamp. Please report issue.\n")
957-
pkg.SrcModTime = time.Now()
974+
if exeModTime := getExeModTime(); exeModTime.After(pkg.SrcModTime) {
975+
pkg.SrcModTime = exeModTime
958976
}
959977

960978
for _, importedPkgPath := range pkg.Imports {
@@ -966,22 +984,18 @@ func (s *Session) BuildPackage(pkg *PackageData) (*compiler.Archive, error) {
966984
return nil, err
967985
}
968986

969-
impModTime := importedPkg.SrcModTime
970-
if impModTime.After(pkg.SrcModTime) {
987+
if impModTime := importedPkg.SrcModTime; impModTime.After(pkg.SrcModTime) {
971988
pkg.SrcModTime = impModTime
972989
}
973990
}
974991

975-
if pkg.FileModTime().After(pkg.SrcModTime) {
976-
pkg.SrcModTime = pkg.FileModTime()
992+
if fileModTime := pkg.FileModTime(); fileModTime.After(pkg.SrcModTime) {
993+
pkg.SrcModTime = fileModTime
977994
}
978995

979996
if !s.options.NoCache {
980-
archive := s.buildCache.LoadArchive(pkg.ImportPath)
981-
if archive != nil && !pkg.SrcModTime.After(archive.BuildTime) {
982-
if err := archive.RegisterTypes(s.Types); err != nil {
983-
panic(fmt.Errorf("failed to load type information from %v: %w", archive, err))
984-
}
997+
archive := s.buildCache.LoadArchive(pkg.ImportPath, pkg.SrcModTime, s.Types)
998+
if archive != nil {
985999
s.UpToDateArchives[pkg.ImportPath] = archive
9861000
// Existing archive is up to date, no need to build it from scratch.
9871001
return archive, nil
@@ -1021,7 +1035,7 @@ func (s *Session) BuildPackage(pkg *PackageData) (*compiler.Archive, error) {
10211035
fmt.Println(pkg.ImportPath)
10221036
}
10231037

1024-
s.buildCache.StoreArchive(archive)
1038+
s.buildCache.StoreArchive(archive, time.Now())
10251039
s.UpToDateArchives[pkg.ImportPath] = archive
10261040

10271041
return archive, nil

‎build/cache/cache.go

Copy file name to clipboardExpand all lines: build/cache/cache.go
+17-5Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@ import (
66
"crypto/sha256"
77
"fmt"
88
"go/build"
9+
"go/types"
910
"os"
1011
"path"
1112
"path/filepath"
13+
"time"
1214

1315
"github.com/gopherjs/gopherjs/compiler"
1416
log "github.com/sirupsen/logrus"
@@ -90,7 +92,10 @@ func (bc BuildCache) String() string {
9092

9193
// StoreArchive compiled archive in the cache. Any error inside this method
9294
// will cause the cache not to be persisted.
93-
func (bc *BuildCache) StoreArchive(a *compiler.Archive) {
95+
//
96+
// The passed in buildTime is used to determine if the archive is out-of-date when reloaded.
97+
// Typically it should be set to the srcModTime or time.Now().
98+
func (bc *BuildCache) StoreArchive(a *compiler.Archive, buildTime time.Time) {
9499
if bc == nil {
95100
return // Caching is disabled.
96101
}
@@ -106,7 +111,7 @@ func (bc *BuildCache) StoreArchive(a *compiler.Archive) {
106111
return
107112
}
108113
defer f.Close()
109-
if err := compiler.WriteArchive(a, f); err != nil {
114+
if err := compiler.WriteArchive(a, buildTime, f); err != nil {
110115
log.Warningf("Failed to write build cache archive %q: %v", a, err)
111116
// Make sure we don't leave a half-written archive behind.
112117
os.Remove(f.Name())
@@ -125,7 +130,10 @@ func (bc *BuildCache) StoreArchive(a *compiler.Archive) {
125130
//
126131
// The returned archive would have been built with the same configuration as
127132
// the build cache was.
128-
func (bc *BuildCache) LoadArchive(importPath string) *compiler.Archive {
133+
//
134+
// The imports map is used to resolve package dependencies and may modify the
135+
// map to include the package from the read archive. See [gcexportdata.Read].
136+
func (bc *BuildCache) LoadArchive(importPath string, srcModTime time.Time, imports map[string]*types.Package) *compiler.Archive {
129137
if bc == nil {
130138
return nil // Caching is disabled.
131139
}
@@ -140,12 +148,16 @@ func (bc *BuildCache) LoadArchive(importPath string) *compiler.Archive {
140148
return nil // Cache miss.
141149
}
142150
defer f.Close()
143-
a, err := compiler.ReadArchive(importPath, f)
151+
a, buildTime, err := compiler.ReadArchive(importPath, f, srcModTime, imports)
144152
if err != nil {
145153
log.Warningf("Failed to read cached package archive for %q: %v", importPath, err)
146154
return nil // Invalid/corrupted archive, cache miss.
147155
}
148-
log.Infof("Found cached package archive for %q, built at %v.", importPath, a.BuildTime)
156+
if a == nil {
157+
log.Infof("Found out-of-date package archive for %q, built at %v.", importPath, buildTime)
158+
return nil // Archive is out-of-date, cache miss.
159+
}
160+
log.Infof("Found cached package archive for %q, built at %v.", importPath, buildTime)
149161
return a
150162
}
151163

‎build/cache/cache_test.go

Copy file name to clipboardExpand all lines: build/cache/cache_test.go
+46-7Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package cache
22

33
import (
4+
"go/types"
45
"testing"
6+
"time"
57

68
"github.com/google/go-cmp/cmp"
79
"github.com/gopherjs/gopherjs/compiler"
@@ -15,21 +17,24 @@ func TestStore(t *testing.T) {
1517
Imports: []string{"fake/dep"},
1618
}
1719

20+
srcModTime := newTime(0.0)
21+
buildTime := newTime(5.0)
22+
imports := map[string]*types.Package{}
1823
bc := BuildCache{}
19-
if got := bc.LoadArchive(want.ImportPath); got != nil {
24+
if got := bc.LoadArchive(want.ImportPath, srcModTime, imports); got != nil {
2025
t.Errorf("Got: %s was found in the cache. Want: empty cache.", got.ImportPath)
2126
}
22-
bc.StoreArchive(want)
23-
got := bc.LoadArchive(want.ImportPath)
27+
bc.StoreArchive(want, buildTime)
28+
got := bc.LoadArchive(want.ImportPath, srcModTime, imports)
2429
if got == nil {
25-
t.Errorf("Got: %s wan not found in the cache. Want: archive is can be loaded after store.", want.ImportPath)
30+
t.Errorf("Got: %s was not found in the cache. Want: archive is can be loaded after store.", want.ImportPath)
2631
}
2732
if diff := cmp.Diff(want, got); diff != "" {
2833
t.Errorf("Loaded archive is different from stored (-want,+got):\n%s", diff)
2934
}
3035

3136
// Make sure the package names are a part of the cache key.
32-
if got := bc.LoadArchive("fake/other"); got != nil {
37+
if got := bc.LoadArchive("fake/other", srcModTime, imports); got != nil {
3338
t.Errorf("Got: fake/other was found in cache: %#v. Want: nil for packages that weren't cached.", got)
3439
}
3540
}
@@ -59,20 +64,54 @@ func TestInvalidation(t *testing.T) {
5964
},
6065
}
6166

67+
srcModTime := newTime(0.0)
68+
buildTime := newTime(5.0)
69+
imports := map[string]*types.Package{}
6270
for _, test := range tests {
6371
a := &compiler.Archive{ImportPath: "package/fake"}
64-
test.cache1.StoreArchive(a)
72+
test.cache1.StoreArchive(a, buildTime)
6573

66-
if got := test.cache2.LoadArchive(a.ImportPath); got != nil {
74+
if got := test.cache2.LoadArchive(a.ImportPath, srcModTime, imports); got != nil {
6775
t.Logf("-cache1,+cache2:\n%s", cmp.Diff(test.cache1, test.cache2))
6876
t.Errorf("Got: %v loaded from cache. Want: build parameter change invalidates cache.", got)
6977
}
7078
}
7179
}
7280

81+
func TestOldArchive(t *testing.T) {
82+
cacheForTest(t)
83+
84+
want := &compiler.Archive{
85+
ImportPath: "fake/package",
86+
Imports: []string{"fake/dep"},
87+
}
88+
89+
buildTime := newTime(5.0)
90+
imports := map[string]*types.Package{}
91+
bc := BuildCache{}
92+
bc.StoreArchive(want, buildTime)
93+
94+
oldSrcModTime := newTime(2.0) // older than archive build time, so archive is up-to-date
95+
got := bc.LoadArchive(want.ImportPath, oldSrcModTime, imports)
96+
if got == nil {
97+
t.Errorf("Got: %s was nil. Want: up-to-date archive to be loaded.", want.ImportPath)
98+
}
99+
100+
newerSrcModTime := newTime(7.0) // newer than archive build time, so archive is stale
101+
got = bc.LoadArchive(want.ImportPath, newerSrcModTime, imports)
102+
if got != nil {
103+
t.Errorf("Got: %s was not nil. Want: stale archive to not be loaded.", want.ImportPath)
104+
}
105+
}
106+
73107
func cacheForTest(t *testing.T) {
74108
t.Helper()
75109
originalRoot := cacheRoot
76110
t.Cleanup(func() { cacheRoot = originalRoot })
77111
cacheRoot = t.TempDir()
78112
}
113+
114+
func newTime(seconds float64) time.Time {
115+
return time.Date(1969, 7, 20, 20, 17, 0, 0, time.UTC).
116+
Add(time.Duration(seconds * float64(time.Second)))
117+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.