What else do I have to do, other than making a cron.xml file for scheduling ? I am getting the same exception:
java.security.AccessControlException: access denied
("java.lang.RuntimePermission" "modifyThreadGroup")
as I was getting before.
This is my cron.xml :
<?xml version="1.0" encoding="UTF-8"?>
<cronentries>
<cron>
<url>/tw</url>
<description>Tweet every half an hour</description>
<schedule>every 30 minutes from 8:00 to 17:00</schedule>
</cron>
</cronentries>
/tw is the servlet that has a doGet method which uses java.util.Timer to schedule the task.
You have to not use Timer (or anything else that uses threads via the normal Java API). AppEngine doesn't allow creation of additional threads as part of a request except via its own special interface (and they're not allowed to outlive the request).
The point of crons is that they're already called once for each time they're supposed to happen. You don't need to do any further "scheduling" in the servlet - just do what you want to happen when the cron fires.
I think you're doing this a bit wrong. Cron is used to specify at what intervals/time a servlet will be called. So, your actual servlet needs to do the work (i.e. send a tweet) and cron service will make sure it's called at correct times.
You can use threads, subject to restrictions described in The Sandbox. But you may not need to use threads at all. Schedule the work using a Push Queue. To reduce platform overheads, AppEngine overprovisioning may start either your cron task or your queued task multiple times, so your logic may need to take extra precautions to avoid sending duplicate tweets.
Related
I know that I need to set up all my crons in cron.xml file. I now want to set the schedules dynamically i.e. in a database table so that I can tweak them with a simple update.
For example instead of having the below:
<cron>
<url>/cron/task1</url>
<description>Task 1 </description>
<schedule>every 5 minutes</schedule>
</cron>
I want to have something like:
<cron>
<url>/cron/task1</url>
<description>Task 1 </description>
<schedule>${TASK1_SCHEDULE}</schedule>
</cron>
where TASK1_SCHEDULE will be an entry from the database.
Is that possible ? Or is there any other way to achieve that programmatically?
You cannot dynamically modify the cron.xml file to accept new jobs or modifications to the list of jobs.
I agree with Martin in that you write a Cron Job that executes at the threshold interval that you can tolerate for your application i.e. 1 min or 2 minutes. In that, I would suggest manage a custom Job definition entity that contains various parameters depending on your needs, including the time for next execution.
In your Cron Job, once the time for next execution has passed, you should use a TaskQueue to execute the functionality, rather than running each one on our own and waiting for it to complete.
Take a look at the following article that provides a similar framework for doing so: http://pisarenko.net/blog/2013/09/03/creating-dynamic-task-scheduler-on-appengine/
Write a custom scheduler because you cannot change cron.xml from your code. Call your scheduler at the shortest interval you require. Within your scheduler, query the database for tasks that are due and execute them.
Because of browser compatibility issues, I have decided to use long polling for a real time syncing and notification system. I use Java on the backend and all of the examples I've found thus far have been PHP. They tend to use while loops and a sleep method. How do I replicate this sort of thing in Java? There is a Thread.sleep() method, which leads me to...should I be using a separate thread for each user issuing a poll? If I don't use a separate thread, will the polling requests be blocking up the server?
[Update]
First of all, yes it is certainly possible to do a straightforward, long polling request handler. The request comes in to the server, then in your handler you loop or block until the information you need is available, then you end the loop and provide the information. Just realize that for each long polling client, yes you will be tying up a thread. This may be fine and perhaps this is the way you should start. However - if your web server is becoming so popular that the sheer number of blocking threads is becoming a performance problem, consider an asynchronous solution where you can keep a large numbers of client requests pending - their request is blocking, that is not responding until there is useful data, without tying up one or more threads per client.
[original]
The servlet 3.0 spec provides a standard for doing this kind asynchronous processing. Google "servlet 3.0 async". Tomcat 7 supports this. I'm guessing Jetty does also, but I have not used it.
Basically in your servlet request handler, when you realize you need to do some "long" polling, you can call a method to create an asynchronous context. Then you can exit the request handler and your thread is freed up, however the client is still blocking on the request. There is no need for any sleep or wait.
The trick is storing the async context somewhere "convenient". Then something happens in your app and you want to push data to the client, you go find that context, get the response object from it, write your content and invoke complete. The response is sent back to the client without you having to tie up a thread for each client.
Not sure this is the best solution for what you want but usually if you want to do this at period intervals in java you use the ScheduleExecutorService. There is a good example at the top of the API document. The TimeUnit is a great enum as you can specify the period time easily and clearly. So you can specify it to run every x minutes, hours etc
I need to wait for a condition in a Spring MVC request handler while I call a third party service to update some entities for a user.
The wait averages about 2 seconds.
I'm calling Thread.sleep to allow the remote call to complete and for the entities to be updated in the database:
Thread.currentThread().sleep(2000);
After this, I retrieve the updated models from the database and display the view.
However, what will be the effect on parallel requests that arrive for processing at this controller/request handler?
Will parallel requests also experience a wait?
Or will they be spawned off into separate threads and so not be affected by the delay experienced by the current request?
What are doing may work sometimes, but it is not a reliable solution.
The Java Future interface, along with a configured ExecutorService allows you to begin some operation and have one or more threads wait until the result is ready (or optionally until a certain amount of time has passed).
You can find documentation for it here:
http://download.oracle.com/javase/6/docs/api/java/util/concurrent/Future.html
I am working on a servlet that can take a few hours to complete the request. However, the client calling the servlet is only interested in knowing whether the request has been received by the servlet or not. The client doesn't want to wait hours before it gets any kind of response from the servlet. Also since calling the servlet is a blocking call, the client cannot proceed until it receives the response from the servlet.
To avoid this, I am thinking of actually launching a new thread in the servlet code. The thread launched by the servlet will do the time consuming processing allowing the servlet to return a response to the client very quickly. But I am not sure if this an acceptable way of working around the blocking nature of servlet calls. I have looked into NIO but it seems like it is not something that is guaranteed to work in any servlet container as the servlet container has be NIO based also.
What you need is a job scheduler because they give assurance that a job will be finished, even in case a server is restarted.
Take a look at java OSS job schedulers, most notably Quartz.
Your solution is correct, but creating threads in enterprise applications is considered a bad practice. Better use a thread pool or JMS queue.
You have to take into account what should happen server goes down during processing, how to react when multiple requests (think: hundreds or even thousands) occur at the same time, etc. So you have chosen the right direction, but it is a bit more complicated.
A thread isn't bad but I recommend throwing this off to an executor pool as a task. Better yet a long running work manager. It's not a bad practice to return quickly like you plan. I would recommend providing some sort of user feedback indicating where the user can find information about the long running job. So:
Create a job representing the work task with a unique ID
Send the job to your background handler object (that contains an executor)
Build a url for the unique job id.
Return a page describing where they can get the result
The page with the result will have to coordinate with this background job manager. While it's computing you can have this page describe the progress. When its done the page can display the results of the long running job.
I am building an app for which I need to set up cron jobs. What I want to do is to set the specific minutes in a hour where specific crons should run. For instance:
Task1 at 1st minute of the hour
Task2 on every second minute of the hour
Task3 every 2 minute only in the second half of the hour
Building this in the standard Unix cron format is reasonably straightforward, but could not figure out how to do it in the Google-App-Engine.
The documentation does not list any non-trivial examples. Any suggestions on how to do it? Examples would be excellent.
The documentation you linked to seems to indicate that it isn't possible to do what you want using only Cron for Java (unless they have an undocumented feature for it). In particular this doesn't appear to allow for multiple times.
time specifies the time of day, as HH:MM in 24 hour time.
The Python version says the exact same thing.
However, one solution (albeit somewhat more expensive in terms of CPU usage) would be to call a URL every minute, and from the handler for that URL, dispatch out to whatever other calls you need.
In other words, something like:
<?xml version="1.0" encoding="UTF-8"?>
<cronentries>
<cron>
<url>/run-scheduled-tasks</url>
<description>Run all scheduled tasks</description>
<schedule>every 1 minutes</schedule>
</cron>
</cronentries>
Then in run-scheduled-tasks, check a database for when each task last run, and if your complex condition for triggering them has occurred since then.
If the documentation is correct you can't get as granular as you are wanting. Doesn't look like they support picking a particular minute of the hour. Or a subset of an hour.
You might have to get creative. Why do you need such specific timing?
This may seem silly. Write three servlet. And schedule them from another UNIX machine on the other part of the world :D. Or even you can write a java app to do it. enjoy
Have a look at Quartz and see if that'll solve your problem.