@@ -325,12 +325,9 @@ func main() {
325
325
}
326
326
}()
327
327
328
- workc := make (chan buildgo.BuilderRev )
329
-
330
328
if * mode == "dev" {
331
329
// TODO(crawshaw): do more in dev mode
332
330
gcePool .SetEnabled (* devEnableGCE )
333
- http .HandleFunc ("/dosomework/" , handleDoSomeWork (workc ))
334
331
} else {
335
332
go gcePool .cleanUpOldVMs ()
336
333
if kubeErr == nil {
@@ -342,7 +339,7 @@ func main() {
342
339
}
343
340
344
341
go listenAndServeInternalModuleProxy ()
345
- go findWorkLoop (workc )
342
+ go findWorkLoop ()
346
343
go findTryWorkLoop ()
347
344
go reportMetrics (context .Background ())
348
345
// TODO(cmang): gccgo will need its own findWorkLoop
@@ -351,22 +348,38 @@ func main() {
351
348
go listenAndServeTLS ()
352
349
go listenAndServeSSH () // ssh proxy to remote buildlets; remote.go
353
350
354
- for {
355
- work := <- workc
356
- if ! mayBuildRev (work ) {
357
- if inStaging {
358
- if _ , ok := dashboard .Builders [work .Name ]; ok && logCantBuildStaging .Allow () {
359
- log .Printf ("may not build %v; skipping" , work )
360
- }
351
+ select {}
352
+ }
353
+
354
+ // ignoreAllNewWork, when true, prevents addWork from doing anything.
355
+ // It's sometimes set in staging mode when people are debugging
356
+ // certain paths.
357
+ var ignoreAllNewWork bool
358
+
359
+ // addWorkTestHook is optionally set by tests.
360
+ var addWorkTestHook func (work buildgo.BuilderRev )
361
+
362
+ func addWork (work buildgo.BuilderRev ) {
363
+ if f := addWorkTestHook ; f != nil {
364
+ f (work )
365
+ return
366
+ }
367
+ if ignoreAllNewWork || isBuilding (work ) {
368
+ return
369
+ }
370
+ if ! mayBuildRev (work ) {
371
+ if inStaging {
372
+ if _ , ok := dashboard .Builders [work .Name ]; ok && logCantBuildStaging .Allow () {
373
+ log .Printf ("may not build %v; skipping" , work )
361
374
}
362
- continue
363
- }
364
- st , err := newBuild (work )
365
- if err != nil {
366
- log .Printf ("Bad build work params %v: %v" , work , err )
367
- } else {
368
- st .start ()
369
375
}
376
+ return
377
+ }
378
+ st , err := newBuild (work )
379
+ if err != nil {
380
+ log .Printf ("Bad build work params %v: %v" , work , err )
381
+ } else {
382
+ st .start ()
370
383
}
371
384
}
372
385
@@ -811,19 +824,21 @@ func workaroundFlush(w http.ResponseWriter) {
811
824
w .(http.Flusher ).Flush ()
812
825
}
813
826
814
- // findWorkLoop polls https://build.golang.org/?mode=json looking for new work
815
- // for the main dashboard. It does not support gccgo.
816
- func findWorkLoop (work chan <- buildgo.BuilderRev ) {
827
+ // findWorkLoop polls https://build.golang.org/?mode=json looking for
828
+ // new post-submit work for the main dashboard. It does not support
829
+ // gccgo. This is separate from trybots, which populates its work from
830
+ // findTryWorkLoop.
831
+ func findWorkLoop () {
817
832
// Useful for debugging a single run:
818
833
if inStaging && false {
819
834
const debugSubrepo = false
820
835
if debugSubrepo {
821
- work <- buildgo.BuilderRev {
836
+ addWork ( buildgo.BuilderRev {
822
837
Name : "linux-arm" ,
823
838
Rev : "c9778ec302b2e0e0d6027e1e0fca892e428d9657" ,
824
839
SubName : "tools" ,
825
840
SubRev : "ac303766f5f240c1796eeea3dc9bf34f1261aa35" ,
826
- }
841
+ })
827
842
}
828
843
const debugArm = false
829
844
if debugArm {
@@ -832,31 +847,29 @@ func findWorkLoop(work chan<- buildgo.BuilderRev) {
832
847
time .Sleep (time .Second )
833
848
}
834
849
log .Printf ("ARM machine(s) registered." )
835
- work <- buildgo.BuilderRev {Name : "linux-arm" , Rev : "3129c67db76bc8ee13a1edc38a6c25f9eddcbc6c" }
850
+ addWork ( buildgo.BuilderRev {Name : "linux-arm" , Rev : "3129c67db76bc8ee13a1edc38a6c25f9eddcbc6c" })
836
851
} else {
837
- work <- buildgo.BuilderRev {Name : "linux-amd64" , Rev : "9b16b9c7f95562bb290f5015324a345be855894d" }
838
- work <- buildgo.BuilderRev {Name : "linux-amd64-sid" , Rev : "9b16b9c7f95562bb290f5015324a345be855894d" }
839
- work <- buildgo.BuilderRev {Name : "linux-amd64-clang" , Rev : "9b16b9c7f95562bb290f5015324a345be855894d" }
852
+ addWork ( buildgo.BuilderRev {Name : "linux-amd64" , Rev : "9b16b9c7f95562bb290f5015324a345be855894d" })
853
+ addWork ( buildgo.BuilderRev {Name : "linux-amd64-sid" , Rev : "9b16b9c7f95562bb290f5015324a345be855894d" })
854
+ addWork ( buildgo.BuilderRev {Name : "linux-amd64-clang" , Rev : "9b16b9c7f95562bb290f5015324a345be855894d" })
840
855
}
841
-
842
- // Still run findWork but ignore what it does.
843
- ignore := make (chan buildgo.BuilderRev )
844
- go func () {
845
- for range ignore {
846
- }
847
- }()
848
- work = ignore
856
+ ignoreAllNewWork = true
849
857
}
858
+ // TODO: remove this hard-coded 15 second ticker and instead
859
+ // do some new streaming gRPC call to maintnerd to subscribe
860
+ // to new commits.
850
861
ticker := time .NewTicker (15 * time .Second )
851
862
for {
852
- if err := findWork (work ); err != nil {
863
+ if err := findWork (); err != nil {
853
864
log .Printf ("failed to find new work: %v" , err )
854
865
}
855
866
<- ticker .C
856
867
}
857
868
}
858
869
859
- func findWork (work chan <- buildgo.BuilderRev ) error {
870
+ // findWork polls the https://build.golang.org/ dashboard once to find
871
+ // post-submit work to do. It's called in a loop by findWorkLoop.
872
+ func findWork () error {
860
873
var bs types.BuildStatus
861
874
if err := dash ("GET" , "" , url.Values {"mode" : {"json" }}, nil , & bs ); err != nil {
862
875
return err
@@ -881,6 +894,7 @@ func findWork(work chan<- buildgo.BuilderRev) error {
881
894
// 15 seconds, but they should be skewed toward new work.
882
895
// This depends on the build dashboard sending back the list
883
896
// of empty slots newest first (matching the order on the main screen).
897
+ // TODO: delete this code when the scheduler is on by default.
884
898
sent := map [string ]bool {}
885
899
886
900
var goRevisions []string // revisions of repo "go", branch "master" revisions
@@ -951,12 +965,18 @@ func findWork(work chan<- buildgo.BuilderRev) error {
951
965
}
952
966
}
953
967
954
- // The !sent[builder] here is a clumsy attempt at priority scheduling
955
- // and probably should be replaced at some point with a better solution.
956
- // See golang.org/issue/19178 and the long comment above.
957
- if ! isBuilding (rev ) && ! sent [builder ] {
958
- sent [builder ] = true
959
- work <- rev
968
+ if useScheduler {
969
+ addWork (rev )
970
+ } else {
971
+ // The !sent[builder] here is a clumsy attempt at priority scheduling
972
+ // and probably should be replaced at some point with a better solution.
973
+ // See golang.org/issue/19178 and the long comment above.
974
+ // TODO: delete all this code and the sent map above when the
975
+ // useScheduler const is removed.
976
+ if ! sent [builder ] {
977
+ sent [builder ] = true
978
+ addWork (rev )
979
+ }
960
980
}
961
981
}
962
982
}
@@ -969,10 +989,7 @@ func findWork(work chan<- buildgo.BuilderRev) error {
969
989
continue
970
990
}
971
991
for _ , rev := range goRevisions {
972
- br := buildgo.BuilderRev {Name : b , Rev : rev }
973
- if ! isBuilding (br ) {
974
- work <- br
975
- }
992
+ addWork (buildgo.BuilderRev {Name : b , Rev : rev })
976
993
}
977
994
}
978
995
return nil
@@ -1530,30 +1547,26 @@ type BuildletPool interface {
1530
1547
// and highPriorityOpt.
1531
1548
GetBuildlet (ctx context.Context , hostType string , lg logger ) (* buildlet.Client , error )
1532
1549
1533
- // HasCapacity reports whether the buildlet pool has
1534
- // quota/capacity to create a buildlet of the provided host
1535
- // type. This should return as fast as possible and err on
1536
- // the side of returning false.
1537
- HasCapacity (hostType string ) bool
1538
-
1539
1550
String () string // TODO(bradfitz): more status stuff
1540
1551
}
1541
1552
1542
- // GetBuildlets creates up to n buildlets and sends them on the returned channel
1553
+ // getBuildlets creates up to n buildlets and sends them on the returned channel
1543
1554
// before closing the channel.
1544
- func GetBuildlets (ctx context.Context , pool BuildletPool , n int , hostType string , lg logger ) <- chan * buildlet.Client {
1555
+ func getBuildlets (ctx context.Context , n int , schedTmpl * SchedItem , lg logger ) <- chan * buildlet.Client {
1545
1556
ch := make (chan * buildlet.Client ) // NOT buffered
1546
1557
var wg sync.WaitGroup
1547
1558
wg .Add (n )
1548
1559
for i := 0 ; i < n ; i ++ {
1549
1560
go func (i int ) {
1550
1561
defer wg .Done ()
1551
1562
sp := lg .CreateSpan ("get_helper" , fmt .Sprintf ("helper %d/%d" , i + 1 , n ))
1552
- bc , err := pool .GetBuildlet (ctx , hostType , lg )
1563
+ schedItem := * schedTmpl // copy; GetBuildlet takes ownership
1564
+ schedItem .IsHelper = i > 0
1565
+ bc , err := sched .GetBuildlet (ctx , lg , & schedItem )
1553
1566
sp .Done (err )
1554
1567
if err != nil {
1555
1568
if err != context .Canceled {
1556
- log .Printf ("failed to get a %s buildlet: %v" , hostType , err )
1569
+ log .Printf ("failed to get a %s buildlet: %v" , schedItem . HostType , err )
1557
1570
}
1558
1571
return
1559
1572
}
@@ -1574,9 +1587,9 @@ func GetBuildlets(ctx context.Context, pool BuildletPool, n int, hostType string
1574
1587
return ch
1575
1588
}
1576
1589
1577
- var testPoolHook func (* dashboard.BuildConfig ) BuildletPool
1590
+ var testPoolHook func (* dashboard.HostConfig ) BuildletPool
1578
1591
1579
- func poolForConf (conf * dashboard.BuildConfig ) BuildletPool {
1592
+ func poolForConf (conf * dashboard.HostConfig ) BuildletPool {
1580
1593
if testPoolHook != nil {
1581
1594
return testPoolHook (conf )
1582
1595
}
@@ -1589,10 +1602,10 @@ func poolForConf(conf *dashboard.BuildConfig) BuildletPool {
1589
1602
} else {
1590
1603
return kubePool
1591
1604
}
1592
- case conf .IsReverse () :
1605
+ case conf .IsReverse :
1593
1606
return reversePool
1594
1607
default :
1595
- panic (fmt .Sprintf ("no buildlet pool for builder type %q" , conf .Name ))
1608
+ panic (fmt .Sprintf ("no buildlet pool for host type %q" , conf .HostType ))
1596
1609
}
1597
1610
}
1598
1611
@@ -1641,7 +1654,7 @@ func (st *buildStatus) start() {
1641
1654
}
1642
1655
1643
1656
func (st * buildStatus ) buildletPool () BuildletPool {
1644
- return poolForConf (st .conf )
1657
+ return poolForConf (st .conf . HostConfig () )
1645
1658
}
1646
1659
1647
1660
// parentRev returns the parent of this build's commit (but only if this build comes from a trySet).
@@ -1721,8 +1734,12 @@ func (st *buildStatus) getHelpers() <-chan *buildlet.Client {
1721
1734
}
1722
1735
1723
1736
func (st * buildStatus ) onceInitHelpersFunc () {
1724
- pool := st .buildletPool ()
1725
- st .helpers = GetBuildlets (st .ctx , pool , st .conf .NumTestHelpers (st .isTry ()), st .conf .HostType , st )
1737
+ schedTmpl := & SchedItem {
1738
+ BuilderRev : st .BuilderRev ,
1739
+ HostType : st .conf .HostType ,
1740
+ IsTry : st .isTry (),
1741
+ }
1742
+ st .helpers = getBuildlets (st .ctx , st .conf .NumTestHelpers (st .isTry ()), schedTmpl , st )
1726
1743
}
1727
1744
1728
1745
// useSnapshot reports whether this type of build uses a snapshot of
@@ -1835,11 +1852,9 @@ func (st *buildStatus) build() error {
1835
1852
}
1836
1853
1837
1854
sp = st .CreateSpan ("get_buildlet" )
1838
- pool := st .buildletPool ()
1839
1855
bc , err := sched .GetBuildlet (st .ctx , st , & SchedItem {
1840
1856
HostType : st .conf .HostType ,
1841
1857
IsTry : st .trySet != nil ,
1842
- Pool : pool ,
1843
1858
BuilderRev : st .BuilderRev ,
1844
1859
})
1845
1860
sp .Done (err )
@@ -1980,7 +1995,7 @@ func (st *buildStatus) buildRecord() *types.BuildRecord {
1980
1995
1981
1996
// Log whether we used COS, so we can do queries to analyze
1982
1997
// Kubernetes vs COS performance for containers.
1983
- if st .conf .IsContainer () && poolForConf (st .conf ) == gcePool {
1998
+ if st .conf .IsContainer () && poolForConf (st .conf . HostConfig () ) == gcePool {
1984
1999
rec .ContainerHost = "cos"
1985
2000
}
1986
2001
@@ -2099,7 +2114,6 @@ func (st *buildStatus) crossCompileMakeAndSnapshot(config *dashboard.CrossCompil
2099
2114
kubeBC , err := sched .GetBuildlet (ctx , st , & SchedItem {
2100
2115
HostType : config .CompileHostType ,
2101
2116
IsTry : st .trySet != nil ,
2102
- Pool : kubePool ,
2103
2117
BuilderRev : st .BuilderRev ,
2104
2118
})
2105
2119
sp .Done (err )
0 commit comments