@@ -78,7 +78,7 @@ func (d *dockerLogger) Start(opts *StartOpts) error {
78
78
go func () {
79
79
defer close (d .doneCh )
80
80
81
- stdout , stderr , err := d .openStreams (opts )
81
+ stdout , stderr , err := d .openStreams (ctx , opts )
82
82
if err != nil {
83
83
d .logger .Error ("log streaming ended with terminal error" , "error" , err )
84
84
return
@@ -132,7 +132,9 @@ func (d *dockerLogger) Start(opts *StartOpts) error {
132
132
133
133
}
134
134
135
- func (d * dockerLogger ) openStreams (opts * StartOpts ) (stdout , stderr io.WriteCloser , err error ) {
135
+ // openStreams open logger stdout/stderr; should be called in a background goroutine to avoid locking up
136
+ // process to avoid locking goroutine process
137
+ func (d * dockerLogger ) openStreams (ctx context.Context , opts * StartOpts ) (stdout , stderr io.WriteCloser , err error ) {
136
138
d .stdLock .Lock ()
137
139
stdoutF , stderrF := d .stdout , d .stderr
138
140
d .stdLock .Unlock ()
@@ -141,6 +143,10 @@ func (d *dockerLogger) openStreams(opts *StartOpts) (stdout, stderr io.WriteClos
141
143
return stdoutF , stderrF , nil
142
144
}
143
145
146
+ // opening a fifo may block indefinitely until a reader end opens, so
147
+ // we preform open() without holding the stdLock, so Stop and interleave.
148
+ // This a defensive measure - logmon (the reader end) should be up and
149
+ // started before dockerLogger is started
144
150
if stdoutF == nil {
145
151
stdoutF , err = fifo .OpenWriter (opts .Stdout )
146
152
if err != nil {
@@ -155,6 +161,13 @@ func (d *dockerLogger) openStreams(opts *StartOpts) (stdout, stderr io.WriteClos
155
161
}
156
162
}
157
163
164
+ if ctx .Err () != nil {
165
+ // Stop was called and don't need files anymore
166
+ stdoutF .Close ()
167
+ stderrF .Close ()
168
+ return nil , nil , ctx .Err ()
169
+ }
170
+
158
171
d .stdLock .Lock ()
159
172
d .stdout , d .stderr = stdoutF , stderrF
160
173
d .stdLock .Unlock ()
0 commit comments