add context cancellation to image.Service.Cancel()

This commit is contained in:
Dmitry Verkhoturov
2020-04-12 03:34:13 -05:00
committed by Umputun
parent 449e375cbb
commit a133ab31fa
3 changed files with 13 additions and 5 deletions
+3 -1
View File
@@ -502,7 +502,9 @@ func (a *serverApp) run(ctx context.Context) error {
log.Printf("[WARN] failed to close avatar store, %s", e)
}
a.notifyService.Close()
a.imageService.Close()
// call potentially infinite loop with cancellation after a minute as a safeguard
minuteCtx, _ := context.WithTimeout(context.Background(), time.Minute)
a.imageService.Close(minuteCtx)
close(a.terminated)
return nil
+8 -2
View File
@@ -149,14 +149,20 @@ func (s *Service) Cleanup(ctx context.Context) {
}
// Close flushes all in-progress submits and enforces waiting commits
func (s *Service) Close() {
func (s *Service) Close(ctx context.Context) {
log.Printf("[INFO] close image service ")
// terminate commit goroutine using s.term only if it is started
if atomic.LoadInt32(&s.term) == 1 {
atomic.StoreInt32(&s.term, 0) // enforce non-delayed commits for all ids left in submitCh
var ctxCancel bool
for {
select {
case <-ctx.Done():
ctxCancel = true
default:
}
// set to 1 by commit goroutine after everything waited on TTL sent
if atomic.LoadInt32(&s.term) == 1 {
if atomic.LoadInt32(&s.term) == 1 || ctxCancel {
break
}
time.Sleep(10 * time.Millisecond)
+2 -2
View File
@@ -128,7 +128,7 @@ func TestService_Close(t *testing.T) {
svc.Submit(func() []string { return []string{"id1", "id2", "id3"} })
svc.Submit(func() []string { return []string{"id4", "id5"} })
svc.Submit(nil)
svc.Close()
svc.Close(context.TODO())
store.AssertNumberOfCalls(t, "Commit", 5)
}
@@ -141,7 +141,7 @@ func TestService_SubmitDelay(t *testing.T) {
svc.Submit(func() []string { return []string{"id4", "id5"} })
svc.Submit(nil)
store.AssertNumberOfCalls(t, "Commit", 3)
svc.Close()
svc.Close(context.TODO())
store.AssertNumberOfCalls(t, "Commit", 5)
}