Amit
asked on
Triggering a shell command from a java servlet 30 minutes after the http call
Hi,
I want to run a shell process from a servlet. But in the url I can get a delay parameter
http://server//myservlet/executecommand?delay=30
so depending upon the delay the shell process will be called if it's 10 then 10 minutes after the URL call and if it's 30 then 30 minutes after the URL Call
Any pointers for me to get started
I want to run a shell process from a servlet. But in the url I can get a delay parameter
http://server//myservlet/executecommand?delay=30
so depending upon the delay the shell process will be called if it's 10 then 10 minutes after the URL call and if it's 30 then 30 minutes after the URL Call
Any pointers for me to get started
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Bear in mind that suggestions to use the existing JDK classes could tie the thread of the task to the thread(s) of the context in which it's started, which is problematic.
ASKER
Hi
@CEHJ I will be looking into quartz in the evening in the mean time
the attached file is not sending the email after the delay and I am also getting null exceptions in apache logs (because my runnable is returning a null)
So to test what dpearson has suggested I create a simple send mail program that should send email 2 minutes after the http call. But the email is getting sent instantaneously
amit i will try yours too but dpearson's implementation seemed very simple to test
could the experts please take a look at attached file
SendMail.java
@CEHJ I will be looking into quartz in the evening in the mean time
the attached file is not sending the email after the delay and I am also getting null exceptions in apache logs (because my runnable is returning a null)
So to test what dpearson has suggested I create a simple send mail program that should send email 2 minutes after the http call. But the email is getting sent instantaneously
amit i will try yours too but dpearson's implementation seemed very simple to test
could the experts please take a look at attached file
SendMail.java
You almost have it. Your code here:
threadPool.schedule(sendEm ail("mail sent", "mail sent"), interval, TimeUnit.MINUTES);
is actually calling the "sendEmail" method immediately.
What you want is to create a new instance of an object which has a "run" method and then the run method will be called in 2 minutes.
Also you should make this
ScheduledThreadPoolExecuto r threadPool = new ScheduledThreadPoolExecuto r(1);
a member variable - so it doesn't get garbage collected.
Here's a small example app that shows all of the ideas:
Should produce this output:
Started at Thu Oct 29 21:03:07 PDT 2015
Time is Thu Oct 29 21:04:07 PDT 2015 <-- note: 1 minute later
Hope that helps,
Doug
threadPool.schedule(sendEm
is actually calling the "sendEmail" method immediately.
What you want is to create a new instance of an object which has a "run" method and then the run method will be called in 2 minutes.
Also you should make this
ScheduledThreadPoolExecuto
a member variable - so it doesn't get garbage collected.
Here's a small example app that shows all of the ideas:
public class ScheduledTest {
// Static variable so not garbage collected
private static ScheduledThreadPoolExecutor m_executor = new ScheduledThreadPoolExecutor(1);
private static class Task implements Runnable {
// run method will be called later
public void run() {
System.out.println("Time is " + new Date());
}
}
public void start() {
System.out.println("Started at " + new Date());
m_executor.schedule(new Task(), 1, TimeUnit.MINUTES);
}
public static void main(String[] args) throws InterruptedException {
ScheduledTest test = new ScheduledTest() ;
test.start();
// This is just so the main method doesn't exit while we're waiting for the
// schedule to run. You don't need this in a web app since there's no main...
Thread.sleep(5 * 60 * 1000);
}
}
Should produce this output:
Started at Thu Oct 29 21:03:07 PDT 2015
Time is Thu Oct 29 21:04:07 PDT 2015 <-- note: 1 minute later
Hope that helps,
Doug
Bear in mind that suggestions to use the existing JDK classes could tie the thread of the task to the thread(s) of the context in which it's started, which is problematic.CEHJ - can you say a bit more about your concern here? I'm assuming the task will execute on a thread from the executor's pool. Do you see an issue with that?
Doug
ASKER
@Doug thanks a lot for that
@CEHJ I still cannot find a good example of quartz being used for doing a one time delayed task
Here's what I did (see the 2 attached file)
but here while I need the delayed "Hello Quartz" what I don't need is to start the job as soon as it creates the job object
So I don't need the first "Hello Quartz" printed immediately as that will defeat my purpose of needing a delay
SimpleTriggerExample.java
HelloJob.java
@CEHJ I still cannot find a good example of quartz being used for doing a one time delayed task
Here's what I did (see the 2 attached file)
but here while I need the delayed "Hello Quartz" what I don't need is to start the job as soon as it creates the job object
So I don't need the first "Hello Quartz" printed immediately as that will defeat my purpose of needing a delay
SimpleTriggerExample.java
HelloJob.java
ASKER
@doug and @amit how can I do one more thing if in the url parameters I have (this can be n number of delays which I will handle by looking at request array)
delay1=10
delay2=20
delay3=30
then how can I do it without creating multiple threads
delay1=10
delay2=20
delay3=30
then how can I do it without creating multiple threads
CEHJ - can you say a bit more about your concern here? I'm assuming the task will execute on a thread from the executor's pool. Do you see an issue with that?That would be OK if the pool has come from the container. But what if it comes from the servlet the container is executing? I'm thinking of issues like prevention of the servlet being unloaded. It could be OK but i think a division of responsibility is clearer. Spring scheduling might be a better option
ASKER
@CEHJ do you want me to create another thread for the quartz scheduler question i posted above
You can if you want. It might attract more with Quartz experience
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Hi Doug,
How many concurrent requests I can send in this scenario. What I mean to say is that in terms of several requests coming at the same time. Can this code handle it or it needs to be more sophisticated for those kind of scenarios
thanks
-anshu
How many concurrent requests I can send in this scenario. What I mean to say is that in terms of several requests coming at the same time. Can this code handle it or it needs to be more sophisticated for those kind of scenarios
thanks
-anshu
Each concurrent request (coming in as an HTTP request to the web server) can add a task to the queue. Adding the task will take almost no time, so there's no limit there on the maximum concurrency.
Later, the scheduled executor will start processing each of those requests (to send off an email). Currently there is one thread doing this work (the sending of the emails) because we chose a thread pool size of 1:
Make sense?
Doug
Later, the scheduled executor will start processing each of those requests (to send off an email). Currently there is one thread doing this work (the sending of the emails) because we chose a thread pool size of 1:
private static ScheduledThreadPoolExecutor m_executor =
new ScheduledThreadPoolExecutor(1);
If you increase this to a larger number, then you could send out more emails at the same time as each "send email" task would execute in parallel on a different thread.Make sense?
Doug
ASKER
it does make sense, and the thread concurrency etc will be handled by apache/tomcat and my delayed task will fire at the right delayed moment without any issues right !!!
Yep you should be all set to go to massive scale.
ASKER
Hi Doug and CEHJ
I have posted another question in reference to this
https://www.experts-exchange.com/questions/28808959/How-to-create-java-threads-with-multiple-start-and-run-signatures.html
thanks
-anshu
I have posted another question in reference to this
https://www.experts-exchange.com/questions/28808959/How-to-create-java-threads-with-multiple-start-and-run-signatures.html
thanks
-anshu
ScheduledThreadPoolExecuto
threadPool.schedule(new MyTask(), interval, TimeUnit.MINUTES);
and then execute the command inside MyTask (which is a Runnable).
Doug