fn: timeouts and container exists should stop slot queuing (#843)

1) in theory it may be possible for an exited container to
requeue a slot, close this gap by always setting fatal error
for a slot if a container has exited.
2) when a client request times out or cancelled (client
disconnect, etc.) the slot should not be allowed to be
requeued and container should terminate to avoid accidental
mixing of previous response into next.
This commit is contained in:
Tolga Ceylan
2018-03-12 11:18:55 -07:00
committed by GitHub
parent 080b46d4cb
commit e80a06937b
2 changed files with 70 additions and 32 deletions

View File

@@ -508,6 +508,12 @@ func (s *hotSlot) Error() error {
return s.fatalErr
}
func (s *hotSlot) trySetError(err error) {
if s.fatalErr == nil {
s.fatalErr = err
}
}
func (s *hotSlot) exec(ctx context.Context, call *call) error {
ctx, span := trace.StartSpan(ctx, "agent_hot_exec")
defer span.End()
@@ -540,19 +546,21 @@ func (s *hotSlot) exec(ctx context.Context, call *call) error {
select {
case err := <-s.errC: // error from container
s.trySetError(err)
return err
case err := <-errApp: // from dispatch
if s.fatalErr == nil && err != nil {
if err != nil {
if models.IsAPIError(err) {
s.fatalErr = err
s.trySetError(err)
} else if err == protocol.ErrExcessData {
s.fatalErr = err
s.trySetError(err)
// suppress excess data error, but do shutdown the container
return nil
}
}
return err
case <-ctx.Done(): // call timeout
s.trySetError(ctx.Err())
return ctx.Err()
}
}