0

I have developed a REST-ful web service using Jersey in Java. It is basically a JSON service wrapped around scraped web data. At the moment I serialize my entire scraped data set (A Set<Object>) to a file and when the user requests data I load it from disk and deserialize it. The web application will probably be running on a Tomcat server.

However, this data might change at any point during the day so I would like to update it every n hours. I know how to update the file periodically (e.g., a ScheduledExecutorService) but I'm unsure where I would execute the code due to not being familiar with the flow of a Tomcat server.

For example, as per this article it would be a bad idea to execute the ScheduledExecutorService in the resource class as it is created per user request.

Any help is greatly appreciated.

Christophe De Troyer
  • 2,852
  • 3
  • 30
  • 47

2 Answers2

2

I am sure that you have a Context for this, maybe like a Java servlet Context. What you can do is create a method that creates a thread which does the file updating for you. Something like:

private static class myWorker extends Thread {

//Constructor
public myWorker() {
//set your parameters
}

@Override
run(){
    while(true) {
        //Do your file updating
        sleep X;
        //X is the time between each update

    }

}

}

and create an instance of this class in your context definition and start the thread.

One thing you can keep in mind is that you might face the fact that you are writing to your file when also you try to read it at the same time (by a jersey request). So I suggest you use a syncronized void to read/write to it..

Hope it helps!

Cesar Villasana
  • 681
  • 3
  • 6
  • Hmm, this sounds like a good solution. I think I have something working. I actually did what this person did here: http://stackoverflow.com/questions/18367514/servletcontextlistener-not-being-invoked. Does that sound good enough? I spawned my thread there and from the looks of it, it only get executed once! :) – Christophe De Troyer Sep 25 '14 at 08:01
  • 2
    Yes!, that is exactly what I meant with the Context definition. In the url you gave, that person is creating a Context. And you can initialize your worker thread inside the contextInitialized method by doing myWorker.start() (after creating it of course). Cheers! – Cesar Villasana Sep 25 '14 at 14:21
1

why it shall not be a good idea to use a scheduler? For example, i'm using a quartz scheduler to fetch new cache data from a cache proxy by calluing a rest service. The scheduler is using a trigger with a expression like "0 0/2 * * * ?", which means trigger 2 minutes.

Example:

public class CacheTrigger {
    public CacheTrigger initTrigger(Class<? extends Job> jobClazz) {
        try {
            scheduler = new StdSchedulerFactory().getScheduler();
            job = JobBuilder.newJob(jobClazz).withIdentity("CacheLoaderJob","group1").build();
            trigger = newTrigger().withIdentity("CacheLoaderJob")
                .withSchedule(CronScheduleBuilder.cronSchedule("0 0/1 * * *  ?")).build();
        } catch (final SchedulerException e) {
            //logging
        }
        return this;
    }


    public void initScheduling() {
        try {
            if ( !isStarted ) {
                scheduler.scheduleJob(job, trigger);
                scheduler.start();
                isStarted = true;
            } else {
                logger.logInfo("cache trigger was already started.");
            }
        } catch (final SchedulerException e) {
            logger.logException(this.getClass(), e.getMessage());
        }
    }
}

jobClazz refers to the following:

public class CoreCacheLoaderJob implements Job {

@Override
public void execute(JobExecutionContext context) throws JobExecutionException {

    //do the update or refresh job

}

This works for me on a tomcat machine which is up and running since almost 12 month. Hope this will be helpful for you.

piet
  • 376
  • 1
  • 5
  • 17
  • in Jersey2 Application, how do we configure web.xml for quartz and where to instantiate the Scheduler to be available across Different API Classes? – zee Jan 25 '17 at 18:56