I'm working with Java Play Framework (2.3.6) and have some problems handeling scheduled tasks. Sometimes some of my recurring tasks crash with an exception. So I want to create a website to check the status of my scheduling tasks to have a quick view, if each tasks still runs without problems.
I know, I have also to check the exceptions but the website would be a nice controlling tool.
So I have some scheduled tasks like this one:
ExecutionContext dispatcher = Akka.system().dispatcher();
FiniteDuration timeNow = Duration.create(0, TimeUnit.SECONDS);
FiniteDuration time1m = Duration.create(1, TimeUnit.MINUTES);
Recorder recorderTask = new Recorder(); // implements Runnable
Akka.system().scheduler().schedule(timeNow, time1m, recorderTask, dispatcher);
Now, is there any possibility to check the status of my task (like it's alive)?
Thanks for your help!
Related
I develop a simple Spring Boot app that consumes REST and writes to DB.
I tried a #Scheduled annotation to initiate a task to run it periodically.
But the scheduling process starts automaticly, which is not exactly what I want.
I need an ability to start and stop a scheduled task from a web page.
When a user opens a page he must see a status of a process : Running/Stoped.
What is the easy way to implement it? Create a new thread? How to get a status of a process? Save it in db?
Maybe smb has an example of starting and stoping schedduled task from web page?
Try to use ScheduledExecutorService. For example, first of all create a ScheduledExecutorService:
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(Runtime.getRuntime().availableProcessors());
then create a scheduled task:
ScheduledFuture<?> task = scheduledExecutorService.scheduleAtFixedRate(
() -> System.out.println("some task"), 0, 30, TimeUnit.SECONDS);
and when you want to cancel the task, do the following:
task.cancel(true);
I have a problem, I am trying to execute a Task in ScheduledExecutorService, and I am executing the task with the command:
updateTagDataHandle = scheduler.scheduleWithFixedDelay(updateTagDataRunnable, 500, 500, TimeUnit.MILLISECONDS);
and after several success runs it stops. the task itself takes a few seconds I checked with println that it go to the end of the task with no errors, and I print any exception and didnt see an exception in the end. I need it to continue run infinite number of times.
any help would be appreciated
edit
my code for initializing the task scheduler was:
scheduler = Executors.newScheduledThreadPool(1);
so the corePoolSize = 1 so there only one thread alive and the task share this on thread. but setting the threadPool to be more than one is not helping and still there seems to be only one thread active.
same question here:
Executors Factory method newScheduledThreadPool always returns the same Thread pool
and here:
Why doesn't ScheduledExecutorService spawn threads as needed?
any help would be appreciated
edit:
didnt find a solution so used the scheduler custom thread creation :
scheduler = Executors.newScheduledThreadPool(7, new ThreadFactory() {
#Override
public Thread newThread(Runnable r) {
return new Thread(r);
}
});
Try changing the initial delay to 1000 milliseconds.
I was trying the same code in my android app and this solved the problem.
I'm going to build a web application that's going to host urban games.
A user visits my website, clicks "Start game" and starts receiving some SMS messages when gets to some location and has to answer them to get points.
Is Play suitable for this kind of application? After clicking the "start game" button some logic has to go on its own course. How would I handle checking geolocation of the players (I have API for that) parallely? I would like to ping the player every ~5 sec. and do some logic. The user of course has to be able to use the web application at the same time as it's processing his location, assigning points, sending and receiving messages etc.
So to sum up: I want an application written in Play that starts a separate thread for a game after clicking "start game" and other users are able to view their data (statisctics etc.), while the threads work their way with the game logic.
I found something like jobs but they are documented for version 1.2. After some reading it turned out that Akka is the recommended one now but it uses and actor model.
Is Play + Akka a good choice for my project?
Absolutely. It is very easy to set up computations in a separate ThreadPool (also referred to as ExecutionContext) with the Play Framework. You may want to read up on the documentation here, but in a nutshell you'll be wanting to do something like this in your Application.scala controller file (note this example uses Scala):
// Async Action that's triggered when a user clicks "Start Game".
// Runs logic in separate gameLogicContext thread pool and asynchronously returns a response without blocking of Play's default thread pool.
def startGame = Action.async { implicit request =>
Future {
// ... your game logic here. This will be run in gameLogicContext
Ok("Game started in separate thread pool") // http response
}(Contexts.gameLogicContext) // the thread pool the future should run in.
}
And then you will set up a separate gameLogicContext thread pool within your application.conf file:
play {
akka {
actor {
game-logic-context = {
fork-join-executor {
parallelism-min = 300
parallelism-max = 300 // thread pool with 300 threads
}
}
}
}
}
I had a need to limit the connection rate (in my servlet) to certain external service and I decided to give ScheduledExecutorService a try. Scheduling itself seems to function just fine, but output gets printed only occasionally - in most cases nothing is outputted. Why does such happen? I'm using Tomcat 7 as a test server.
int waitingtimeinmilliseconds = 5000;
ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
ScheduledFuture scheduledFuture = scheduledExecutorService.schedule() {
public void run() {
Fetcher fetcher = new Fetcher(loginname, password);
List<Item> items = fetcher.fetchItems();
// do something with the results
//ServletOutputStream
out.print("teststring" + items.size());
}
}, waitingtimeinmilliseconds, TimeUnit.MILLISECONDS);
scheduledExecutorService.shutdown();
You'll find very exhaustive description of what is causing your problem in: HttpServletResponse seems to periodically send prematurely (also check: starting a new thread in servlet).
Basically you cannot use external threads to write to servlet output. Once you leave doGet()/doPost(), servlet container assumes you are done and discards the output after flushing it to the client. But since you are writing to the stream asynchronously, sometimes the output gets through, while other times gets discarded.
If you want your rate limiting to be very scalable, consider async servlets (from 3.0). If you just want to throttle some clients, RateLimiter from guava will work for you1.
1 - see RateLimiter - discovering Google Guava on my blog.
I have a web application, I need to run a backgroung process which will hit a web-service, after getting the response it will wait for few seconds(say 30) then again hit the service. The response data can vary from very less to very large, so i dont want to call the processagain untill i am finished with processing of data. So, its a recursive call with a time delay. How i intend to do is:
Add a ContextListener to web app.
On contextIntialized() method , call invokeWebService() i.e. arbitary method to hit web service.
invokeWebService will look like:
invokeWebService()
{
//make request
//hit service
//get response
//process response
timeDelayInSeconds(30);
//recursive call
invokeWebService();
}
Pls. suggest whether I am doing it right. Or go with threads or schedulers. Pls. answer with sample codes.
You could use a ScheduledExecutorService, which is part of the standard JDK since 1.5:
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
Runnable r = new Runnable() {
#Override
public void run() {
invokeWebService();
}
};
scheduler.scheduleAtFixedRate(r, 0, 30, TimeUnit.SECONDS);
It is not recursive but repeated. You have two choice here:
Use a Timer and a TimerTask with scheduleAtFixedRate
Use Quartz with a repeated schedule.
In quartz, you can create a repeated schedule with this code:
TriggerBuilder.newTrigger().withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(30))
.build()
From what I am getting, waiting sort of implies hanging, which I do not really think is a good idea. I would recommend you use something such as Quartz and run your method at whatever interval you wish.
Quartz is a full-featured, open source job scheduling service that can
be integrated with, or used along side virtually any Java EE or Java
SE application
Tutorials can be accessed here.
As stated in here you can do something like so:
JobDetail existingJobDetail = sched.getJobDetail(jobName, jobGroup);
if (existingJobDetail != null) {
List<JobExecutionContext> currentlyExecutingJobs = (List<JobExecutionContext>) sched.getCurrentlyExecutingJobs();
for (JobExecutionContext jec : currentlyExecutingJobs) {
if(existingJobDetail.equals(jec.getJobDetail())) {
//String message = jobName + " is already running.";
//log.info(message);
//throw new JobExecutionException(message,false);
}
}
//sched.deleteJob(jobName, jobGroup); if you want to delete the scheduled but not-currently-running job
}