Is there any native library or third party support like ScheduledExecutorService by java native library at go lang for production use case?
Please find the code snippet in java 1.8 :
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class TaskScheduler {
/**
* @param args
*/
public static void main(String[] args) {
Runnable runnable = ()-> {
// task to run goes here
System.out.println("Hello !!");
};
ScheduledExecutorService service = Executors.newScheduledThreadPool(1);
service.scheduleAtFixedRate(runnable, 0, 1, TimeUnit.SECONDS);
}
}
Looking for idiomatic go implementation with no memory leakage
obviously not looking for solution like this :
go func() {
for true {
fmt.Println("Hello !!")
time.Sleep(1 * time.Second)
}
}()
Thanks
Ticker is the perfect solution to my problem.
Two quick question :
1 - Ticker doesnât get invoke as soon as the application starts. It always wait for interval time given at ticker creation.
Letâs say ,if i want to execute some task at given interval of 15 mins.For the first time execution,Ticker waits 15 min to invoke the task after application start.
I found a hack way by calling the task for the first time from main and then rely on ticker to trigger the task in each 15 mins.In javaScheduledExecutorService, we can achieve the behavior by just passing â0â as delay.
Is there any way to do this with ticker ?
2 - I am stopping the ticker and exiting main only after some os interrupts. will it lead to high CPU and resource utilization ?
code snippet :
func main() {
task(time.Now())
tick := time.NewTicker(time.Second * 5)
go scheduler(tick)
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
<-sigs
tick.Stop()
//os.Exit(1)
}
func scheduler(tick *time.Ticker) {
for t := range tick.C {
task(t)
}
}
func task(t time.Time) {
fmt.Println("hello! printed at ", t)
}
okay, according to the official spec, it says âStop the ticker to release associated resources.â
but at my implementation âstopâ is getting called after signal interrupt. So, i thought it might cause some high resource utilization. Thanks for the explanation
In your case you donât have to stop it because when you exit your program it will stop anyways. You usually have to stop it in forever loops when you want to reuse the same ticker.
In this above example, I donât think ,they are reusing the ticker.Still, they stopping the ticker by defer. All, I need to know, is it best practice to stop it always? because i donât see any harm on not stopping the ticker, as you said, it will stop anyways after main exit.
If it is the practice, then i have to, otherwise code wonât pass the review
@johandalabacka
Awesome, I have used the second solution.It always wait for task to be finished.
some doubts though:
1: after receiving true from done chan at scheduler func ,shouldnât it return from the function immediately and exit the for loop ? why it is waiting for unfinished task?
2: ticker has not been stopped,is it intentional ?
But it does this by calling return or do I missunderstand you?
you could stop it but as stated in an earlier post. It is only necessary if youâre going to start it again later and the program just exits shortly afterwards.
Select always block the execution, till it gets some value from either channel.
My question was : if done becomes true , for block should exit immediately by return. why is it waiting for unfinished task to be finished which was triggered by ticker channel previously?
done <- true in the main go routine will block until the ongoing task has run and select reads from done. You should use this pattern if the the task canât be interrupted in the middle. Maybe it has to finish some database operation or writing to a file. If it is ok that the task is aborted at the same time as the program will you not need this construct with the done channel.