I have this structure in my Service component in my Spring:
#Autowired
PointController controller;
#Autowired
ParametroService parametroService;
Timer timer = new Timer();
TimerTask timerTask = new TimerTask() {
#Override
public void run() {
List<IntRaptMec> allPointments = getNotValidated();
for(IntRaptMec pointment : allPointments) {
controller.validate(pointment.getIdTemp());
}
}
};
public void doValidationsTask() {
Parametro parametroTempo = parametroService.getParametro("1", "ATRC_MEC", "TEMPO_VERIFICACAO");
timer.scheduleAtFixedRate(
timerTask,
Integer.parseInt(parametroTempo.getValor()) * oneMinute,
Integer.parseInt(parametroTempo.getValor()) * oneMinute
);
}
All that I want is that after the Spring Application fully initializes it will execute the method run() inside the TimerTask. Then, after a given time in minutes that will be get from the parametroService.getParametro(), execute this task again.
I tried to follow this link from the docs:
https://docs.spring.io/spring/docs/current/spring-framework-reference/integration.html#scheduling-annotation-support
But seems that I can't dinamically sets the Delay time that a specific task will be executed
You can annotate your run() method with #EventListener or create a new such annotated method which will call run():
#EventListener
public void handleContextRefresh(ContextRefreshedEvent event) {
run();
}
If you don't use context which supports refresh() operation, you should be fine.
If you use such context (and you don't want run() to execute on context refresh) make sure you store this state within your bean.
More info on standard Spring events.
You are correct that annotation #Scheduled does not allow you to read delay parameter dynamically. For that reason and because this annotation takes delay parameter only in milliseconds or as crone expression which is not user friendly, I wrote my own utility that does it. The Utility is available as part of Open Source MgntUtils library. You will need to write your classes that will extend classes provided in the library and then you will get the desired functionality. But it does require a little bit of work. However the library comes with example package that has source code of working example with detailed explanation in javadoc. If you are interested library is available at Github and at Maven Central. In both places it is available with sources and javadoc. The desired feature is described in detail in javadoc. If you download and unzip javadoc into folder c:\tmp then look at URL file:///C:/tmp/javadoc/com/mgnt/lifecycle/management/backgroundrunner/package-summary.html for detailed description on how to use this feature. For working code example look in the sources at package com.mgnt.lifecycle.management.backgroundrunner.example
Also, there is an article that explains about the features of the library, except that this particular feature is not described in that article yet. Here is the link: Open Source Java library with stack trace filtering, Silent String parsing, Unicode converter and Version comparison
You can implement a spring SmartLifecycle interface. This will get invoked when Spring context is loaded completely. And Then you can start the timertask.
public class TimerTaskInvoker implements SmartLifecycle{
#override
public void start(){
timer.scheduleAtFixedRate(timerTask);
}
}
You can check the reference - https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/SmartLifecycle.html
#PostConstruct may be the annotation you need.
https://www.baeldung.com/running-setup-logic-on-startup-in-spring
You can use spring scheduler and specify the initialDelay and fixedRate using the #Scheduled annotation.
#EnableScheduling
class CustomScheduler{
#Scheduled(fixedRate = 1000, initialDelay = 1000)
public void taskYouWantToPerform() {
List<IntRaptMec> allPointments = getNotValidated();
for(IntRaptMec pointment : allPointments) {
controller.validate(pointment.getIdTemp());
}
}
}
For more details refer this
Related
i'm looking for a solution that allow me to handle the setup and the cleanup of my test environment at the launch and the end of my test framework execution.
The setup is not a problem but the cleanup imply to know when the test framework has finished to work or the index of the current test in execution queue.
Has someone a solution to implement this?
You can use org.spockframework.runtime.extension.IGlobalExtension to achieve this, as Spock extensions have callbacks for both BEFORE all specs start, and AFTER all specs end.
public interface IGlobalExtension {
void start();
void visitSpec(SpecInfo spec);
void stop();
}
So, implement stop() in your case to do whatever you need to do.
Spock finds extensions via Java's ServiceLoader, so make sure to add a META-INF/services file (pre-Java9) or declare it in your module-info.java file (post Java9), as explained here: http://spockframework.org/spock/docs/1.1/extensions.html#_writing_custom_extensions
One solution is to create an abstract class that all your specs extend:
class AbstractSpec extends Specification
then inside AbstractSpec find out the classes that are going to be run(for example if you're using spring framework):
private static final synchronized TEST_CLASSES = new ClassPathScanningCandidateComponentProvider(false).with {
addIncludeFilter(new AssignableTypeFilter(AbstractSpec.class))
findCandidateComponents("com/example/test").findAll { it.beanClassName != AbstractSpec.class.canonicalName }
.collect { Class.forName(it.beanClassName) }
}
then inside AbstractSpec do the actual clean up after all classes are run:
def synchronized cleanupSpec() {
TEST_CLASSES.remove(getClass())
if (TEST_CLASSES.isEmpty()) {
// clean up here
}
}
The problem with this solution is that if you run a subset of tests or classes in your IDE; you might have all the test classes in the classpath so TEST_CLASSES won't be emptied so the clean up won't execute.
I use Spring's scheduler (#EnableScheduling) and have the following #Scheduled method, which is called every minute:
#Component
public class ScheduledTask {
#Scheduled(fixedRate = 60*1000)
public void run() {
// ...
Now I would like to be able to trigger a scheduler run, on demand, from another place in the code.
I can inject ScheduledTask and just call the run method. However I want to make sure that there is only one thread running the run method at any given time. In other words, if the scheduler is currently running run I want the call to be ignored.
Also I want to call run asynchronously, but this can be easily addressed by using #EnableAsync and #Async.
Is there any Spring feature that can be used in this scenario?
Edited as of comment:
Just use an AtomicBoolean.
#Component
public class ScheduledTask {
private AtomicBoolean isRunning = new AtomicBoolean(false);
#Scheduled(fixedRate = 60*1000)
public void run() {
if (isRunning.compareAndSet(false, true)) {
// ... do your things
//whenever you are done
isRunning.set(false);
}
I don't think there's something simpler in Spring. It makes no sense as it is really a flag thing.
Edit:
If you want to use it in several places of the application, consider implementing your own annotation with the semaphore or atomic boolean embedded.
We have a Play-Project that uses PlayFramework 2.5.4 and MongoDB. We want to update our database daily. At the moment we check the time everytime we get a Request and update if a day is over.
That leads to some Problems:
The current player has to wait a quiet long time until the request finishes
it can happen that there is one day no update (but we want everyday one, even if nothing changes)
we have to modify every request we insert.
So i found already the documentation of AKKA and old stackoverflowquestions (like How to schedule task daily + onStart() in Play 2.0.4?). But the solutions donĀ“t work anymore.
Akka.system().scheduler()
is deprecated
system.scheduler()
gives compilingerrors (from docu) and i dont know if an import is missing or what else.
As i know you should use #inject since Version 2.4, but i cant find proper examples on how to use it with schedule or how to use it afterall
Actually all i want to do is call PlayerDBHandler.newDay() every day on the same time.
Thanks for Help
Without seeing the compilation errors, I'm guessing that system isn't defined. Expanding the example from the documentation, something like this should work.
public class SchedulingTask {
#Inject
public SchedulingTask(final ActorSystem system,
#Named("update-db-actor") ActorRef updateDbActor) {
system.scheduler().schedule(
Duration.create(0, TimeUnit.MILLISECONDS), //Initial delay
Duration.create(1, TimeUnit.DAYS), //Frequency
updateDbActor,
"update",
system.dispatcher(),
null);
}
}
system is injected, and you can also inject a reference to the actor. Alternatively, you can look up the actor ref from system.
Once you've adapted this to do what you want, declare SchedulingTask in a module.
package com.example;
import com.google.inject.AbstractModule;
import play.libs.akka.AkkaGuiceSupport;
public class MyModule extends AbstractModule implements AkkaGuiceSupport {
#Override
protected void configure() {
bindActor(UpdateDbActor.class, "update-db-actor");
bind(SchedulingTask.class).asEagerSingleton();
}
}
Finally, update your application conf to enable the module.
play.modules.enabled += "com.example.MyModule"
I'm writing a gerrit plugin and want to close network connections on plugin restart/shutdown. This can be done using a LifecycleListener.
As far as I know, there are two modes of operation for a gerrit plugin concerning Guice. One is to not declare anything in the Manifest and use auto-registration for everything, using annotations like #Listen and #Export. The other is to create a Guice module and do all wiring manually in that module.
I'd like to use auto-registration, but I can't make it work with a LifecycleListener. Adding a #Listen annotation has no effect, the Listener is getting ignored.
My code looks like this (minimized):
#Listen
#Singleton
public class CommitValidationTest implements CommitValidationListener {
#Listen
public static class Lifecycle implements LifecycleListener {
#Override
public void start() {
// write to log
}
#Override
public void stop() {
// write to log
}
}
}
I gathered that LifecycleListeners can't be used in combination with AutoRegistration.
Here's why: In order for the #Listen annotation to work, the #ExtensionPoint interface which is implemented by the class (in this case LifecycleListener) must have a DynamicItem, DynamicSet or DynamicMap definition in a Guice module, which isn't the case for LifecycleListener.
I want to execute a call to a particular method every minute, and it should get called with the server startup. This should be a single thread.
I tried using the CRON job , but am facing some issues with it.
Is there any way through which I can achieve it
Use ExecutorServices...
Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate( new Runnable()
{
#Override
public void run()
{
// call your method here
}
}, 0, 1, TimeUnit.MINUTES );
For a similar task i am using a Quartz scheduler. It is very easy to use. My intervals are larger than a minute though, but this should not matter.
You have the option to specify how many threads your scheduler will be using in a config file.
http://quartz-scheduler.org/
http://quartz-scheduler.org/api/2.0.0/
If you are using JBoss (may also apply to other AS, I have no data on them), you may want to try the bundled quartz scheduler. It offers very finegrained job control. You don't have to use the bundled version though, and are free to use it as dependency on the AS of your choice.
You can use Spring Tasks to achieve this easily using annotations. They are in the context jars so you shouldn't have to add any new jars to achieve this.
In your appContext add (adjust the pool-size accordingly):
<task:annotation-driven executor="myExecutor" scheduler="myScheduler"/>
<task:executor id="myExecutor" pool-size="2"/>
<task:scheduler id="myScheduler" pool-size="2"/>
You'll need to pull in the appropriate namespace too:
xmlns:task="http://www.springframework.org/schema/task"
After you do all of this you should be able to just annotate the method you want to be called. Since you want your method called every minute you should use fixedRate:
#Scheduled(fixedRate=60000)
Doing this should force the call to run on startup and every minute thereafter. The time as you can probably see is set in milliseconds.
Execute a particular method every minute? This sounds like you need a Timer. Have a look at this article for more information. Timer executes the method at a background thread - why is it important to execute the method within your main thread?
class DemoThread extends Thread {
public void run() {
while(true) {
try {
sleep(60000);
}
catch(InterruptedException e) {
}
// call some random method here
}
}
}
Init the Thread and run it.
DemoThread thread = new DemoThread();
thread.start();