Do not run scheduled tasks before application is ready - spring

Is it possible to postpone scheduled task (or not execute it at all) until application is ready (i.e. until after ApplicationReadyEvent)?
#Scheduled(cron = "0 0 */4 * * *")
fun foo() {
...
}

Related

Is there a way to make a #Scheduled function run on initialisation?

I want my program to download from an API every day at 5 AM and at launch. Is there a way to achieve this?
#Scheduled(cron = "0 0 5 * * *", zone = "Europe/Oslo")
fun scheduledDL(link: String) {
val xmlString = downloader.download(link)
}

Coroutine: difference between join() and cancelAndJoin()

I follow the reference document on Coroutine (https://kotlinlang.org/docs/reference/coroutines/cancellation-and-timeouts.html) and I test in the same time the example on Android Studio (a good boy).
But I am very confuse with cancelAndJoin() method.
If I replace, in the example code, the "cancelAndJoin" with "join", there is no difference in logs.
Here is the code :
fun main() = runBlocking {
val startTime = System.currentTimeMillis()
val job = launch(Dispatchers.Default) {
var nextPrintTime = startTime
var i = 0
while (i < 5) { // computation loop, just wastes CPU
// print a message twice a second
if (System.currentTimeMillis() >= nextPrintTime) {
println("job: I'm sleeping ${i++} ...")
nextPrintTime += 500L
}
}
}
delay(1300L) // delay a bit
println("main: I'm tired of waiting!")
job.cancelAndJoin() // cancels the job and waits for its completion
println("main: Now I can quit.")
}
and in the 2 cases (with join or cancelAndJoin) the logs are :
job: I'm sleeping 0 ...
job: I'm sleeping 1 ...
job: I'm sleeping 2 ...
main: I'm tired of waiting!
job: I'm sleeping 3 ...
job: I'm sleeping 4 ...
main: Now I can quit.
Does anybody can explain what is the difference with the 2 methods?
This is not clear because cancel is "stopping the job", join is "waiting for completion", but the two together??? We "stop" and "wait"???
Thanks by advance :)
This is not clear because cancel is "stopping the job", join is
"waiting for completion", but the two together??? We "stop" and
"wait"?
Just because we wrote job.cancel() doesn't mean that job will cancel immediately.
When we write job.cancel() the job enters a transient cancelling state. This job is yet to enter the final cancelled state and only after the job enters the cancelled state it can be considered completely cancelled.
Observe how the state transition occurs,
When we call job.cancel() the cancellation procedure(transition from completing to cancelling) starts for the job. But we still need to wait, as the job is truly cancelled only when it reaches the cancelled state. Hence we write job.cancelAndJoin(), where cancel() starts the cancellation procedure for job and join() makes sure to wait until the job() has reached the cancelled state.
Make sure to check out this excellent article
Note: The image is shamelessly copied from the linked article itself
Ok I've just realize that my question was stupid!
cancelAndJoin() is equal to do cancel() and then join().
The code demonstrate that the job can not be cancelled if we don't check if it is active or not. And to do so, we must use "isActive".
So like this:
val startTime = System.currentTimeMillis()
val job = launch(Dispatchers.Default) {
var nextPrintTime = startTime
var i = 0
while (isActive) { // cancellable computation loop
// print a message twice a second
if (System.currentTimeMillis() >= nextPrintTime) {
println("job: I'm sleeping ${i++} ...")
nextPrintTime += 500L
}
}
}
delay(1300L) // delay a bit
println("main: I'm tired of waiting!")
job.cancelAndJoin() // cancels the job and waits for its completion
println("main: Now I can quit.")

R subprocess failed when launched from windows task manager

