Play Framework - Schedule a task at precise time [duplicate] - scala

This question already has answers here:
scala - How to run a task every day a 11PM
(2 answers)
Closed 6 years ago.
I'm doing a Scala - Play application and I want to schedule a task to sending mail everyday at 3 A.M, so I create a class for that but i'ts not working:
class ManageSendInvalidateDaemon #Inject() (app: Application, emailSender: EmailSender, mailer: MailerClient) {
Akka.system(app).scheduler.schedule(
scala.concurrent.duration.Duration.create(20,TimeUnit.SECONDS),
scala.concurrent.duration.Duration.create(60, TimeUnit.SECONDS),
new Runnable(){
override def run()={
//Function to send the mail
}
}
);
};
I think the problem is here:
scala.concurrent.duration.Duration.create(20,TimeUnit.SECONDS),
scala.concurrent.duration.Duration.create(60, TimeUnit.SECONDS),
I don't really understand what it's the use of these 2 lines

That will not work as you expect. Akka scheduler just lets you specify the recurrency of the task, but not the day, hour etc when it will run (ex: you can tell it to run a task every 10 minutes, but not run this at 15:30 each Monday).
Those two lines instruct Akka to run that task every 60 seconds, and run the first time 20 seconds after you define it (so if the schedule call is executed at 12h30m that task will run the first time at 12:30:20 and then 12:31:20, 12:32:20, etc).
To overcome this, you just need to run a task periodically (in your case, each minute for example), and check the current hour. If it is 3AM send those emails (and eventually store anywere that this task was executed).
Another option is to use something like akka-quartz-scheduler, that lets you specify that type of scheduling

I had the same problem. So I created a method to calculate how much time from now until the time I want to run my
schedule = Akka.system().scheduler().schedule(
Duration.create(nextRunTime(), TimeUnit.MILLISECONDS),
Duration.create(DAY_IN_MS, TimeUnit.MILLISECONDS),
...,);
The nextRunTime() method calculates how much time in milliseconds will be until the next 3 AM and after that I set an interval of one day (DAY_IN_MS)
private int nextRunTime() {
String runTimeValue = "03:00";
LocalTime now = new LocalTime();
LocalTime runTime = new LocalTime(runTimeValue);
int timeUntilRun;
if (runTime.isAfter(now)) { // From now until the run time
timeUntilRun = runTime.getMillisOfDay() - now.getMillisOfDay();
} else { // From now until midnight, plus from midnight until the run time
timeUntilRun = DAY_IN_MS - now.getMillisOfDay() + runTime.getMillisOfDay();
}
Logger.info("nextRunTime(): next run in " + timeUntilRun + " ms");
return timeUntilRun;
}

Related

Flutter Local Notifications show notification every 72 hours

