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 <[email protected] <javascript:>>
> 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
> > <[email protected] <javascript:>> 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
> >> [email protected] <javascript:>.
> >> 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 [email protected] <javascript:>.
> > 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 [email protected].
For more options, visit https://groups.google.com/d/optout.