Fix busy waiting on stdin

When running an execution, Nomad continuously reads from the stdin
reader. Because the readers we implemented (codeOceanToRawReader and
nullReader) return zero if there is no input available, this leads to
busy waiting and a high CPU load on Poseidon. By waiting indefinitely in
case of the nullReader and for at least one byte on case of the
codeOceanToRawReader before returning, we prevent this issue.
This commit is contained in:
Konrad Hanff
2021-06-17 16:41:24 +02:00
parent 0b9e5a5ba5
commit 17c1e379c2
2 changed files with 8 additions and 2 deletions

View File

@ -93,7 +93,12 @@ func (cr *codeOceanToRawReader) readInputLoop() context.CancelFunc {
// Read implements the io.Reader interface. // Read implements the io.Reader interface.
// It returns bytes from the buffer. // It returns bytes from the buffer.
func (cr *codeOceanToRawReader) Read(p []byte) (n int, err error) { func (cr *codeOceanToRawReader) Read(p []byte) (n int, err error) {
for n = 0; n < len(p); n++ { if len(p) == 0 {
return
}
// Ensure to not return until at least one byte has been read to avoid busy waiting.
p[0] = <-cr.buffer
for n = 1; n < len(p); n++ {
select { select {
case p[n] = <-cr.buffer: case p[n] = <-cr.buffer:
default: default:

View File

@ -292,7 +292,8 @@ func (a *APIClient) LoadEnvironmentJobs() ([]*nomadApi.Job, error) {
type nullReader struct{} type nullReader struct{}
func (r nullReader) Read(_ []byte) (int, error) { func (r nullReader) Read(_ []byte) (int, error) {
return 0, nil // An empty select blocks forever.
select {}
} }
// ExecuteCommand executes the given command in the given allocation. // ExecuteCommand executes the given command in the given allocation.