Setup & Config
Windows 10
[1] "R version 3.5.0 (2018-04-23)
A C:/test.r containing
library(subprocess)
is_windows <- function () (tolower(.Platform$OS.type) == "windows")
R_binary <- function () {
R_exe <- ifelse (is_windows(), "R.exe", "R")
return(file.path(R.home("bin"), R_exe))
}
handle <- spawn_process(R_binary(), c("--no-save"))
Sys.sleep(1)
print(handle)
process_write(handle, 'n <- 10\n')
process_write(handle, "rnorm(10)\n")
process_read(handle, PIPE_STDOUT, timeout = 1000)
Results
1 - Launching test.R in a Rgui.exe/Rterm.exe everything works
2 - Launching test.R through task scheduler I got the following error
Error in spawn_process(R_binary(), c("--no-save")) :
could not create process: Accès refusé ("Access refused")
Exécution arrêtée ("Excution stopped")
You can launch test.R by doing a manual task scheduler task or by
install.packages("taskscheduleR")
library(taskscheduleR)
myscript <- system.file("extdata", "helloworld.R", package = "taskscheduleR")
myscript="C:/test..r"
taskscheduler_create(taskname = "myfancyscript", rscript = myscript,
schedule = "ONCE", starttime = format(Sys.time() + 10*60, "%H:%M"))
taskcheduler_runnow("myfancyscript")
(Then you can read the error log in the subprocess directory)
Question ?
It seems that a R process launched by task scheduler has lower right and fail to launch a subprocess, why ?
I already tried to put the task scheduler process with the highest privilege but it failed !
Thanks

Java task scheduler run daily from start to end date

I've got a spring boot application in java with some scheduled tasks I need to run at midnight every day, from 15th June to 15th August
#Scheduled(cron = "0 0 0 15-30 5 ?") // Midnight every day from 15th June until end of month
public void sendReminderEmailsJune() {
doStuff();
}
#Scheduled(cron = "0 0 0 * 6 ?") // Every day in July
public void sendReminderEmailsJuly() {
doStuff();
}
#Scheduled(cron = "0 0 0 1-15 7 ?") // The first day in August to 15th August
public void sendRemindersEmailsAugust() {
doStuff();
}
Is there a better way to do this so I don't need 3 separate #Scheduled functions?
You could simply repeat these annotations, if you are on
Spring 4 / JDK 8
#Scheduled(cron = "0 0 12 * * ?")
#Scheduled(cron = "0 0 18 * * ?")
public void sendReminderEmails() {...}
else, JDK 6+
#Schedules({
#Scheduled(cron = "0 0 12 * * ?"),
#Scheduled(cron = "0 0 18 * * ?")})
public void sendReminderEmails() {...}

What does the linux scheduler return when there are no tasks left in the queue

The linux scheduler calls for an scheduler algorithm that finds the next task in the task list.
What does the scheduling algorithm return if there are no tasks left?
Below is a piece of code
struct rt_info* sched_something(struct list_head *head, int flags)
{
/* some logic */
return some_task; // What task's value if there are no tasks left.
}
There is special "idle" task with PID=0, sometimes it is called swapper (Why do we need a swapper task in linux?). This task is scheduled to CPU core when there is no other task ready to run. There are several idle tasks - one for each CPU core
Source kernel/sched/core.c http://lxr.free-electrons.com/source/kernel/sched/core.c?v=3.16#L3160
3160 /**
3161 * idle_task - return the idle task for a given cpu.
3162 * #cpu: the processor in question.
3163 *
3164 * Return: The idle task for the cpu #cpu.
3165 */
3166 struct task_struct *idle_task(int cpu)
3167 {
3168 return cpu_rq(cpu)->idle;
3169 }
3170
So, pointer to this task is stored in runqueue (struct rq) kernel/sched/sched.h:
502 * This is the main, per-CPU runqueue data structure. ... */
508 struct rq {
557 struct task_struct *curr, *idle, *stop;
There is some init code in sched/core.c:
4517 /**
4518 * init_idle - set up an idle thread for a given CPU
4519 * #idle: task in question
4520 * #cpu: cpu the idle task belongs to
4524 */
4525 void init_idle(struct task_struct *idle, int cpu)
I think, idle task will run some kind of loop with special asm commands to inform CPU core that there is no useful job...
This post http://duartes.org/gustavo/blog/post/what-does-an-idle-cpu-do/ says idle task executes cpu_idle_loop kernel/sched/idle.c (there may be custom version of loop for arch and CPU - called with cpu_idle_poll(void) -> cpu_relax();):
40 #define cpu_relax() asm volatile("rep; nop")
45 static inline int cpu_idle_poll(void)
..
50 while (!tif_need_resched())
51 cpu_relax();
221 if (cpu_idle_force_poll || tick_check_broadcast_expired())
222 cpu_idle_poll();
223 else
224 cpuidle_idle_call();

Resources