I had an old application that was running on websphere and using old cron job scheduling library which was written in house long time ago.
I am trying to convert it to JBOSS EAP6.4 and I could not determine a good way to convert the job scheduler.
Basically, in the old app we were using a config file that lists the jobs and frequency.
This is an example of the config file
year mo dom dow hr mn prio persist package.class parms
# ==== == === === == == ======= ======= ============================================== ============================
* * * * * 15,45 norm false com.shaw.CronClass1 O
* * * 1,2,3,4,5,6 0-17,19-23 00,30 norm false com.CronClass2 B
* * * 0 1-23 00,30 norm false com.CronClass3 B
The format messy, but basically the first line says: run this job every twice every hour at 15 min and 45 min
The second line says: run this job mon-sat between 12AM-5PM and then 7PM-11PM , every 30 minutes.
I want to do something similar with JBOSS , I saw the jboss Timer service
http://docs.oracle.com/javaee/6/tutorial/doc/bnboy.html
But I don't think it has all those options and I cannot use those settings in annotation because they can change. that's why we put them in an external file that is loaded when the app starts.
Is there any library, tool or a way to this easily ?
You can use the Quartz job scheduler API. It allows scheduling both simple timers and CRON timers. The example to set it up with JBoss/ Wildfly is provided here http://www.mastertheboss.com/jboss-frameworks/jboss-quartz/quartz-2-tutorial-on-jboss-as-7
Related
I want to execute a Job in CRON for every 14 days from a specific date and timezone.
As an e.g. from JUNE 24TH every 14 days in CST time zone.
Run job every fortnight
The easy way
The easiest way to do this is simply to create the task to run every 14 days from when you want it to first run like:
CREATE TASK mytask_fortnightly
WAREHOUSE = general
SCHEDULE = '20160 MINUTE'
AS
SELECT 'Hello world'
How it works
As there are 60 minutes in an hour, 24 hours in a day and 14 days in a fortnight, ergo that's 20,160 minutes.
Caveat
The above solution does not run the task every fortnight from a given date/time, but rather every fortnight from when the task is created.
Even though this is the simplest method, it does require you to be nominally present to create the task at the exact desired next scheduled time.
As a workaround however, you can create a one-shot task to do that for you the very first time at the exact correct date/time. This means you don't have to remember to be awake / alert / present to do it manually yourself, and you can clean up the creation task afterwards.
The harder way.
Other solutions will require you to create a task which gets run every Thursday (since 2021-06-24 is/was a Thursday, each subsequent Thursday will either be the off-week, or the fortnight week)
e.g. SCHEDULE = 'USING CRON 0 0 * * THU'
Then you will add specific logic to it to determine which one the correct fortnight is.
Using this method will also incur execution cost for the off-week as well to determine if it's the correct week.
Javascript SP
In javascript you can determine if it's the correct week or not by subtracting the start date from the current date and if it's not a mutiple of 14 days, use this as a conditional to short circuit the SP.
const deltaMs = (new Date) - (new Date('2021-06-24'));
const deltaDays = ~~(deltaMs / 86400000);
const run = deltaDays % 14 === 0;
if (!run) return;
// ... continue to do what you want.
SQL
You can also check if it's a fortnight using the following SQL condition in a WHERE clause, or IFF / CASE functions.
DATEDIFF('day', '2021-06-24', CURRENT_DATE) % 14 = 0
"Connection closed" occurs when executing a function for data pre-processing.
The data pre-processing is as follows.
Import data points of about 30 topics from the database.( Data for 9 days every 1 minute,
60 * 24 * 9 * 30 = 388,800 values)
Convert data to a pandas dataframe for pre-processing such as missing value or resampling (this process takes the longest time)
Data processing
In the above data pre-processing, the following error occurs.
volttron.platform.vip.rmq_connection ERROR: Connection closed unexpectedly, reopening in 30 seconds.
This error is probably what the VOLTTRON platform does to manage the agent.
Since it takes more than 30 seconds in step 2, an error occurs and the VOLTTRON platform automatically restarts the agent.
Because of this, the agent cannot perform data processing normally.
Does anyone know how to avoid this?
If this is happening during agent instantiation I would suggest moving the pre-processing out of the init or configuration steps to a function with the #core.receiver("onstart") decorator. This will stop the agent instantiation and configuration steps from timing out. The listener agent's on start method can be used as an example.
I am working with a path of jobs on autosys that runs every night.
One of these jobs needs to run only on certain dates at the beginning of each month (usually the first 4 days but it can change depending on the business) so currently I'm putting said job ON_ICE or OFF_ICE manually and I'm looking to automate this.
I currently have 2 ideas but I'm stuck either way I choose.
Option 1 (the cleanest ?)
I would create a new job in between daily_job and monthly_job, called let's say calendar_check.
this job would start a batch on my app serveur, checking the database of my app where the calendar is, and depending of the database check sending back to autosys the good command to put the next job ON or OFF_ICE.
My batch looks like this
%My_SQLPATH% -S %My_SQL_SERVER% -d %My_SQL_DB -h-1 -W -Q "SQL Query that returns 1 or 0 depending on the calendar in my application" output.txt
set /P bEndMonth= < output.txt
echo %bEndMonth%
del output.txt
IF %bEndMonth% == 0 (start "somthing i don't know what 'sendevent -j ON_ICE -e monthly_job'") ELSE (start "somthing i don't know what 'sendevent -e OFF_ICE -j monthly_job'")
That last line is what I don't know how to write or if it's even possible to get back to my autosys server and use the sendevent command.
Little diagram for clarity
Option 2 (more messy but maybe easier)
I create 2 new jobs. One, on my path of jobs put monthly_job ON_ICE everyday.
Another one, not on my path of jobs, reads an autosys calendar and runs only on the calendar dates to put monthly_job OFF_ICE.
Downside is I must maintain another calender in autosys but it's minor.
But again I don't know the syntaxe for the jil to ask one job to put another job on or off ice.
Little diagram again for clarity
Any help is welcome or any other idea on how i could implement this.
Thank you !
For executing sendevent command in Autosys, the autosys cli package has to be installed, local variable to be declared and then login to the particular instance.
This could be verified by the Scheduling Admin/Middleware team if any.
If the days of the run at the start of the month is fixed, like first 5 days or first 5 working days, extended calendar can be considered.
Alternative way:
Since the condition to run/hold the job is based on the output of the SQL query from the database, we would use user defined exit code based on which the monthly job would trigger.
Step1: Make a script that would fetch the SQL query output and based on it we can define user exit codes.
LOGIN Database;
EXEC SQL Query;
IF %bEndMonth% == 0
THEN exit 0;
ELSE
exit 1;
Generally if the job exit code is > than 0, it would trigger an alarm for job failure, if required to suppress this, add the following attribute to this job:
max_exit_success:1
Now the job would be marked as success incase the exit is 0 or 1.
Considering the name of the job is Job_Cal_Check and is defined daily to run.
Step 2:
The monthly job/box would have no calendar and it would only trigger if the Job_Cal_Check job has exit 1. Add the following attribute
condition: exitcode (Job_Cal_Check) = 1
Edits: Fix Mis Run of successive jobs
Create an intermediate job to sleep for x seconds, calculate this time +-2 or 3 seconds taken for the monthly job to start after completion of the Job_Cal_Check.
The job flow would be:
Non Monthly Job
Previous Chain -> Job_Cal_Check -> Sleep_Job -> Followup_Jobs *(would wait only for Sleep_Job as the Monthly job would have completed status from the previous run)*
Monthly Job
Previous Chain -> Job_Cal_Check -> Sleep_Job + Monthly_Job *(both these jobs would we activated simultaneously)* -> Followup_Jobs *(would wait for both the jobs to complete)*
Job attributes as follows:
Sleep_Job:
condition: success (Job_Cal_Check)
Followup_Jobs
condition: success (Sleep_Job) AND success(Monthly_Job)
On days of Non monthly job,
Followup_Jobs would only wait for the Sleep_Job to complete.
On days of Monthly job,
Followup_Jobs would first wait for the Sleep_Job to complete by this time the Montlhy_Job would have Activated/In Running/Completed and upon completion, the job flow would continue.
Hope this helps, if anything more required do ask.
I am trying to make scheduled job using apex code that will run everyday at same time ex. 00:00. According to documentations I need to use slash '/' for increment. So, the string will look something like this:
0 0 * /1 * ?
But, when I execute this string, the scheduled job is executed every hour. Does anyone have this kind of issue before?
You can use the following expression to run the scheduled job daily.
0 0 1 * * ?
This will run the scheduled job everyday at 1:00AM.
Here is how you read the above expression
0 = Second
0 = Minute
1 = Hour
* = All days
* = All months
? = No specific value
And, I have omitted the optional year part from expression.
Also, you are confusing the / which serves completely different purpose.
Docs for: /
Specifies increments. The number before the slash specifies when the intervals will begin, and the number after the slash is the interval amount. For example, if you specify 1/5 for Day_of_month, the Apex class runs every fifth day of the month, starting on the first of the month.
In Task Queues code is executed to connect to the server side
through URL Fetch.
My file queue.yaml.
queue:
- Name: default
rate: 10 / m
bucket_size: 1
In such settings, Tusk performed all at once, simultaneously.
Specificity is that between the requests should be delayed at least 5
sec. Task must perform on stage with a difference> 5 sec. (but
does not parallel).
What are the values set in queue.yaml?
You can't specify minimum delays between tasks in queue.yaml, currently; you should do it (partly) in your own code. For example, if you specify a bucket size of 1 (so that more than one task should never be executing at once) and make sure the tasks runs for at least 5 seconds (get a start=time.time() at the start, time.sleep(time.time()-(5+start)) at the end) this should work. If it doesn't, have each task record in the store the timestamp it finished, and when it start check if the last task ended less than 5 seconds ago, and in that case terminate immediately.
The other way could be store the task data in table. In your task-queue add a id parameter. Fetch 1st task from table and pass its id to task queue processing servlet. In servlet at the end delay for 5 second and feth next task, pass its id and.... so on.