I came to the following solution for my long running tasks, using go-routines & the context package,
https://play.golang.org/p/2V_29lHt4Wn package main import ( "context" "fmt" "time" ) //LongRunningTask func LongRunningTask(ctx context.Context, index int) (err error) { // we'll signal on that channel when we finished var finished chan struct{} fmt.Printf("Starting task %d at: %s\n", index, time.Now()) var cancelWork = make(chan struct{},0) go func() { workloop: for i:= 0 ;i < 10 ;i++{ // sleeping for a long time time.Sleep(time.Second * 2) select { case <-cancelWork: fmt.Printf("Canceling work for Index: %d\n",index) break workloop default: } } finished <- struct{}{} }() select { // when the task finished normal we'll get a notification on the finished channel case <-finished: fmt.Printf("Task %d finished at:%s\n", index, time.Now()) return nil // If the context gets canceled we receive a signal on that channel case <-ctx.Done(): err := ctx.Err() _=err //the context.Err() method gives us the reason why it was canceled fmt.Printf("task %d aborted reason:%s at: %s\n", index, ctx.Err(), time.Now()) cancelWork <- struct{}{} return ctx.Err() } } func main() { var ctx context.Context // get a new Context and the corresponding cancel function ctx, cancel := context.WithCancel(context.Background()) // create a new context with a timeout value of 4 Seconds derived from the context above ctx, _ = context.WithTimeout(ctx, time.Second*4) // Sleeping for one Second to clarify that the timeout is running from the point where it is created time.Sleep(time.Second * 1) fmt.Printf("Starting background tasks time %s", time.Now()) for i := 0; i < 7; i++ { go LongRunningTask(ctx, i) } // if we sllep longer than the timeout we'll see that the tasks will be canceled after timeout time.Sleep(time.Second * 8) // The call of the cancel function has only effect when we slept shorter then the defined timeout // if so the single call of the cancel function will send a cancellation information to all child context cancel() // Sleep a while to see the cancellation messages time.Sleep(time.Second * 4) } Am Freitag, 16. März 2018 15:45:00 UTC+1 schrieb Sathish VJ: > > All the examples I've seen use some kind of ticker to run various cases of > a select statement. But how does one run a long running task that is still > cancelable? > > > In the example below the quit part is never reached. > > https://play.golang.org/p/PLGwrUvKaqn (it does not run properly on > play.golang.org). > > package main > > > import ( > "fmt" > "os" > "time" > ) > > > func f(quit chan bool) { > for { > select { > case <-time.After(0 * time.Second): > // start long running task immediately. > for { > time.Sleep(500 * time.Millisecond) > fmt.Printf(". ") > } > case <-quit: > fmt.Println("quit called") > //deallocate resources in other long running task and then return > from function. > os.Exit(0) // or return > } > } > } > > > func main() { > var quit chan bool > go f(quit) > > > println("quit sending ... ") > quit <- true > println("after quit sent") > > > var i chan int > <-i > } > > > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.