I'm trying to make a Listener (or something like that?) that will start a specific event when a date field from a database row is the same as the current time. Of course I can trigger every second to check if the date/time is the same as the current, but I think that is quite expansive. There should be a better alternative..
What I trying to do is the following:
I have several (for example football) matches scheduled in my database. At the specific time when the match should start, I will start a event in my Java app. This could be 1 or more matches at that time.
I understand that you are trying to schedule execution of future events in java app not in database.
You should consider using ScheduledExecutorService method schedule to delay execution of task to specific point in time.
The only problem you have to solve is how you synchronize task in database with this in schedule.
EDIT:
If you keep map with taskID->ScheduledFuture object returned you can easily call cancel on the object to remove task. But you have to add some kind of last-modification column to detect new and updated tasks and query database to check if there are not any new tasks.
Related
I have a bpmn process that once starts and continues its execution forever based on the Timer cycle event. There is no end event for it.
I had recently done few changes with the workflow and made a redeployment to camunda. Since the existing processes are already running I need an option to stop it which I am finding difficult to do through workflow.
How can I stop existing execution if a new workflow started its execution? Can we achieve that using workflow itself? REST / Java coding cannot be done to achieve this.
I have another question regarding an order by query in camunda.
From the above scenario, i ended up seeing quite a few similar variables in variable table. How can i get the latest variable out of it? orderByActivityInstanceId is the only option i saw, which i feel is not reliable.
You can use other events (conditional, message or signal) to react to the situation in which you want to stop the looping process. You can for instance add an event-based sub process with a interrupting message start event to your process model.
To your second point: https://docs.camunda.org/manual/7.15/reference/rest/history/activity-instance/get-activity-instance-query/
sortBy Sort the results by a given criterion. Valid values are
activityInstanceId, instanceId, executionId, activityId, activityName,
activityType, startTime, endTime, duration, definitionId, occurrence
and tenantId. Must be used in conjunction with the sortOrder
parameter.
https://docs.camunda.org/manual/7.15/reference/rest/variable-instance/get/
is another option
To stop all the active process instances in Camunda, you can do this by calling a Camunda REST API or by Java Coding.
Using REST API
Activate/Suspend Process Instance By Id
Using Java
Suspend Process Instances
If you would like to suspend all process instances of a given process definition, you can use the method suspendProcessDefinitionById(...) of theRepositoryService and specify the suspendProcessInstances option.
Thanks a lot, i appreciate your response #amine & #rob.
I got it resolved using a signal event. Every time when a new process is deployed it triggers a signal event that will stop the recursion.
To sort the data there are options within camunda. But I had done it differently.
If there is more than one variable, I fetch them using versionTag from the process definition table.
In my Spring project, I have an entity Customer.
Now once we get a new Customer, we persist it in our system, and exactly after one hour, I want to check if the Customer has made any purchase.
If yes, I take some action. If no, the some other.
I contemplated two strategies,
1) Firing up an event when the Customer is persisted. And then having the event listener thread sleep for one hour. I believe this will be a very bad way to handle this.
2) Having a cron check every once in a while for customers for whom one hour has passed since registration. But then, I figure it will be very difficult to be accurate. I would have to run the cron every minute which won't be great.
Any ideas?
You could use the 'ScheduledThreadPoolExecutor' which as per javadoc is:
A ThreadPoolExecutor that can additionally schedule commands to run after a given delay, or to execute periodically
In your case, when a customer is created, you can use the 'schedule' method to wake up after 1 hour and then perform required activities. This method can also be used if you want those activities to be executed periodically as well.
I believe run the cron every minute is not that bad, how many customers would you handle in one minute?
Although not sure why you cannot use the event when a registered Customer will make any purchase i.e. when a particular registered customer will make purchase you can take the action inline as and then.
You described 2 strategies both will work but I would prefer to run cron job which you can configure explicitly. In that way you avoid the overhead of maintaining the threads. If you configure the cron job timing correctly and allow a single job to run at a time I do not see any problem with that. Remember cron jobs are used for batch processing rather than handling events.
I am developing spring mvc application.
I have gone through below links
http://docs.spring.io/spring/docs/current/spring-framework-reference/html/scheduling.html#scheduling-annotation-support-scheduled
http://www.mkyong.com/spring-batch/spring-batch-and-spring-taskscheduler-example/
These guide for how to schedule.
But I have to give it to the users, to schedule(run on daily/weekly basis etc.) some functionality from GUI.
Can any one please help me how can I achieve this?
Suppose you have several tasks to be scheduled by user.
Define a Enum for the tasks names and a Runner to run task by enum. Define a job to be executed every second (minute, hour). The job just checks whether there is a user's task to be executed.
Now user defines such a task whith following params
TaskType (the Enum value)
TaskTime (when it should be started e.g. 12:00)
TaskPeriod (how often it should be called)
TaskTime and TaskPeriod could be joined e.g. in cron expression.
Then all the task info is stored somewhere (e.g. in DB).
Your permanent Job every second reads from the DB whether there is a task to be executed. It checks task time and task period and compares with current time. If it's time to start it gets enum value and calls Runner's method for the enum.
Please check the link. It explains how to schedule tasks by giving crone expressions in a property file.
Other solution is using the quartz library directly. We can schedule or reschedule jobs easily using that. Refer this.
Hope this will help.
I have a table which has event-details. New records will be inserted to this table by another process continuously. The table has a column Event-end-time.
I have to design a mechanism to invoke a java method to process the events upon reaching the event end time. Some of the option i have are :
Continuously query the database (every 1 min) and find the next latest report to be processed and invoke it on reaching the end time.
Figure out if there is any built in mechanism in ORACLE database to send the java application a notification / Oracle itslef invoking the java method upon reaching the end time of the event.
I have seen options for notification if an record is Inserted/updated/deleted (trigger based) , but till now i have had no luck if the Notification condition to be made custom(if time specified in a column of teh record is reached).
Any advice regarding this will be much appreciated.
Regards,
Deepak
The best way that I know of to do this is via Oracle AQ ( a JMS implementation )
There is also database change notification, which I don't have any experience in, but could be what you are after, I believe it actually builds upon AQ.
/* removed trigger idea because the event end data is already in the table and the action
* should be fired when the event date/time is reached
*/
Since you want to fire your event when a certain time is passed, it could simpley be adding a Oracle Scheduler job with a start date identical to the event end time. See CREATE_JOB Procedure on Oracle Documentation site. Oracle Scheduler is very powerfull and can start all kinds of actions like pl/sql code, procdures and shell scripts, that can be local and remote using credentials.
I'm about to create a small application which will be responsible for sending out various reports to various users at various intevals. We might be talking about 50 or 100 different reports going to different people. Some reports needs to be generated every day, some every week, and some every month.
I've been using the Quartz library earlier to run tasks at regular intervals. However, in order to keep things simple I like the thought of having a single Quartz thread taking care of all reports. That is, the thread should loop through all reports, say every 15 minutes, and determine wether it is time for one or more to be generated and sent. It does not matter if a report is generated at 12:00 or 12:15.
I'm thinking about wether it would be possible, somehow, for each report to set up specific times such as "mon#12:00,wed#12:00" or "fri#09:30". Then, based on that, the thread would determine if it was time to send a report or not.
My question is; has anyone else done something like this and does any libraries exist which can make it easy to implement this task?
why not simply register a separate quartz task instance for each report and let Quartz handle all the scheduling for you? That is after all the point behind it.
you can create just single thread and it would ping a "job schedule data structure" at some time interval to see if it needs to run a report. If yes, it would run the report, otherwise, it would go for a short nap and ping again after specified sleep time.
It will cause problem if one job takes too much time to complete and you start accumulating jobs.
The job schedule data structure would keep its record sorted by time stamp.