Skip to content

Commit 7a979b4

Browse files
author
John Howard
committed
Limit parallel starts
Signed-off-by: John Howard <jhoward@microsoft.com>
1 parent 4a468a6 commit 7a979b4

File tree

1 file changed

+49
-0
lines changed

1 file changed

+49
-0
lines changed

internal/hcs/system.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package hcs
22

33
import (
44
"encoding/json"
5+
"os"
6+
"strconv"
57
"sync"
68
"syscall"
79
"time"
@@ -13,8 +15,29 @@ import (
1315

1416
var (
1517
defaultTimeout = time.Minute * 4
18+
19+
// currentContainerStarts is used to limit the number of concurrent container
20+
// starts.
21+
currentContainerStarts containerStarts
1622
)
1723

24+
type containerStarts struct {
25+
maxParallel int
26+
inProgress int
27+
sync.Mutex
28+
}
29+
30+
func init() {
31+
mpsS := os.Getenv("HCSSHIM_MAX_PARALLEL_START")
32+
if len(mpsS) > 0 {
33+
mpsI, err := strconv.Atoi(mpsS)
34+
if err != nil || mpsI < 0 {
35+
return
36+
}
37+
currentContainerStarts.maxParallel = mpsI
38+
}
39+
}
40+
1841
type System struct {
1942
handleLock sync.RWMutex
2043
handle hcsSystem
@@ -145,6 +168,32 @@ func (computeSystem *System) Start() error {
145168
return makeSystemError(computeSystem, "Start", "", ErrAlreadyClosed, nil)
146169
}
147170

171+
// This is a very simple backoff-retry loop to limit the number
172+
// of parallel container starts if environment variable
173+
// HCSSHIM_MAX_PARALLEL_START is set to a positive integer.
174+
// It should generally only be used as a workaround to various
175+
// platform issues that exist between RS1 and RS4 as of Aug 2018
176+
if currentContainerStarts.maxParallel > 0 {
177+
for {
178+
currentContainerStarts.Lock()
179+
if currentContainerStarts.inProgress < currentContainerStarts.maxParallel {
180+
currentContainerStarts.inProgress++
181+
currentContainerStarts.Unlock()
182+
break
183+
}
184+
if currentContainerStarts.inProgress == currentContainerStarts.maxParallel {
185+
currentContainerStarts.Unlock()
186+
time.Sleep(100 * time.Millisecond)
187+
}
188+
}
189+
// Make sure we decrement the count when we are done.
190+
defer func() {
191+
currentContainerStarts.Lock()
192+
currentContainerStarts.inProgress--
193+
currentContainerStarts.Unlock()
194+
}()
195+
}
196+
148197
var resultp *uint16
149198
err := hcsStartComputeSystem(computeSystem.handle, "", &resultp)
150199
events, err := processAsyncHcsResult(err, resultp, computeSystem.callbackNumber, hcsNotificationSystemStartCompleted, &defaultTimeout)

0 commit comments

Comments
 (0)