I am trying to send out notifications every 72 hours. I am using the flutter_local_notifications package. I know I can periodically show notifications but as far as I can see it is limited to these options:
/// The available intervals for periodically showing notifications.
enum RepeatInterval {
/// An interval for every minute.
everyMinute,
/// Hourly interval.
hourly,
/// Daily interval.
daily,
/// Weekly interval.
weekly
}
Is there any way to achieve the 72h interval? I couldn't find anything on this. Let me know if you need any more info! Any help is appreciated!
you can try this :-
fltrNotification = new FlutterLocalNotificationsPlugin();
var scheduledTime = DateTime.now().add(Duration(hour : 72));
fltrNotification.schedule(1, "Times Uppp", task,
scheduledTime, generalNotificationDetails);
always this approach works
make your own copy of package
modify it 😊
1.make your own copy
you can easily copy the package file to your project . and use it like this (flutter doc)
dependencies:
plugin1:
path: ../plugin1/
if you prefer you can fork project and use it like below
dependencies:
plugin1:
git:
url: git://github.com/flutter/plugin1.git
2.modify it 🛠
for your question you can change the value of Daily interval to (3 * Daily interval)
I found this part of code (android - ios)
I would use the flutter cron package if I were you: cron package on pub.dev
It allows you schedule a cron job which is simply a task that runs every x seconds or days, months...
For your example:
fltrNotification = new FlutterLocalNotificationsPlugin();
final cron = Cron();
// Schedule a task that will run every 3 days
cron.schedule(Schedule.parse('0 0 */3 * *'), () async {
// Schedule a notification right now
fltrNotification.schedule(1, "Times Uppp", task,
DateTime.now(), generalNotificationDetails);
print('every three days');
});
If you want to change the frequency, cron is very flexible and you can do pretty much any frequency, the cron syntax is pretty straightforward and their are some websites online that allow you to simply generate it.
There are, of course, several ways to use cron to do what you want. You could schedule a notification for the next 72 hours every 72 hours, refreshing every 24 hours, whatever seems better to you.
(I used part of Piyush Kumar's answer for this example by the way, and updated it to use cron)

Schedule function execution in swift

I'm developing a simple app in Swift and I need to schedule a function execution every 24 hours. I'm aware of the method:
DispatchQueue.main.asyncAfter(deadline: .now() + 10.0, execute: {
self.functionToCall()
})
that could solve my problem but, is this the right solution for a 24 hours delay?
Thanks
Theoretically, this is possible.
The problem is that your app would have to run in the foreground for 24 hours, which is very unlikely to happen. Unfortunately, you can not run background tasks just like that.
The solution:
Just make it look like the function would execute in the background. Every time the update function is called, simply save the Int(Date().timeIntervalSince1970) to UserDefaults. This works like a timestamp and saves the last time you called your update function. Every time in the viewDidLoad()-function (not sure if it's called the same on Mac apps, but you can imagine what I mean) call:
If let timestamp = UserDefaults.standard.integer(forKey: "yourTimestampKey") {
let currentTimestamp = Date().timeIntervalSince1970
if (currentTimestamp - timestamp) > 86400 { // number of seconds in 24 hours
// the last time your function was updated was at least 24h ago
update()
}
}
That's how you can make it appear like it was updated in the background. I use this all the time in my apps and it works perfectly.
EDIT:
Maybe, just in case the app does indeed run 24 hours in a row, I would set up the upper function that you posted first as well.

Schedule Node.js job every five minutes

I'm new to node.js. I need node.js to query a mongodb every five mins, get specific data, then using socket.io, allow subscribed web clients to access this data. I already have the socket.io part set up and of course mongo, I just need to know how to have node.js run every five minutes then post to socket.io.
What's the best solution for this?
Thanks
var minutes = 5, the_interval = minutes * 60 * 1000;
setInterval(function() {
console.log("I am doing my 5 minutes check");
// do your stuff here
}, the_interval);
Save that code as node_regular_job.js and run it :)
You can use this package
var cron = require('node-cron');
cron.schedule('*/5 * * * *', () => {
console.log('running a task 5 minutes');
});
This is how you should do if you had some async tasks to manage:
(function schedule() {
background.asyncStuff().then(function() {
console.log('Process finished, waiting 5 minutes');
setTimeout(function() {
console.log('Going to restart');
schedule();
}, 1000 * 60 * 5);
}).catch(err => console.error('error in scheduler', err));
})();
You cannot guarantee however when it will start, but at least you will not run multiple time the job at the same time, if your job takes more than 5 minutes to execute.
You may still use setInterval for scheduling an async job, but if you do so, you should at least flag the processed tasks as "being processed", so that if the job is going to be scheduled a second time before the previous finishes, your logic may decide to not process the tasks which are still processed.
#alessioalex has the right answer when controlling a job from the code, but others might stumble over here looking for a CLI solution. You can't beat sloth-cli.
Just run, for example, sloth 5 "npm start" to run npm start every 5 minutes.
This project has an example package.json usage.
there are lots of Schedule package that would help you to do this in node.js . Just choose one of them based on your needs
following are list of packages:
Agenda,
Node-schedule,
Node-cron,
Bree,
Cron,
Bull

Help and advice needed working with Quartz.NET NthIncludedDayTrigger

I've started using Quartz.NET recently, and so far, it's been really
helpful. Now, I'm trying to use it to create a job that runs once a
month using a NthIncludedDayTrigger (I want to use the
NthIncludedDayTrigger as eventually I will be specifying a calendar to
exclude weekends/holidays).
To familiarise myself with the code, I've
set up a simple console application to create an NthIncludedDayTrigger
where the first fire time will be 15 seconds from now:
static void Main(string[] args)
{
IScheduler scheduler = StdSchedulerFactory.DefaultScheduler;
scheduler.Start();
var jobDetail = new JobDetail("Job name", "Group name", typeof(SomeIJobImplementation));
var trigger = new NthIncludedDayTrigger();
trigger.Name = "Trigger name";
trigger.MisfireInstruction = MisfireInstruction.NthIncludedDayTrigger.DoNothing;
trigger.IntervalType = NthIncludedDayTrigger.IntervalTypeMonthly;
//I'm using the following while experimenting with the code (AddHour(1) to account for BST):
trigger.FireAtTime = DateTime.UtcNow.AddHours(1).AddSeconds(15).ToString("HH:mm:ss");
//I'm using the following while experimenting with the code:
trigger.N = DateTime.Today.Day;
Console.WriteLine("Started, press any key to stop ...");
Console.ReadKey();
scheduler.Shutdown(false);
}
...
public class SomeIJobImplementation : IJob
{
public void Execute(JobExecutionContext context)
{
Logger.Write(String.Format(
"Job executed called at {0}",
DateTime.Now.ToString("dd-MMM-yyyy HH:mm:ss")), null, 1,
TraceEventType.Information);
}
}
Running this results in the job being executed multiple times
(approximately once per second) for one minute. I'm using an ADO.NET
job store and can see in my database that QRTZ_TRIGGERS.NEXT_FIRE_TIME
is set to the last executed time, i.e. doesn't seem to be scheduled to
run again.
I expected the above code to run the job once (after about 15
seconds), then schedule the job to run again in one months time.
Perphaps the issue is just with the way I'm using Quartz.NET whilst
I've been experimenting or, maybe, my expectations are wrong? Either
way, I would be most grateful for any help/suggestions to explain the
behaviour I've observed, and what I need to change to get the
behaviour I want.
I must be late but I was trying to implement the same solution and ended up here.
I reckon you should star the scheduler after you've defined jobs and triggers.

Quartz.Net - delay a simple trigger to start

I have a few jobs setup in Quartz to run at set intervals. The problem is though that when the service starts it tries to start all the jobs at once... is there a way to add a delay to each job using the .xml config?
Here are 2 job trigger examples:
<simple>
<name>ProductSaleInTrigger</name>
<group>Jobs</group>
<description>Triggers the ProductSaleIn job</description>
<misfire-instruction>SmartPolicy</misfire-instruction>
<volatile>false</volatile>
<job-name>ProductSaleIn</job-name>
<job-group>Jobs</job-group>
<repeat-count>RepeatIndefinitely</repeat-count>
<repeat-interval>86400000</repeat-interval>
</simple>
<simple>
<name>CustomersOutTrigger</name>
<group>Jobs</group>
<description>Triggers the CustomersOut job</description>
<misfire-instruction>SmartPolicy</misfire-instruction>
<volatile>false</volatile>
<job-name>CustomersOut</job-name>
<job-group>Jobs</job-group>
<repeat-count>RepeatIndefinitely</repeat-count>
<repeat-interval>43200000</repeat-interval>
</simple>
As you see there are 2 triggers, the first repeats every day, the next repeats twice a day.
My issue is that I want either the first or second job to start a few minutes after the other... (because they are both in the end, accessing the same API and I don't want to overload the request)
Is there a repeat-delay or priority property? I can't find any documentation saying so..
I know you are doing this via XML but in code you can set the StartTimeUtc to delay say 30 seconds like this...
trigger.StartTimeUtc = DateTime.UtcNow.AddSeconds(30);
This isn't exactly a perfect answer for your XML file - but via code you can use the StartAt extension method when building your trigger.
/* calculate the next time you want your job to run - in this case top of the next hour */
var hourFromNow = DateTime.UtcNow.AddHours(1);
var topOfNextHour = new DateTime(hourFromNow.Year, hourFromNow.Month, hourFromNow.Day, hourFromNow.Hour, 0, 0);
/* build your trigger and call 'StartAt' */
TriggerBuilder.Create().WithIdentity("Delayed Job").WithSimpleSchedule(x => x.WithIntervalInSeconds(60).RepeatForever()).StartAt(new DateTimeOffset(topOfNextHour))
You've probably already seen this by now, but it's possible to chain jobs, though it's not supported out of the box.
http://quartznet.sourceforge.net/faq.html#howtochainjobs