github.com/yoctocloud/packer@v0.6.2-0.20160520224004-e11a0a18423f/builder/azure/common/interruptible_task.go (about) 1 // Copyright (c) Microsoft Corporation. All rights reserved. 2 // Licensed under the MIT License. See the LICENSE file in builder/azure for license information. 3 4 package common 5 6 import ( 7 "time" 8 ) 9 10 type InterruptibleTaskResult struct { 11 Err error 12 IsCancelled bool 13 } 14 15 type InterruptibleTask struct { 16 IsCancelled func() bool 17 Task func(cancelCh <-chan struct{}) error 18 } 19 20 func NewInterruptibleTask(isCancelled func() bool, task func(cancelCh <-chan struct{}) error) *InterruptibleTask { 21 return &InterruptibleTask{ 22 IsCancelled: isCancelled, 23 Task: task, 24 } 25 } 26 27 func StartInterruptibleTask(isCancelled func() bool, task func(cancelCh <-chan struct{}) error) InterruptibleTaskResult { 28 t := NewInterruptibleTask(isCancelled, task) 29 return t.Run() 30 } 31 32 func (s *InterruptibleTask) Run() InterruptibleTaskResult { 33 completeCh := make(chan error) 34 35 cancelCh := make(chan struct{}) 36 defer close(cancelCh) 37 38 go func() { 39 err := s.Task(cancelCh) 40 completeCh <- err 41 42 // senders close, receivers check for close 43 close(completeCh) 44 }() 45 46 for { 47 if s.IsCancelled() { 48 return InterruptibleTaskResult{Err: nil, IsCancelled: true} 49 } 50 51 select { 52 case err := <-completeCh: 53 return InterruptibleTaskResult{Err: err, IsCancelled: false} 54 case <-time.After(100 * time.Millisecond): 55 } 56 } 57 }