Why not something more like this? https://play.golang.org/p/3t4UtoFkoIt
A lot of this comes down to what that long running task is doing. If it's hard at work doing computational work, the polling approach might be appropriate. If it's mostly waiting on external events then passing the context instance down and selecting on the Done channel is probably the way forward. On 19 March 2018 at 07:44, Sathish VJ <sathis...@gmail.com> wrote: > Looks like this last one works but also quite complicated. > > One question ... what is the effect of having "default" on line 24 as empty? > > > On 18 March 2018 at 14:21, 'Reinhard Luediger' via golang-nuts > <golang-nuts@googlegroups.com> wrote: >> >> 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 a topic in the >> Google Groups "golang-nuts" group. >> To unsubscribe from this topic, visit >> https://groups.google.com/d/topic/golang-nuts/l2A0PS91T0A/unsubscribe. >> To unsubscribe from this group and all its topics, send an email to >> golang-nuts+unsubscr...@googlegroups.com. >> For more options, visit https://groups.google.com/d/optout. > > > -- > 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. -- 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.