I have an EJB application and used EJB Timer to place some tasks(persisted database sequence ID) with expire date/time on it and once time expires remove the tasks from the Timer and invoke some method.
I am in situation that there are bunch of the tasks placed in EJB Timer and whenever Timer Timeouts and it gets each of the tasks from Timer and try to invoke some method that has to update some database associated with task id. I found some how those all tasks are deleted from database during some database moves.
Now Ejb Timer keep repeating the Timeout and the tasks keep throwing exception in logs. I don't the way I do not know how to remove these tasks from EJB Timer so it does not try to call method with each task id which are no longer there.
Any help will be appreciated!
Thanks!
There is no ability to remove timers from the admin console, but you can use the WAS_HOME/bin/cancelEJBTimers command to remove them. You can view them first using the findEJBTimers command.
Use cancelEJBTimer.sh command under /opt/IBM/WebSphere/AppServer/bin
(your path may be different).
Don't put any server name and filter and it will display the instruction. It is very easy to kill the zombie tasks.
Related
DO you know if it's possible to setup some timer event/task to wait for some time for receiving some action? For example, I need to set up some mechanism where I invoke timer task which waits for example for 10 seconds then I will restart checking process.
Thanks,
You can try <pick> It implements the deferred choice workflow pattern, i.e. it can wait for several messages and several timers concurrently. The event that occurs first wins and the contained activity will be executed.
So there is a exists for BPMN which we've used for our needs.
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 have run into a case where I have to use a persistent Scheduler, since I have a web application that can crash or close due to some problems and might lose it job details if this happens . I have tried the following:
Use Quartz scheduler:
I used RAMJobStore first, but since it isn't persistent, it wasn't of much help. Can't setup JDBCJobStore because, this will require huge code changes to my existing code base.
In light of such a scenario,
I have the following queries:
If I use Spring's built in #Schedule annotation will my jobs be persistent..? I don't mind if the jobs get scheduled after the application starts. All I want is the jobs to not lose their details and triggers.?
If not, are there any other alternatives that can be followed , keeping in mind that I need to schedule multiple jobs with my scheduler.?
If yes, how can I achieve this.? My triggers are different each job. For e.g I might have a job that is scheduled at 9AM and another at 8.30AM and so on.
If not a scheduler, then can I have a mechanism to handle this.?
One thing, I found is that the documentation for Quartz isn't very descriptive. I mean it's fine for a top level config, but configuring it on your an application is a pain. This is just a side note. Nothing to do with the question.
Appreciate the help. :)
No, Spring's #Schedule-annotation will typically only instruct Spring at what times a certain task should be scheduled to run within the current VM. As far as I know there is not a context for the execution either. The schedule is static.
I had a similar requirement and created db-scheduler (https://github.com/kagkarlsson/db-scheduler), a simple, persistent and cluster-friendly scheduler. It stores the next execution-time in the database, and triggers execution once it is reached.
A very simple example for a RecurringTask without context could look like this:
final RecurringTask myDailyTask = ComposableTask.recurringTask("my-daily-task", Schedules.daily(LocalTime.of(8, 0)),
() -> System.out.println("Executed!"));
final Scheduler scheduler = Scheduler
.create(dataSource)
.startTasks(myDailyTask)
.threads(5)
.build();
scheduler.start();
It will execute the task named my-daily-task at 08:00 every day. It will be scheduled in the database when the scheduler is first started, unless it already exists in the database.
If you want to schedule an ad-hoc task some time in the future with context, you can use the OneTimeTask:
final OneTimeTask oneTimeTask = ComposableTask.onetimeTask("my-onetime-task",
(taskInstance, context) -> System.out.println("One-time task with identifier "+taskInstance.getId()+" executed!"));
scheduler.scheduleForExecution(LocalDateTime.now().plusDays(1), oneTimeTask.instance("1001"));
See the example above. Any number of tasks can be scheduled, as long as task-name and instanceIdentifier is unique.
#Schedule has nothing to do with the actual executor. The default java executors aren't persistent (maybe there are some app-server specific ones that are), if you want persistence you have to use Quartz for job execution.
Good Day,
I am required to write a java server that performs an action every X minutes. The action is to check a database to see if the current/system time matches any of the times in a database, and to pull out those items, and send a TCP message to them.
Hencen, the database call is local on the machine, so that is no problem. However, at least 10 TCP calls need to be sent out simultaneously. Hence, the tick may actually need to occur on it's own thread. Can I have some suggestions?
Do I need a thread pool?
one thing you can do is create a schedular job and run that job every x minutes. so that job will be perform every x minutes and you need to define your task in job to perform for more info click here
I would use a Timer or else I would use the Quartz Scheduler - the former is more lightweight, while the latter is (optionally) durable (meaning that scheduled tasks will be saved to a database and reloaded when your program restarts).
Either TimerTask (or) ScheduledExecutorServices implementations would be best options for this task. Yes, I think thread pool would be best option because you don't need to create 10 threads every X minutes.
I am using EJB 3.0 Timers in my application.
One thing about EJB Timers is that they are by default persistent which means that when ever there is server restart the Timers will automatically be invoked with out calling them again.
I have a requirement that these timers should be manually be started when ever server is restarted. For this I know we need to change some attribute in config XML which I don't know exact.
Where do I need to change the attribute to set persistent=false.
I am using Weblogic Server.
In EJB 3.0 timers are persistent and there is no attribute to set to make them non-persistent. Possibility to affect this came with EJB 3.1 TimerConfig. Also WebLogic specific configuration does not provide any help.
Create a programmatic Timer (#Timeout Method needed)
TimerConfig timerConfig = new TimerConfig("some info ...", false);
timerService.createIntervalTimer(3000, 1000, timerConfig);
or create automatic timer: just annotate a method with #Schedule:
#Schedule(hour = "*", minute = "*", second = "*", persistent = false)
private void myScheduledMethod(Timer timer) {
// ...
}
For this to work, you need to use EJB 3.1 or higher, that means you need a Java EE 6 (or higher) Server, or container supporting this ejb version.
For Weblogic use need at least the version 12cR1.
If this did not help, i would suggest to cancel all Timers at shutdown, i.e. in the #PreDestroy method of the corresponding bean.
I hope, i could help.
This thread is old, but I think the concerns still apply nowadays.
There is an attribute since EJB 3.1 to specify EJB persistency, as #mikko-maunu indicated, yet I've perceived it was modeled with two responsibilities:
to have the schedule configuration persist after system reinitialization;
to refire all eventually misfired triggers at system initialization.
I think the concepts above should have been modeled independently, so we could have a EJB timer stored on a database, and also have finer control over what to do with misfired triggers at system reinitialization, i.e. should them be retriggered or ignored.
Otherwise, it would seem awkward having a EJB Timer based job module where some of them are stored in a DB and others are not, just because we don't want to refire previous missed triggers for a job scheduled too frequently, running at an hourly basis, for example.
I've noticed, in JBoss 7.1 / Java EE 7, that keeping the schedule information in a database can potentially support a central control for a clustered configuration, instead of having repeated and independent instances of non-persistent time schedules. But the colateral effect is having, for a job triggered many times a day, all eventially misfired triggers fired at once at system reinitialization.
To have finer control over a persistent EJB Timer at restart time, we could, at the #PostConstruct method, check if the timer's getNextTimeout() is a past time. If the timer should ignore misfired triggers, we could cancel the old timer and immediately create a new one, using the same scheduleExpression, so only future triggers will be considered. This seems very useful for timers scheduled to run many times a day.
Another possible, maybe simpler approach is, in the #Timeout method, check if the timer's next execution time, getNextTimeout(), is before the current date and time, and then decide if previous, misfired triggers should be treated or discarded.