Thursday, December 5, 2024
HomeGolangctx->Performed not getting known as for ContextWithTimeout - Getting Assist

ctx->Performed not getting known as for ContextWithTimeout – Getting Assist


Hello,

I’m new to go and I’m attempting to know why the next code doesn’t work. I’ve a context with a timeout and I’m doing a for loop with a choose with <-ctx.Performed() as the primary case. I anticipated the operate to exit when the timeout occurs nevertheless it doesn’t. Can somebody please inform me what I’m doing incorrect?

bundle major

import (
	"context"
	"fmt"
	"time"
)

func major() {
	ctx, cancel := context.WithTimeout(context.TODO(), time.Second)
	defer cancel()
	for {
		choose {
		case <-ctx.Performed():
			fmt.Println("Ended at:", time.Now())
			return
		default:
			fmt.Println(".")
		}
	}
}

This additionally fails to exit

func major() {
	ctx, cancel := context.WithTimeout(context.TODO(), time.Second)
	defer cancel()
	for ctx.Err() == nil {
		fmt.Println(".", ctx, ctx.Err())
	}
}

Theses packages does work for me.
I wouldn’t take into account them right as they’re redlining the CPU at 100% whereas polling.

As your variety of cores and OS differ polling may work higher or worst.

One thing like this works on the playground (as a substitute of simply my CPU):

bundle major

import (
	"context"
	"fmt"
	"time"
)

func major() {
	ctx, cancel := context.WithTimeout(context.TODO(), time.Second)
	defer cancel()
	for {
		choose {
		case <-ctx.Performed():
			fmt.Println("Ended at:", time.Now())
			return
		default:
			fmt.Println(".")
			time.Sleep(time.Second / 4)
		}
	}
}
func major() {
	ctx, cancel := context.WithTimeout(context.TODO(), time.Second)
	defer cancel()
	for ctx.Err() == nil {
		fmt.Println(".", ctx, ctx.Err())
                time.Sleep(time.Second/4)
	}
}

The individuals writing the scheduler tries to make it capable of deal with circumstances like this, nevertheless it looks as if there’s a bug and it doesn’t correctly observe timers or one thing.
Even when the scheduler is ready to resolve polling loops it’s a large efficiency price so that you shouldn’t write this code on function.



1 Like

The primary one I wouldn’t take into account right too.
Because the default department is all the time prepared, it could be authorized to decide on it all the time:
A choose … chooses one at random if a number of are prepared

However for me as nicely, each terminate.
Which platform/model are you utilizing?

It runs ceaselessly on the playground.

The issue right here is that context was by no means cancelled. You defer-ed it. Defer signifies that the operate will execute when the func the place you outlined it exits. Most important won’t ever do, since you utilize infinite loop. To exit from the loop with context, you have to name cancel() with out defer.

Did you attempt to debug it? What system do you utilize?

That was what I used to be considering of as nicely. The unique code I had was really studying some bytes on the default case and would anticipate 100 ms for at the least one byte. I wrote a mock for the reader utilizing bytes.Buffer and put a 100 ms wait contained in the Learn to imitate the conduct. It could intermittently fail when operating the take a look at suite and all the time move by itself. Possibly the 100 ms wait wasn’t sufficient for Go to have the ability to course of the ctx->Performed.

Glorious level. I hadn’t realized that choose chooses one at random. I assumed the circumstances had been positioned in precedence. Nonetheless, the second case doesn’t use a choose.

I’m utilizing go model 1.22. I did strive it on the playground for each model 1.21 and 1.22 they usually each fail. I used to be operating it inside a go take a look at on my Home windows machine after I first noticed the conduct. Nonetheless, I’ve run it on my Home windows machine as a easy app and that was nice.

Sure, I’ve tried to debug it. If I put print statements, they present me that completed is rarely known as even when the timeout has handed. But when I put a breakpoint in, it all the time works.

Default fires provided that not one of the circumstances are prepared.
https://go.dev/tour/concurrency/6

If it’s home windows machine, then possibly it’s one thing much like time definition points on home windows, due to the system clock. Right here runtime: time.Sleep takes extra time than anticipated on Home windows (1ms -> 10ms) · Concern #44343 · golang/go · GitHub. One of many feedback advise to strive home windows.TimeBeginPeriod(1)

Might be as nicely. From the solutions I’ve bought right here. It appears to be like like the usage of ctx is just not actually really helpful inside tight loops.

That’s good to know. Thanks for pointing that out.

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments