Merge pull request #44 from Random-Liu/stop-on-cancellation

Stop waiting on cancellation.
This commit is contained in:
Lantao Liu 2017-05-23 15:08:57 -07:00 committed by GitHub
commit 6ce1dc0167
2 changed files with 27 additions and 5 deletions

View File

@ -76,7 +76,7 @@ func (c *criContainerdService) StopContainer(ctx context.Context, r *runtime.Sto
return nil, fmt.Errorf("failed to stop container %q: %v", id, err) return nil, fmt.Errorf("failed to stop container %q: %v", id, err)
} }
err = c.waitContainerStop(id, time.Duration(r.GetTimeout())*time.Second) err = c.waitContainerStop(ctx, id, time.Duration(r.GetTimeout())*time.Second)
if err == nil { if err == nil {
return &runtime.StopContainerResponse{}, nil return &runtime.StopContainerResponse{}, nil
} }
@ -92,7 +92,7 @@ func (c *criContainerdService) StopContainer(ctx context.Context, r *runtime.Sto
} }
// Wait forever until container stop is observed by event monitor. // Wait forever until container stop is observed by event monitor.
if err := c.waitContainerStop(id, killContainerTimeout); err != nil { if err := c.waitContainerStop(ctx, id, killContainerTimeout); err != nil {
return nil, fmt.Errorf("error occurs during waiting for container %q to stop: %v", return nil, fmt.Errorf("error occurs during waiting for container %q to stop: %v",
id, err) id, err)
} }
@ -100,7 +100,7 @@ func (c *criContainerdService) StopContainer(ctx context.Context, r *runtime.Sto
} }
// waitContainerStop polls container state until timeout exceeds or container is stopped. // waitContainerStop polls container state until timeout exceeds or container is stopped.
func (c *criContainerdService) waitContainerStop(id string, timeout time.Duration) error { func (c *criContainerdService) waitContainerStop(ctx context.Context, id string, timeout time.Duration) error {
ticker := time.NewTicker(stopCheckPollInterval) ticker := time.NewTicker(stopCheckPollInterval)
defer ticker.Stop() defer ticker.Stop()
timeoutTimer := time.NewTimer(timeout) timeoutTimer := time.NewTimer(timeout)
@ -122,6 +122,8 @@ func (c *criContainerdService) waitContainerStop(id string, timeout time.Duratio
return nil return nil
} }
select { select {
case <-ctx.Done():
return fmt.Errorf("wait container %q is cancelled", id)
case <-timeoutTimer.C: case <-timeoutTimer.C:
return fmt.Errorf("wait container %q stop timeout", id) return fmt.Errorf("wait container %q stop timeout", id)
case <-ticker.C: case <-ticker.C:

View File

@ -33,9 +33,10 @@ import (
func TestWaitContainerStop(t *testing.T) { func TestWaitContainerStop(t *testing.T) {
id := "test-id" id := "test-id"
timeout := 2 * stopCheckPollInterval
for desc, test := range map[string]struct { for desc, test := range map[string]struct {
metadata *metadata.ContainerMetadata metadata *metadata.ContainerMetadata
cancel bool
timeout time.Duration
expectErr bool expectErr bool
}{ }{
"should return error if timeout exceeds": { "should return error if timeout exceeds": {
@ -44,10 +45,22 @@ func TestWaitContainerStop(t *testing.T) {
CreatedAt: time.Now().UnixNano(), CreatedAt: time.Now().UnixNano(),
StartedAt: time.Now().UnixNano(), StartedAt: time.Now().UnixNano(),
}, },
timeout: 2 * stopCheckPollInterval,
expectErr: true,
},
"should return error if context is cancelled": {
metadata: &metadata.ContainerMetadata{
ID: id,
CreatedAt: time.Now().UnixNano(),
StartedAt: time.Now().UnixNano(),
},
timeout: time.Hour,
cancel: true,
expectErr: true, expectErr: true,
}, },
"should not return error if container is removed before timeout": { "should not return error if container is removed before timeout": {
metadata: nil, metadata: nil,
timeout: time.Hour,
expectErr: false, expectErr: false,
}, },
"should not return error if container is stopped before timeout": { "should not return error if container is stopped before timeout": {
@ -57,6 +70,7 @@ func TestWaitContainerStop(t *testing.T) {
StartedAt: time.Now().UnixNano(), StartedAt: time.Now().UnixNano(),
FinishedAt: time.Now().UnixNano(), FinishedAt: time.Now().UnixNano(),
}, },
timeout: time.Hour,
expectErr: false, expectErr: false,
}, },
} { } {
@ -64,7 +78,13 @@ func TestWaitContainerStop(t *testing.T) {
if test.metadata != nil { if test.metadata != nil {
assert.NoError(t, c.containerStore.Create(*test.metadata)) assert.NoError(t, c.containerStore.Create(*test.metadata))
} }
err := c.waitContainerStop(id, timeout) ctx := context.Background()
if test.cancel {
cancelledCtx, cancel := context.WithCancel(ctx)
cancel()
ctx = cancelledCtx
}
err := c.waitContainerStop(ctx, id, test.timeout)
assert.Equal(t, test.expectErr, err != nil, desc) assert.Equal(t, test.expectErr, err != nil, desc)
} }
} }