Because then you have to deal with all the chennels by yourself. Using the Context API looks for me a bit cleaner and even easier.
Am Montag, 19. März 2018 15:04:17 UTC+1 schrieb matthe...@gmail.com: > > Only a detail, but why not this instead as the API? > > func LongRunningTask(cancel <-chan struct{}, index int) (err error) { > > Matt > > On Monday, March 19, 2018 at 7:43:19 AM UTC-5, rog wrote: >> >> 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 <sath...@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 >> > <golan...@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...@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...@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.