How can I write an Quartz Scheduler Expression to create a trigger that fires every 5 minutes between 15:30 and 15:55 in one simple expression case? Is that possible? or should I create more than one trigger, and register both of them to run the same job?
I believe this is the easiest (but not necessarily most elegant) way to achieve this:
0 30,35,40,45,50,55 15 * * ?
Related
I have a task which needs to be executed after successful completion of different predecessor tasks.
Say for example below three tasks triggers at same time and calls different stored proc.
CREATE TASK myschema.mytask_1
WAREHOUSE = mywh
schedule='USING CRON 0 8 * * MON America/Los_Angeles'
as call myschema.MY_PROC_1();
CREATE TASK myschema.mytask_2
WAREHOUSE = mywh
schedule='USING CRON 0 8 * * MON America/Los_Angeles'
as call myschema.MY_PROC_2();
CREATE TASK myschema.mytask_3
WAREHOUSE = mywh
schedule='USING CRON 0 8 * * MON America/Los_Angeles'
as call myschema.MY_PROC_3();
However I want the below 4th task to be executed after all the above three completes successfully. If any one of them got failed 4th shouldn't trigger. In short 4th task depend on completion of all above three tasks.
I have read through some snowflake docs and found only one task can be set as dependencies. For now can think of below by going one after the other. Also I'm not sure how to evaluate the successful completion of prior task to proceed further. Can someone please help me to achieve this is in any better way. Any help on this is much appreciated.
CREATE TASK myschema.mytask_1
WAREHOUSE = mywh
schedule='USING CRON 0 8 * * MON America/Los_Angeles'
as call myschema.MY_PROC_1();
CREATE TASK myschema.mytask_2
WAREHOUSE = mywh
AFTER myschema.mytask_1
as call myschema.MY_PROC_2();
CREATE TASK myschema.mytask_3
WAREHOUSE = mywh
AFTER myschema.mytask_2
as call myschema.MY_PROC_3();
CREATE TASK myschema.mytask_4
WAREHOUSE = mywh
AFTER myschema.mytask_3
as call myschema.MY_PROC_4();
Although the solution with Streams suggested by Mike Walton is fascinating, implementing a single stored procedure (possibly within an explicit transaction so that it rolls back when an error occurs) might be a simpler and, therefore, better maintainable solution.
Having said that, if performance is key you may want to opt for the Streams-option cause it guarantees the different pieces of code within each stored procedure run concurrently, whereas the Single-SP would run them sequentially.
If you run the tasks in succession, then any failure will stop the rest from executing, and when the next scheduled execution comes around, it'll start from the beginning and execute again. Depending on your logic, this may not be the behavior you're looking for.
Regarding the first option, one possible solution here is to leverage streams to initiate the 4th task. It is a little bit unorthodox, but you can make it work. Here are the basic steps to look into trying:
Each of the 3 parallel tasks would need to insert a record into a separate table upon successful completion of the SP, so it'd have to be the last step in the SP.
Each of those 3 tables would need to have a STREAM object created.
You'd schedule the task to run every minute and use a WHEN clause that looked something like the below code.
You would then need to execute some additional tasks after the 4th task that did some DML statement against your streams, so that the stream would get reset.
Step 3 example:
CREATE OR REPLACE TASK mytask_4
WAREHOUSE = xxxx
SCHEDULE = '1 MINUTE'
WHEN SYSTEM$STREAM_HAS_DATA('mytask_1_stream') = True
AND SYSTEM$STREAM_HAS_DATA('mytask_2_stream') = True
AND SYSTEM$STREAM_HAS_DATA('mytask_3_stream') = True;
Step 4 exmple:
CREATE OR REPLACE TASK mytask_5
WAREHOUSE = xxxx
AFTER myschema.mytask_4
INSERT * INTO log_table FROM mytask_1_stream;
CREATE OR REPLACE TASK mytask_6
WAREHOUSE = xxxx
AFTER myschema.mytask_4
INSERT * INTO log_table FROM mytask_2_stream;
CREATE OR REPLACE TASK mytask_7
WAREHOUSE = xxxx
AFTER myschema.mytask_4
INSERT * INTO log_table FROM mytask_3_stream;
Like I said, it's a bit of a workaround, but it should work nicely in most cases. And one additional point, mytask_4 in this case will never use any compute unless all 3 of the streams contain data, which means all 3 of your previous tasks have executed successfully. Otherwise, the task will be skipped and wait for the next minute to "check again". If you are running the first 3 tasks less often, you can schedule mytask_4 to run less often, as well, if you wish.
Say i have job which needs to be executed at fixed times in a day like below,
"05:00, 06:10, 07:30, 08:15, 09:05, 10:35"
How could i build a Trigger for this in Quartz ?
I couldnt find the way to achieve this out-of-the-box.
I see two ways to solve your problem:
1. Multiple triggers (recommended).
The most obvious and easy way to set the unusual scheduling for you job is to combine several triggers.
Quartz allows to set as much triggers as you want for single JobDetail.
2. Implement your own trigger.
It is more complicated way, applicable only if you must use only one trigger.
You could implement org.quartz.Trigger interface or any subinterfaces to set yourown rules.
I am using a product called Mirth to reach out to an SFTP server and download a handful of files on a weekly basis. The product has a cron feature, where it allows you to use a cron expression to do configure this function.
The cron expression I am using:
0 45 13 ? * MON *
NOTE: This is not typical Linux-based cron. It's a cron expression spec used by Java for scheduling things even down to the second (https://docs.oracle.com/cd/E12058_01/doc/doc.1014/e12030/cron_expressions.htm).
Is supposed to reach out at 1:45 PM every Monday and pull down files. But when it reaches out it does so continuously for 20 minutes or so, downloading the same files a few hundred times instead of just once.
Is there vagueness in this expression? It seems like it should only call once. I did just notice that there appears to be a space at the very beginning of the expression, not sure how that would make the thing run for 20 minutes again and again, though.
You could ease your crontab scheduling with crontab generators, like ie. this website:
www.crontab.guru
or
www.crontab-generator.org
(These are first two Google results)
From what you described, it looks like invalid syntax for crontab.
EDITED:
1:45 PM every Monday would be:
45 13 * * 1
In our app, we have an ability to schedule tasks and we converting this functionality to Quartz. One of the problems that I have is scheduling recurring task that should run, for example, every third day.
The cron expression that I had in mind first of all is:
0 37 18 */3 * ? *
But what this will do, is execute that job on 1,4,7, etc... Which is fine, assuming that I want to start from the first day of the month. However, how to deal with this issue if I need to start from 11th?
I could do something like this:
0 37 18 11/3 * ? *
But, in this case, I will always miss all the days before the 11th.
Also, when the time comes for the next month, the expectation that the day of the month will now be different (on one month the job executed on 1st, and on another it could be on 2/3), but based on the cron above it will restart on the same day (e.g. 1st).
I could, of course, count using hours, but then I will have an issue with day light saving?
What is the correct way to organize it? Or am I missing something?
UPDATE
Possible solution is to use simple trigger, as per http://www.quartz-scheduler.org/documentation/quartz-2.1.x/cookbook/BiDailyTrigger.
But in this case, how do I resolve DST problem?
Thanks,
So I've decided to use Quartz.NET to schedule some tasks for me in my application and I'd like to schedule my tasks to run daily from the following 3 pieces of information.
TimeSpan startTime //i.e. 10:30
TimeSpan endTime // i.e. 18:30
TimeSpan repeatInterval // 30 Minutes
And the trigger will fire every day at 10:30, 11:00, 11:30...18:30
Seems pretty simple right? But I can't seem to find anything in the TriggerUtils that would allow me to do something like this. I've also tried the CronTrigger route but it doesn't seem very clean for intervals like 90 seconds.
If there's a built in way to do this I'd love to use it but if not I'm ready to roll my own Trigger. Any pointers for implementing a Trigger from scratch (which methods need to be overridden etc.) would also be much appreciated.
You could define a SimpleTrigger with the repeat interval you want and restrict it to run within a daily time range with a DailyCalendar.