Spring Boot - check if target date is reached for objects - java

I don't know if it's a real question or not... But i'd like to know how some of you will approach this...
I have a Spring Boot application.
Then I have a Interruttore.class, which has, among others this field timeoutDatewhich is a Date.
In the app, various instances of this class are used. The timeoutDate field can be updated, for every single object, by various factors. I need to know when the actual date reaches the timeutDate.
In a very simple (and not optimized) way i would have created a #Scheduled task, but the delay will be too short and i don't like it, how can i do?

In a very simple (and not optimized) way i would have created a
#Scheduled task, but the delay will be too short and i don't like it,
how can i do?
Why too short ?
You can use the delay you wish.
#Scheduled(fixedDelay=50000) // 50 secs
#Scheduled(fixedDelay=1000) // 1 secs

Look at the documentation for Spring's various task scheduling APIs: http://docs.spring.io/spring/docs/current/spring-framework-reference/html/scheduling.html
You have plenty of choices. I think the "not optimised" idea you might have is to schedule a repeating task which searches your beans to find the expired ones. That would indeed be inefficient for large numbers of beans.
You could simply create a scheduled task for each bean with a timeoutDate, created at the same time as that bean, and when its timeoutdate is updated (Spring AOP could help with this).
Alternatively you could keep a list of beans, sorted by timeout date. Schedule a task for the time of the earliest expiry. It reaps that bean and any others who's time is past, then schedules a new task for the time of the next expiry.
If you do this, you need to make sure that:
- it handles new objects added to the list (perhaps with an expiry date earlier than the currently scheduled cull)
- it handles the case where an object is removed for a reason other than a timeout
(Unless neither of those things can happen -- in which case don't worry about it!)

You can use Quartz or Jesque(redis). Whatever task needs to be executed, you can schedule that task at that time.
If this time value can be updated anytime, you can cancel(unschedule) the previously scheduled task(using task identifiers or keys) and reschedule it with the updated time.

Related

Java EE6 Schedule Range

I'm required to have a schedule that runs every 5 minutes from 10 am to 5:45pm, how do I do this with the #Schedule annotation?
So far, I'm limited to the #Schedule(hour=10-18;minute=*/5), but they insist I should have it until 5:45pm not 6pm.
As clearly stated in the documentation for #Schedule and #Schedules, you need to have two #Schedule annotations if you run two schedules - even if you don't like that fact.
Due to the cron-like limitations of having ranges only within individual elements (hours, minutes, seconds...), it's simply not posible to give that additional information of skipping the last two executions at *:50 and *:55 only at 5pm.
That said, you'd probably end up with something like
#Schedules({
#Schedule(hour="10-16" minute="*/5"),
#Schedule(hour="17" minute="0,5,10,15,20,25,30,35,40,45")
})
As you end up with schedule information into you sourcecode that way (even if it's in the form of an annotation) you could just as well run every five minutes and immediately return from the method if called after 5:49pm

Which java concurrent to use for cleaning DB (on demand/scheduled)

I have a thread cleaner in my code that is being created if the DB capacity was exceeded, the capacity is checked on every insertion to the DB. I would like to add more functionality to this cleaner and clean also when number of files exceeding, lets say 10000 files. The new functionality should run scheduled.
I want to be able to clean the DB in 2 ways:
1. On demand.
2. Scheduled, every day on X hour.
Which concurrent java class to use?
How can I make sure that the same thread will be used by the 2 ways above?
Code that would perform cleanup of DB should be completely separated out of scheduling (single responsibility principle), so that you could execute it at any time from some other code.
As for scheduling, I would suggest you looking at Quartz scheduler, and get familiar with CRON so that you could extract it to properties to have possibility to change scheduling trigger without modifying your code.
You should synchronize your code so that no more than one cleanup gets performed at the same time, this should be easy with standard synchronize.
If you wish to make it very simple and don't want to add new dependencies, you can go with standard Java solution: Timer. Timer#scheduleAtFixedRate can provide fixed rate execution. Which means you'll have to add extra code whenever new requirements will show up (e.g., don't schedule at weekend).

EJB timer performance

I am trying to decide if use a java-ee timer in my application or not. The server I am using is Weblogic 10.3.2
The need is: After one hour of a call to an async webservice from an EJB, if the async callback method has not been called it is needed to execute some actions. The information regarding if the callback method has been called and the date of the execution of the call is stored in database.
The two possibilities I see are:
Using a batch process that every half hour looks for all the calls that have been more than one hour without response and execute the needed actions.
Create a timer of one hour after every single call to the ws and in the #Timeout method check if the answer has come and if it has not, execute the required actions.
From a pure programming point of view, it looks easier and cleaner the second one, but I am worry of the performance issues I could have if let's say there are 100.000 Timer created at a single moment.
Any thoughts?
You would be better off having a more specialized process. The real problem is the 100,000 issue. It would depend on how long your actions take.
Because its easy to see that each second, the EJB timer would fire up 30 threads to process all of the current pending jobs, since that's how it works.
Also timers are persistent, so your EJB managed timer table will be saving and deleting 30 rows per second (60 total), this is assuming 100K transactions/hour.
So, that's an lot of work happening very quickly. I can easily see the system simply "falling behind" and never catching up.
A specialized process would be much lighter weight, could perhaps batch the action calls (call 5 actions per thread instead of one per thread), etc. It would be nice if you didn't have to persist the timer events, but that is what it is. You could almost easily simply append the timer events to a file for safety, and keep them in memory. On system restart, you can reload that file, and then roll the file (every hour create a new file, delete the older file after it's all been consumed, etc.). That would save a lot of DB traffic, but you could lose the transactional nature of the DB.
Anyway, I don't think you want to use the EJB Timer for this, I don't think it's really designed for this amount of traffic. But you can always test it and see. Make sure you test restarting your container see how well it works with 100K pending timer jobs in its table.
All depends of what is used by the container. e.g. JBoss uses Quartz Scheduler to implement EJB timer functionality. Quartz is pretty good when you have around 100 000 timer instances.
#Pau: why u need to create a timer for every call made...instead u can have a single timer thread created at start up of application which runs after every half-hour(configurable) period of time and looks in your Database for all web services calls whose response have not been received and whose requested time is past 1 hour. And for selected records, in for loop, it can execute required action.
Well above design may not be useful if you have time critical activity to be performed.
If you have spring framework in your application, you may also look up its timer services.http://static.springsource.org/spring/docs/1.2.9/reference/scheduling.html
Maybe you could use some of these ideas:
Where I'm at, we've built a cron-like scheduler which is powered by a single timer. When the timer fires the system checks which crons need to run using a Quartz CronTrigger. Generally these crons have a lot of work to do, and the way we handle that is each cron spins its individual tasks off as JMS messages, then MDBs handle the messages. Currently this runs on a single Glassfish instance and as our task load increases, we should be able to scale this up with a cluster so multiple nodes are processing the jms messages. We balance the jms message processing load for each type of task by setting the max-pool-size in glassfish-ejb-jar.xml (also known as sun-ejb-jar.xml).
Building a system like this and getting all the details right isn't trivial, but it's proving really effective.

Boolean flag available over multiple instances in App Engine

I have an app that runs over several instances and all requests come through one servlet.
I need to run a cron job which executes once a week for about 3 minutes. During that cron call some kind of flag/boolean will be modified somewhere so that the servlet can pick up and send an "server temporarily unavailable" type message back instead of processing the request. Once the cron job is complete it will flag it back to true.
I cannot use a singleton or a static boolean as the app will be in multiple instances. Nor do I want the servlet to have to fetch a value from the datastore on every request, as it will mean hundreds of thousands of extra datastore reads.
What can I do? Any ideas?
I think you may be able to store boolean in memcached. GAE has a Cache API for Memcached. However note that cache values are not persistent and may not be survived for even 3 minutes. I think you should have a firm time to start cron task hardcoded in one of your Java classes or .properties file and then when your task finishes, it should look at that hard-coded time and schedule itself for next round according to that time.
And by this way your servlet can also look at that time and do not serve requests in the interval you are going to specify. Yeah, that will be very fast but your jobs will be scheduled to a fixed time periodically and you won't be able to change this unless you re-deploy application.
I think the better solution is you should keep the boolean in the datastore and make use of cache. See the following algorithm:
is my boolean in the cache?
yes:
[alright, then choose to serve or not to serve request using it.]
no:
[fetch variable from datastore and put it on the cache.] (cache miss)
Again, cache will be fast, but not as much as hard-coding the schedule in the program.
EDIT: Another solution. (however not possible to implement)
If you want to serving pages during the task execution, you should use a task api
First of all you should be familiar with using countdown for your task (in this case next week) http://code.google.com/appengine/docs/java/javadoc/com/google/appengine/api/taskqueue/TaskOptions.html#countdownMillis(long)
Then you can use size() method of Queue – which I was expecting it to be there but apparently Google didn't implement it– to see if task queue size is 0, then it means it is processed right now because when the task finishes, it submits itself again to 1 week later.
One approach would be to have the cron job publish a message to a JMS topic to which all the servlet instances were listening. The messages could inform the servlet instances to set a value in the static boolean you mentioned to true or false.

How to create a Java timer that repeats at different times

I have some stock market data. I want to simulate the stock market by having prices sent at intervals that can be determined from the times at which trades occur.
What would the best way be to do this.
So far I have a class with static variables and methods in which I am storing the hour, min, millseconds for the last trade time. I then use the trade time for the current trade and calculate it from the stored last trade values.
I then store as a static member variable the "interval" in milliseconds in the same class as the time variables are stored.
I use this line:
timer.schedule(new RemindTask(), TimeStore.getNextInterval());
where TimeStore.getNextInterval() retrieves the interval that was calculated.
Can you think of a better way, this doesnt seem to work, nor does it seem very elegant.
If you don't want to go as far as using Quartz then look at Java's ScheduledExecutorService.
http://java.sun.com/javase/6/docs/api/java/util/concurrent/ScheduledExecutorService.html
Use Quartz.
From the linked page:
Quartz is a full-featured, open source job scheduling system that can be integrated with, or used along side virtually any J2EE or J2SE application - from the smallest stand-alone application to the largest e-commerce system. Quartz can be used to create simple or complex schedules for executing tens, hundreds, or even tens-of-thousands of jobs; jobs whose tasks are defined as standard Java components or EJBs. The Quartz Scheduler includes many enterprise-class features, such as JTA transactions and clustering.
Well For Your Task I have a different Solution.
You can use javax.swing.Timer instead of java.util.Timer;
and then u can call the constructor by sending the delay which u want and null for action actionListeners and then you can add and addactionListeners(this) and override actionPerformed with ur task. In javax.swing.Timer the actionListeners are notified at selected interval repeatedly

Categories