Gathering detailed insights and metrics for oe-job-scheduler
Gathering detailed insights and metrics for oe-job-scheduler
Gathering detailed insights and metrics for oe-job-scheduler
Gathering detailed insights and metrics for oe-job-scheduler
npm install oe-job-scheduler
Typescript
Module System
Min. Node Version
Node Version
NPM Version
JavaScript (100%)
Total Downloads
0
Last Day
0
Last Week
0
Last Month
0
Last Year
0
1 Stars
72 Commits
2 Branches
11 Contributors
Updated on Apr 07, 2025
Latest Version
2.2.0
Package Id
oe-job-scheduler@2.2.0
Unpacked Size
6.37 MB
Size
5.80 MB
File Count
16
NPM Version
6.9.0
Node Version
10.16.0
Cumulative downloads
Total Downloads
Last Day
0%
NaN
Compared to previous day
Last Week
0%
NaN
Compared to previous week
Last Month
0%
NaN
Compared to previous month
Last Year
0%
NaN
Compared to previous year
Enterprise applications often require to run jobs - batch or otherwise - automatically, at pre-defined times and/or intervals. Such jobs are run as a background process, and may need dedicated hardware/infrastructure with its own load balancing. Typically, these jobs don't share processing infrastructure with that of OLTP app-instances so as to minimize the impact of the job's load on the online performance of the application.
The oe-job-scheduler module provides the infrastructure for catering to the above need. It is implemented as an app-list module for oe-Cloud based applications. It provides the ability to schedule the execution of any function exported from a node-module that can be "require"d. The schedule can either be specified in the form of a string which has the cron format, or it can simply be an interval (number, in milliseconds).
The cron-like scheduling functionality is obtained using the open-source node-schedule project.
node-schedule is a NodeJS module that exposes a scheduleJob()
function for scheduling a job.
The oe-job-scheduler uses this function to schedule all unscheduled and enabled jobs available in a database table called Job. This happens on application startup.
To prevent jobs getting scheduled multiple times in a clustered environment, the oe-master-job-executor module is used to schedule the jobs. oe-master-job-executor also ensures that the Job Sheduler is restarted on another app-instance if the app-instance currently handling the scheduling goes down for any reason.
An overview of the implementation in the form of a function call-stack is available here. Mouseover on each function-block for additional details.
The Job Scheduler has the following features -
To get the Job Scheduler feature, the following changes need to be done in the oe-Cloud based application:
package.json
dependencies.server/app-list.json
file in the app.IS_JOB_RUNNER
should be set with a value of true
before the application is started.
C:\> set IS_JOB_RUNNER=true ## Windows C:\> node .
$ export IS_JOB_RUNNER=true ## Linux $ node .In case of an application cluster, this variable with the stated value should be set in at least one app-instance.
The code snippets below show how steps 1 and 2 can be done:
package.json (only part of the file is shown here, with relevant section in bold):
... ... "dependencies": { ... ... ... "oe-master-job-executor": "git+https://github.com/EdgeVerve/oe-master-job-executor.git#2.0.0", "oe-job-scheduler": "git+https://github.com/EdgeVerve/oe-job-scheduler.git#2.0.0", ... ...
server/app-list.json (Relevant section in bold):
[ { "path": "oe-cloud", "enabled": true }, { "path": "oe-master-job-executor", "enabled": true }, { "path": "oe-job-scheduler", "enabled": true }, { "path" : "oe-workflow", "enabled" : true }, { "path": "./", "enabled": true } ]
Consider a job which is encapsulated in a function called jobFunc
, which is exported from a node module called jobs/end-of-day-jobs.js
,
where jobs
is a folder in the root of the application.
A sample jobs/end-of-day-jobs.js
file is shown below:
1var jobSch = require('oe-job-scheduler'); 2 3var completionStatus, percentage = 0, errors = false; 4 5function jobFunc(executionID, paramObj) { // paramObj is an arbitrary parameter object defined 6 // in the Job definition passed to the job at runtime 7 8 // Optionally, you can check for conditions when this Job should not run, for e.g., 9 // a holiday, and skip the Job execution using the skip() function as shown below 10 if( appUtil.holiday() ) { 11 jobSch.skip(executionID, { status: 0, msg: "Skipping as it is a holiday today"}, function () {}); 12 return; // It is important that you return to avoid executing the job despite calling skip() 13 // Another way to do this is to use the else clause for the remainder of this Job function. 14 } 15 16 // Do some work 17 someArray.every(function(obj, i) { // 'every' is used instead of 'forEach' as it allows breaking out if necessary 18 // ... 19 // ... 20 // ... 21 // ... 22 // Call the heartbeat function with executionID and optionally a completion status and callback function 23 // This needs to be done repeatedly and with sufficient frequency. It need not be called from a loop always. 24 // It can be called from a setInterval timer as well. In that case, take care to clearInterval at the end of 25 // the job, or if any exception happens. 26 completionStatus = { status: percentage++ }; 27 jobSch.heartbeat(executionID, completionStatus, function () {}); // IMPORTANT: This call to heartbeat() need not be inside the 28 // processing loop as shown here. You could have this repeatedly 29 // called at a suitable frequency from a setInterval(), for example. 30 // In that case, be sure to to call clearInterval() just before you 31 // call jobSch.done() 32 33 34 // Optionally, you can fail the current execution if some error occurs in the Job 35 // by calling the fail() function as follows 36 if( seriousError ) { 37 jobSch.fail(executionID, { status: percentage, msg: "Failing as seriousError occurred"}, function () {}); 38 errors = true; 39 return false; // break the loop to avoid executing the job despite calling skip() 40 } else return true; 41 42 }); 43 44 // Call the done function once at the end of a successful job execution 45 if(!errors) 46 jobSch.done(executionID, completionStatus, function () {}); 47 48 49} 50 51// Export the function(s) 52module.exports = { 53 jobFunc: jobFunc 54} 55
As seen in the above sample job, the job function (jobFunc
, in this case) needs to let the job-scheduler know that it is still active by calling
the heartbeat()
function exposed by the job-scheduler module. Otherwise, the job will be marked as failed, and it will be retried if it is
configured to be retriable.
Similarly, a done()
function needs to be called once at the end of the job execution.
The completionStatus
is any object representing the current status of the job execution. It could contain a percentage of completion, for example.
Consider that this job needs to run at 11:15 pm each day. The cron string for this schedule would be "15 23 * * *"
This job can be scheduled by POSTing the following data into the Job
table of the application database:
1{ 2 "jobID" : "EOD.JobFunc", // Mandatory. Arbitrary unique string identifier 3 "schedule" : "15 23 * * *", // Schedule specification in cron format. Will be used if specified. Will use 'interval' if not specified. 4// "schedule" : { start: startTime, end: endTime, rule: "15 23 * * *"}, // Alternate Schedule specification to include a start and end time. startTime, endTime are JavaScript Date objects. Will be used if specified. Will use 'interval' if not specified. 5// "interval": 86400, // Ignored if 'schedule' is specified 6 "enabled" : true, // Optional. Default: false. Needs to be true to actually schedule this job 7 "mdl" : "jobs/end-of-day-jobs", // Mandatory. The node module that exports the job function to be executed at the scheduled time 8 "fn" : "jobFunc", // Mandatory. The job function to be executed at the scheduled time 9 "parameter": {"some": "value"}, // Optional. The value is any arbitrary object. This object will be passed to the Job at runtime 10 "retryEnabled" : true, // Optional. Default: false. Will retry this job 'maxRetryCount' times if set to true 11 "maxRetryCount" : 2 // Optional. Default: 0. Will be used if 'retryEnabled' is true 12}
An alternative way of providing the schedule is as follows:
1. . . 2. . . 3"schedule" : '{"start":"2021-01-01T00:00:00.000Z","end":"2022-12-31T00:00:00.000Z","rule":"* * * * *"}', // Schedule specification using "start, end, rule" format. Will be used if specified. 4. . . 5. . .
The above uses a start time, end time and a cron specification.
Note that the schedule
value is a stringified JSON. Basically, the value can be generated as JSON.stringify({start: startTime, end: endTime, rule: "0 17 * * *"})
where startTime
and endTime
are Javascript Date
objects.
Jobs may be triggered manually once they are defined, using their JobIDs. This can be done either by calling a function or a HTTP endpoint.
The function call to trigger a job is as follows:
var jobSch = require('oe-job-scheduler');
jobSch.executeJobNow(jobID, paramObj, cb);
where -
jobID
- The ID of the Job that needs to be triggered immediately
paramObj
- An optional parameter object (which will be passed to the Job function) which can override the parameter specified (if any) in the Job definition
cb
- A callback function which has an error argument.
The HTTP endpoint for triggering a job is as follows:
POST /JobRunners/runJobNow/<jobID>
BODY
{paramObj}
where -
jobID
- The ID of the Job that needs to be triggered immediately
{paramObj}
- An optional parameter object (which will be passed to the Job function) which can override the parameter specified (if any) in the Job definition
The response will have any errors that may occur.
Jobs may be chained together, i.e., a job can name one or more successor jobs to be triggered automatically, once it (the job defining successor(s))
completes successfully. This can be configured in the job definition of any Job.
The following example defines two jobs - a starting job with jobID Job1
and a successor with jobID Job2
.
1[{ 2 "jobID" : "Job1", // The main Job that is scheduled to run at 11:15 pm 3 "schedule" : "15 23 * * *", 4 "successors": [{jobID: "Job2", parameter: {some: "value", another: "one"}}], // Array of successor objects, each element 5 // defining a jobID and an optional parameter object 6 "enabled" : true, 7 "mdl" : "jobs/end-of-day-jobs", 8 "fn" : "jobFunc1", 9 "retryEnabled" : true, 10 "maxRetryCount" : 2 11}, 12{ 13 "jobID": "Job2", // The successor job 14 "enabled": true, 15 "schedule": "chain", // If this job is to be used only as a successor to other jobs, then 16 // the value needs to be "chain". Otherwise, it could be a regular cron schedule string. 17 "mdl": "jobs/end-of-day-jobs", 18 "fn": "jobFunc2", 19 "retryEnabled": true, 20 "maxRetryCount": 4 21}] 22
Notes:
schedule
field to "chain"jobSch.done()
function.The oe-job-scheduler module can be configured via -
with the following priority: 3 > 2 > 1
Priority is applicable on a per-parameter basis.
The following are the configuration parameters:
---------------------------------------------------------------------------------------------------------------------------------------- config.json setting Env Variable type default Description ---------------------------------------------------------------------------------------------------------------------------------------- jobScheduler.runnerUpdateInterval JOB_RUNNER_UPDATE_INTERVAL number (ms) 15000 Frequency at which a global array containing available runners is updated jobScheduler.scheduleNewJobsInterval SCHEDULE_NEW_JOBS_INTERVAL number (ms) 30000 Frequency at which the Jobs table is polled for new enabled jobs to schedule jobScheduler.defunctJobsRetryInterval DEFUNCT_JOBS_RETRY_INTERVAL number (ms) 30000 Frequency at which JobExecution table is checked for - 1. jobs that are defunct, i.e., jobs which are neither COMPLETED nor FAILED, whose heartbeats are older than DEFUNCT_JOB_TOLERANCE which is equal to (3 * DEFUNCT_JOBS_RETRY_INTERVAL) 2. jobs that are missed due to manual stoppage or application being brought down. jobScheduler.jobTriggerFailRetryDelay JOB_TRIGGER_FAIL_RETRY_DELAY number (ms) 5000 The delay after which a retry of a retry-able job is performed, after an unsuccessful attempt to trigger it jobScheduler.runnerHeartbeatInterval JOB_RUNNER_HEARTBEAT_INTERVAL number (ms) 20000 Frequency at which the job runner heartbeat is sent jobScheduler.runnerCleanupInterval JOB_RUNNER_CLEANUP_INTERVAL number (ms) 15000 Frequency at which the JobRunner table is checked for stale runners for deletion jobScheduler.runnerRetryInterval JOB_RUNNER_RETRY_INTERVAL number (ms) 60000 Frequency at which an app-instance tries to become a job-runner if it fails to become one due to any reason jobScheduler.runnerMaxHeartbeatRetryCount JOB_RUNNER_MAX_HEARTBEAT_RETRY_COUNT number 3 The maximum number of job-runner heartbeat failures that are tolerated before discarding a job-runner and trying to become a new job-runner again jobScheduler.runnerRetryDelay JOB_RUNNER_HEARTBEAT_RETRY_DELAY number (ms) 2000 Frequency at which job-runner heartbeat is updated in the JobRunner table ----------------------------------------------------------------------------------------------------------------------------------------
The oe-job-scheduler module is tested with the default values and it should work with the defaults, i.e., without any overriding configuration via the methods mentioned above. For most scheduling needs, the defaults should suffice.
No vulnerabilities found.
Reason
no binaries found in the repo
Reason
0 existing vulnerabilities detected
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
Found 0/30 approved changesets -- score normalized to 0
Reason
no SAST tool detected
Details
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
security policy file not detected
Details
Reason
project is not fuzzed
Details
Reason
license file not detected
Details
Reason
branch protection not enabled on development/release branches
Details
Score
Last Scanned on 2025-07-07
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More