I have a job scheduled in Application_start event using quartz.net, the trigger is fired every 1 min given by the variable repeatDurationTestData = "0 0/1 * * * ?";
The triggering starts when I first open the site, But stops after some random time when I close the browser and starts again when I open the site. Following is the code
IMyJob testData = new SynchronizeTestData();
IJobDetail jobTestData = new JobDetailImpl("Job", "Group", testData.GetType());
ICronTrigger triggerTestData = new CronTriggerImpl("Trigger", "Group", repeatDurationTestData);
_scheduler.ScheduleJob(jobTestData, triggerTestData);
DateTimeOffset? nextFireTime = triggerTestData.GetNextFireTimeUtc();
What Am i doing wrong here, Is this because of some misfire. Please suggest.
Thanks
At First I would use a simple trigger in this case as it takes a repeat interval and seems to fit better than the cron trigger would (from lesson 5 quartz.net website) :
SimpleTrigger trigger2 = new SimpleTrigger("myTrigger",
null,
DateTime.UtcNow,
null,
SimpleTrigger.RepeatIndefinitely,
TimeSpan.FromSeconds(60));
I would also recommend you don't put the quartz scheduler within the website. the main purpose of a job system is to work independently of anyother system so it generally fits naturally into a windows service. By putting it as part of the website you arn't guaranteed its going to keep going. If you loose the app pool or it restarts, you wont get a reliable result.
There is an example with the quartz.net download.
hope that helps.
Related
I have a pretty large repository and need to include static analysis, since it takes far too long (about 4 hours) for a normal working day we have a cron set to trigger the build automatically every morning purely to perform the static analysis stage and the way we have it set up it only does the static analysis if there has been a change in the code otherwise the static analysis becomes redundant.
The problem lies with the cron, because it is set every day we are now losing build history as well as artifacts.
I've tried to conditionally set the cron but that didn't seem to work since it should have triggered the build this morning and didn't.
triggers {
cron ( checkBuildStatus() )
}
def checkBuildStatus(){
if (currentBuild.changeSets.size() > 0){
return '0 4 * * 1-5 '
}
else {
return ''
}
}
Even if the above implementation worked I'm still not convinced that it would solve my problem of "empty" builds.
Is there a way to trigger a stage/step after working hours and only once (not everyday)?
Any advice will be greatly appreciated.
I decided to change my approach and found the best solution. I created a method, it first checks if there has been a change in the code between the current build and the one before it, and also checks that the branch name is 'master'. I then went ahead and checked the day of the week and set the cron to the following day (e.g if the build is on a Monday the cron will be set to Tuesday morning where it will then perform the static analysis stage). Now the cron will only be set if there has been a change in code and always only for the next day (of course until the next week but I'm hoping there will be changes on the master branch at least every week therefore resetting the cron)
def setCronTrigger(){
if (currentBuild.changeSets.size() > 0 && BRANCH_NAME.equals('master')){
Calendar calendar = Calendar.getInstance()
def day = calendar.get(Calendar.DAY_OF_WEEK)
cron = '* 4 * * ' + day
return cron
}
else {
return ''
}
}
well we can try to solve that problem in another way.
let's create one more job, e.g. cronTrigger. That jobs only triggers external job with static analysis.
if (currentBuild.changeSets.size() > 0) {
build(job: externalJobName, parameters: []) // run another job
}
You can keep more build. That possible to changes as well
I have an application deployed on PCF and have a new relic service binded to it. In new relic I want to get an alert when my application is stopped . I don't know whether it is possible or not. If it is possible can someone tell me how?
Edit: I don't have access to New Relic Infrastructure
Although an 'app not reporting' alert condition is not built into New Relic Alerts, it's possible to rig one using NRQL alerts. Here are the steps:
Go to New Relic Alerts and begin creating a NRQL alert condition:
NRQL alert conditions
Query your app with:
SELECT count(*) FROM Transaction WHERE appName = 'foo'
Set your threshold to :
Static
sum of query results is below x
at least once in y minutes
The query runs once per minute. If the app stops reporting then count will turn the null values into 0 and then we sum them. When the number goes below whatever your threshold is then you get a notification. I recommend using the preview graph to determine how low you want your transactions to get before receiving a notification. Here's some good information:
Relic Solution: NRQL alerting with “sum of the query results”
Basically you need to create a NewRelic Alert with conditions that check if application available, Specially you can use Host not reporting alert condition
The Host not reporting event triggers when data from the Infrastructure agent does not reach the New Relic collector within the time frame you specify.
You could do something like this:
// ...
aggregation_method = "cadence" // Use cadence for process monitoring otherwise it might not alert
// ...
nrql {
// Limitation: only works for processes with ONE instance; otherwise use just uniqueCount() and set a LoS (loss of signal)
query = "SELECT filter(uniqueCount(hostname), WHERE processDisplayName LIKE 'cdpmgr') OR -1 FROM ProcessSample WHERE GENERIC_CONDITIONS FACET hostname, entityGuid as 'entity.guid'"
}
critical {
operator = "below"
threshold = 0
threshold_duration = 5*60
threshold_occurrences = "ALL"
}
Previous solution - turned out it is not that robust:
// ...
critical {
operator = "below"
threshold = 0.0001
threshold_duration = 600
threshold_occurrences = "ALL"
}
nrql {
query = "SELECT percentage(uniqueCount(entityAndPid), WHERE commandLine LIKE 'yourExecutable.exe') FROM ProcessSample FACET hostname"
}
This will calculate the fraction your process has against all other processes.
If the process is not running the percentage will turn to 0. If you have a system running a vast amount of processes it could fall below 0.0001 but this is very unprobable.
The advantage here is that you can still have an active alert even if the process slips out of your current time alert window after it stopped. Like this you prevent the alert from auto-recovering (compared to just filtering with WHERE).
I'm currently developing a Ruby on Rails application that on certain moment has to import a (at least for me) medium-large dataset using a third-party API. It has to do an average of 6000 API calls. One after another. It lasts about 20 minutes.
Right now I have made a rails task that does everything as I want (calls, write to db, etc). But now I want this task/code to be ALSO called from a button on the web. I know it's not a good approach to let the controller call the task so that's why I'm asking.
I want this import code to be available to be called from a controller and a task, because later I want to be able to call this task from a cronjob, and even if it's possible to have callbacks on the progress of the task on the controller, i.e. know how many calls are left.
I know it's not a good approach to let the controller call the task
There's nothing wrong with having a button trigger a background task like this, but of course you need to do so with care. For example, perhaps:
If the task is already running, don't let a second instance overlap.
If the task runs for too long, automatically kill it.
Carefully restrict who can trigger this.
There are many libraries available for implementing a progress bar, or you could even write a custom implementation. For example, see this blog post - which works by polling the current progress:
// app/views/exports/export_users.js.haml
:plain
var interval;
$('.export .well').show();
interval = setInterval(function(){
$.ajax({
url: '/progress-job/' + #{#job.id},
success: function(job){
var stage, progress;
// If there are errors
if (job.last_error != null) {
$('.progress-status').addClass('text-danger').text(job.progress_stage);
$('.progress-bar').addClass('progress-bar-danger');
$('.progress').removeClass('active');
clearInterval(interval);
}
progress = job.progress_current / job.progress_max * 100;
// In job stage
if (progress.toString() !== 'NaN'){
$('.progress-status').text(job.progress_current + '/' + job.progress_max);
$('.progress-bar').css('width', progress + '%').text(progress + '%');
}
},
error: function(){
// Job is no loger in database which means it finished successfuly
$('.progress').removeClass('active');
$('.progress-bar').css('width', '100%').text('100%');
$('.progress-status').text('Successfully exported!');
$('.export-link').show();
clearInterval(interval);
}
})
},100);
An variant approach you could consider is to use a websocket to see progress, rather than polling.
Convert the specific tasks into background jobs, i.e. (active job, sideqik), so your system can continue working while it's doing the tasks. Create classes for each task and call those classes within your background jobs or cronjobs.
One design pattern that could fit here is the "command" pattern, I gave you a list of things you can Google :).
Just move most of the code from the task to a module or method in a model. You can call this code from the task (as your do it now) or from a background job that would start through a controller when you press a button on a view.
The controller display the data from the excel sheet.
I need that the controller check the excel sheet every 1 hour, also the views should be updated.
This is my controller code:
string path3 = "D:/Project/Sesame Incident Dump_20160317.xls";
Excel.Application application3 = new Excel.Application();
Excel.Workbook workbook3 = application3.Workbooks.Open(path3);
Excel.Worksheet worksheet3 = workbook3.ActiveSheet;
Excel.Range range3 = worksheet3.UsedRange;
List<SesameIncident> ListSesameIncident = new List<SesameIncident>();
for (int row = 2; row <= range3.Rows.Count; row++)
{
SesameIncident S = new SesameIncident();
S.Number = (((Excel.Range)range3.Cells[row, 1]).Text);
S.AssignedTo = (((Excel.Range)range3.Cells[row, 5]).Text);
S.Opened = (((Excel.Range)range3.Cells[row, 6]).Text);
S.Status = (((Excel.Range)range3.Cells[row, 7]).Text);
S.Priority = (((Excel.Range)range3.Cells[row, 10]).Text);
S.AssignedGroup = (((Excel.Range)range3.Cells[row, 12]).Text);
ListSesameIncident.Add(S);
}
ViewBag.ListSesameIncidents = ListSesameIncident
.Where(x => x.Status == "Pending Customer").Take(13);
You can add a Header to your HttpContext.Response in your controller
HttpContext.Response.Headers.Add("refresh", "300; url=" + Url.Action("Index"));
<script type="text/javascript">
setTimeout(function () {
location.reload();
}, 5 * 60 * 1000);
</script>
refer Refresh Page for interval using js
You can refresh the page this way
for the controller you might need a table in database to refer, when was last updated, for reference you will have to store reference data permanently , this is my opinion, I never had such requirement
To run something periodically without user interaction (that is, without a request to initiate it), a web application isn't what you want. Instead, you're looking for either a Windows Service or perhaps a simple Console Application scheduled to run at regular intervals by the host system's scheduling software (Windows Task Scheduler, cron, etc.). See How to execute a method in Asp.net MVC for every 24 hours
I would rather think about caching that could potentially save reading xls every time. See How to cache data in a MVC application
To update the client every X second is quite simple. Just use a
meta
http-equiv
With the value refresh in you page's Header.
This solution is clean and easy to read and you will not be depending of a simple JavaScript loop.
To update your excel sheet every X, you need another app with a
Timer. You can do whatever you want, if you're using .net, a simple console application will do the work. If you are using Azure you could just use a worker role, that is exactly what a worker
Is about ;p
Im using Quartz.Net in a MVC application, installed with NuGet.
And have a trigger like this:
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity("trigger1", "group1")
.WithCronSchedule("0 0 4 1 * ?")
.Build();
How can i add a Misfire Instruction so that if the server happens to be down at the time when the job was supposed to be triggered the event is triggered as soon as the server is up again?
And how would that be possible, does Quarts keep track of last time the event was triggered? I cannot find a database or file where this could be saved.
You can define cron schedule attributes using an overload that takes lambda expression:
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity("trigger1", "group1")
.WithCronSchedule("0 0 4 1 * ?", x => x.WithMisfireHandlingInstructionFireAndProceed())
.Build();
Quartz detects misfires by checking whether next scheduled time in database is in the past. For the scenario to work you need to use the persistent storage like you already are doing.
The fire times are stored in table QRTZ_TRIGGERS in columns NEXT_FIRE_TIME and PREV_FIRE_TIME. These values are .NET DateTime tics.