RecurringJob or BackgroundJob + loop for infinite task - hangfire

I'm wondering to use Hangfire to program an update task. I want this task to be executed every time. So when the task finish I want to execute it again.
I don't know if the best method to use is RecurringJob or use a loop and a BackgroundJob for it.
What do you recommend me? Are there any other options?

You can use RecurringJob which triggers every x minutes or x hours (based on your requirement - can set CRON expression) , which will trigger the task/work after every such interval. This you need to use in conjunction with DisableConcurrentExecution attribute, so that multiple instances of same task are not triggered, also this attributes makes sure once your first instance is completely, then only second one will be processed.
Alternatively, you can use BackGroundJob to enqueue a task/job but this does the processing of job only one time. So you need to write some code to check this Jobs status and re-enqueue the same job again, once the first is completed. In this approach you need to write some code to do that.
I would suggest the best way is to use RecurringJob.AddOrUpdate in conjunction with DisableConcurrentExecution

Related

Pyhon APScheduler stop jobs before starting a new one

I need to start a job every 30 minutes, but before a new job is being started I want the old but same job being terminated. This is to make sure the job always fetches the newest data file which is constantly being updated.
Right now I'm using the BlockingScheduler paired with my own condition to stop the job (stop job if processed 1k data etc.), I was wondering if APScheduler supports this "only 1 job at the same time and stop old one before new one" behavior natively
I've read the docs but I think the closest is still the default behavior which equals max_instances=1, this just prevents new jobs firing before the old job finishes, which is not what I'm looking for.
Any help is appreciated. Thanks!
After further research I came to a conclusion that this is not supported natively in APScheduler, but by inspired by
Get number of active instances for BackgroundScheduler jobs
, I modified the answer into a working way of detecting the number of current running instances of the same job, so when you have a infinite loop/long task executing, and you want the new instance to replace the old instance, you can add something like
if(scheduler._executors['default']._instances['set_an_id_you_like'] > 1):
# if multiple instances break loop/return
return
and this is what should look like when you start:
scheduler = BlockingScheduler(timezone='Asia/Taipei')
scheduler.add_job(main,'cron', minute='*/30', max_instances=3, next_run_time=datetime.now(),\
id='set_an_id_you_like')
scheduler.start()
but like the answer in the link, please refrain from doing this if someday there's a native way to do this, currently I'm using APScheduler 3.10
This method at least doesn't rely on calculating time.now() or datetime.datetime.now() in every iteration to check if the time has passed compared when the loop started. In my case since my job runs every 30 minutes, I didn't want to calculate deltatime so this is what I went for, hope this hacky method helped someone that googled for a few days to come here.

Check the current position in a Redis list of some list element

I have a simple job queue on Redis where new jobs are pushed with RPUSH and consumed with BLPOP. The jobs are stringified JSON objects that have an id field among other things (the json string is parsed by the workers).
Each job takes some time to do, so there can be a meaningful wait time. I'd like to be able to find a job's current position in the queue, so that I can give an update to whatever is waiting on that job. That is, be able to do something like "your current position is 300... 250... 200... 100... 10... your job is now being processed".
It can be assumed that the list may grow long but never too long, i.e. possibly 1000 entries but not 1 million.
After looking through the docs a bit, it seems like this is maybe easier said than done. A possible naive solution seems to be to just loop through the list until the element is found. Are there any performance issues with calling LINDEX a couple hundred times at a time like that?
Would appreciate any suggestions on other ways this can be done (or confirmation that LINDEX is the only way). The whole structure (even the usage of a list, or addition of some helper map/list) can be changed if needed, only requirement is that it run on Redis.
You can use a sorted set and a counter to more elegantly solve the problem.
Push a job
Call INCR counter to get a counter.
Use the counter as score of the job, and call ZADD jobs counter job-name
Pop a job
Call BZPOPMIN jobs to get the first unprocessed job.
Get job position
Call ZRANK jobs job-name to get the rank of the job, e.g. the current position of the job.

is it possible to use scheduleAtFixedRate to trigger a function every first of the month?

I am new using kotlin and I am wondering if I can do the following...
I wanna call a method on the first of each month, I found this and saw a couple of examples like this:
timer.schedule(1000) {
println("hello world!")
}
I am wondering if is possible to use (instead of a fixed time) a calendar day? like first of the month?
There's no built-in way to do this.
If the exact time of day doesn't matter*, then one approach is to schedule a task to fire every 24 hours, and have it check whether the current time is the first day of the month, and if so, perform the task.
(* It will drift slightly when summer time starts or ends, or leap-seconds get added, but that may not be significant.)
A more powerful (but more complex approach) is to set the timer to go off once, at the appropriate time on the 1st of next month.  Then, after performing the task, it could re-schedule itself for the 1st of the following month.  (You'd need to take care that it always did so, even if the task threw an exception.)
You could put all this into a timer class of your own, to separate it from the business logic you want to run.
For examples in Java (which will translate directly to Kotlin/JVM), see the answers to these questions.

Check if a query has finished

I need to perform some queries on a rather large table, how do i check if the query has finished?
The main problem is that the queries can take up to 10 minutes and i want to tell the user, and hence the webbrowser, that its still running, so simply waiting for $sth->fetch* to finish is not an option as it will "pause" the script until there is data to be fetched.
I checked the documentation but there seems to be no function like $dbh->has_finished() or $dbh->has_data().
Asynchronous database queries should be possible with an event loop. I suggest that you take a look at AnyEvent::DBI. The trick is to use a condition variable. The query is executed asynchronously. When the query is finishen it calls a callback sub that broadcasts on the condition variable. You can use $cv->ready for checking whether the query is finished.

how to call function every time the current time is equal to time in my row?

I have column "date" in my table.I need to call my function for this table every time when the current time is equal to time in my "date" column. I don't know if it's possible to do this in ms sql server?
It seems like you are trying to implement some kind of scheduling.
You could try implementing one using one of SQL Server services called SQL Server Agent. It may not be fit for all kinds of response to time events, though, but it should be able to manage certain tasks.
You would need to set up a SQL Server Agent job for it.
A job would need to consist of at least one job step and have at least one schedule to be runnable. Perhaps, it would be easiest for you at this point to use the Transact-SQL type of job step.
A Transact-SQL job step is just a Transact-SQL script, a multi-statement query. In your case it would probably first check if there are rows matching the current time. Then, either for every matching row separately or for the entire set of them, it would perform whatever kind of operation Transact-SQL allows you to perform.