I'm trying to execute some task periodically using guava AbstractScheduledService :
public class MyService extends AbstractScheduledService {
public MyService() {
}
#Override
protected void runOneIteration() {
doStuff();
}
private void doStuff() {
// Do stuff
}
#Override
protected Scheduler scheduler() {
return Scheduler.newFixedRateSchedule(0, 8, TimeUnit.HOURS);
}
}
So this service should execute some task periodically every 8 hours but it never actually does. The inherited isRunning() method returns false and the runOneIteration() method never gets invoked.
I have managed to make it work by calling the startAsync() method (inherited from parent class) from my service constructor but I don't see any reference saying this is the way it should work.
Have I missed something here? Is this the way the AbstractScheduledService works?
AbstractScheduledServiced implements Service. The Service interface describes lifecycle methods including startAsync. The ServiceState enum literals contain documentation on what they mean. A Service in NEW state (just created):
A service in this state is inactive. It does minimal work and consumes minimal resources.
For the Service to do something useful you have to transition it to the state RUNNING
A service in this state is operational.
That's why you have to start the Service before it does anything.
I would also advise against calling startAsync from the constructor and instead calling it from the Code that creates your MyService instance. It is rarely an expected thing to have such heavy side effects (creation of Threads) in the constructor.
Related
Example:
class Example {
#Inject
Bee b; // proxy
public void exec() {
b.exec();
}
class Bee {
public void exec() {
exec2();
}
#Transactional
public void exec2() {}
}
As I recently noticed, this will not work. Am I right? Do you have some links to documentation that states that behavior? IMO this case could be handled in the future because intuitively it seems that it should work.
The relevant section of the CDI specification is section 7.2 (Container invocations and interception). Since exec2() is not invoked via a contextual reference, its invocation does not constitute a business method invocation. Since it is not a business method invocation, interceptors responsible for implementing the behavior prescribed by #Transactional are not invoked.
I need to run a function on a complete independent thread wile the rest of my function gets executed for example
public void a(){
// do dome work
}
public void b(){
// do dome work
a()
return "hello"
}
I need my code to start ruining function a but returns hello without waiting for function a to end
I have tried task executors with spring and #Async annotation but noting is working
public static String mainMEthod() {
asyncMethodWithReturnType();
return "hello";
}
#Async
public static Future<String> asyncMethodWithReturnType() {
for (int i = 0; i < 10; i++) {
System.out.println("Execute method asynchronously - " +
Thread.currentThread().getName());
}
try {
Thread.sleep(5000);
return new AsyncResult<String>("hello world !!!!");
} catch (InterruptedException e) {
//do anything
}
return null;
}
Here is the output :
Execute method asynchronously - main
Execute method asynchronously - main
Execute method asynchronously - main
Execute method asynchronously - main
Execute method asynchronously - main
Execute method asynchronously - main
Execute method asynchronously - main
Execute method asynchronously - main
Execute method asynchronously - main
Execute method asynchronously - main
but it should not be running on the main thread
#Async has two limitations:
it must be applied to public methods only
self-invocation – calling the async method from within the same class – won’t work.
The reasons are simple – the method needs to be public so that it can be proxied. And self-invocation doesn’t work because it bypasses the proxy and calls the underlying method directly.
Also make sure to configure correctly:
#Configuration
#EnableAsync
public class SpringAsyncConfig { ... }
Read more:
https://www.baeldung.com/spring-async
The way Spring add functionalities like Async (apart from many others like this) is by creating and injecting a proxy which has the logic of providing these functionality.
In your case the call to asyncMethodWithReturnType cannot be intercepted by Spring as this is plain java method call without intermediate spring managed proxy. For more information you can check out here.
The #Async can't be run in a separate thread if the caller is within the same bean.
So option one is to move the a() method to a different bean and call it from b()
Or, consider doing what we did in our spring boot project when we needed something similar:
public void b() {
CompletableFuture.runAsync(() -> a());
return "hello";
}
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.
I have a class, which has an Initialize method, which creates a bunch of tables in a database. This class looks like this:
public class MyClass
{
private bool initialized = false;
public void Initialize()
{
if(!initialized)
{
//Install Database tables
initialized = true;
}
}
public void DoSomething()
{
//Some code which depends on the database tables being created
}
public void DoSomethingElse()
{
//Some other code which depends on the database tables being created
}
}
The two methods DoSomething and DoSomethingElse need to make sure that the Initialize method has been called before proceeding because they depend on having the tables in the database. I have two choices:
Call the Initialize method in the constructor of the class - this does not seem like a good idea because constructors should now call methods, which are non-trivial and could cause an exception.
Call the Initialize method in each of the two methods - this does not seem like a great solution either especially if there are more than a handful of methods.
Is there a design pattern which could solve this in a more elegant way?
I would use a static factory method in which Initialize is invoked, and make the constructor private, to force use of the static factory method:
public class MyClass
{
private MyClass() { ... }
public static MyClass createInstance() {
MyClass instance = new MyClass();
instance.Initialize();
return instance;
}
}
Also, I would remove the initialized variable - in part because you don't need it any more - but also because it requires some means of guaranteeing visibility (e.g. synchronization, volatile or AtomicBoolean) for thread safety.
I think that Miško Hevery's blog post on (not) doing work in constructors is an interesting read.
I would separate the installation of the database from the definition of tasks that depends on it:
static factory could be used for the database installation as pointed out by #andy-turner
and the repository pattern to do work on the database
I suggest this solution because if i understand correctly, you are concerned about the high number of tasks that depends on the database.
Using the dependency injection pattern the repository can get a reference to the database, so in your bootstrapping code you can execute the database installation once and then inject the reference to the database in all the repositories that depends on it.
I would recommend using a collaborator that does the initialisation. That way MyClass can easily be tested by substituting a mock for the initialiser collaborator. For example:
public class MyClass {
public MyClass(MyClassInitialiser initialiser) {
initialiser.initialize();
}
public void DoSomething() {
//Some code which depends on the database tables being created
}
public void DoSomethingElse() {
//Some other code which depends on the database tables being created
}
}
Or an alternative solution, the idea here is that you're breaking the single responsibility principle in MyClass. There is non-trivial initialisation behaviour (installing database tables) and behaviour on those tables in the same class. So you should separate those responsibilities into two different classes and pass one in as a collaborator to the other.
public class MyClass {
DatabaseCollaborator collaborator;
public MyClass(DatabaseCollaborator collaborator) {
this.collaborator = collaborator;
}
public void DoSomething() {
//Some code which depends on the database tables being created
collaborator.someMethod();
}
public void DoSomethingElse() {
//Some other code which depends on the database tables being created
collaborator.anotherMethod();
}
}
public class DatabaseCollaborator {
DatabaseConfig config;
public DatabaseCollaborator(DatabaseConfig config) {
this.config = config;
}
public void someMethod() {
}
public void anotherMethod() {
}
}
public class DatabaseConfig {
public DatabaseConfig() {
// initialize
}
}
When I want a class whose instances must be initialized exactly once but I want to defer initialization until right before it's necessary (at which point the caller may fail to call an Initialize function, find it inconvenient to do so, or etc.), I do it similar to how you've started out with your code, but I make the initialization method private and name it something like "EnsureInitialized". It uses a flag to track and early exit if initialization has already been done, and all functions which depend on initialization already having happened just call that function as their first line (after argument-checking).
If I expect the caller to control when this instance's initialization is done, I make the method public, name it "Init", track whether it has been run with a flag, handle idempotence or max-run-once inside the Init method however is appropriate for that class, and all methods which depend on Init having already been run will call a different, private method named "AssertIsInitialized" which will throw an exception with text like "Must call init on {class name} instance before using this function".
My goal with these different patterns is to be unambiguous about each method's expectations and operation regarding initialization within the class instance lifecycle, and provide discoverability (of the design or code bugs using it) and automatic behavior (in the case of the self-initializing class in my first paragraph) wherever I think each is most appropriate to what the rest of the application is doing.
I was wondering if it was possible to only allow a certain set of classes to execute a function.
I have a method: setPermission()
This method should only be called by certain classes throughout the project.
Some people suggested having the calling class pass in this, referencing the current object and ensuring it is an instanceof an allowed class. But any class could pass in an instance of an allowed class an so this seems to be an poor solution.
I also stumbled across Exception().getStackTrace()[1].getClassName(); however I am led to believe this is quite an expensive operation.
Is there a correct way to do this?
Use a marker interface (one that doesn't have any methods):
public interface Permissible {}
Then have the classes that are allowed to call your method implement it, then change the parameter type of your method to this interface:
public static void myMethodForObjectsThatHavePermission(Permissible obj) {
//
}
There's no way to enforce it that can't be worked around, but you could have most of your functionality on one class, setPermission() on a subclass, and make clients get an instance of your class via a factory method that is declared to return the parent class, but actually returns an instance of the subclass. That way, code that is supposed to call setPermission(), and knows about it, can do a downcast and call it, and all other users of the class won't even see it.
public class Service {
protected boolean permission = false;
protected Service() {
/* control creation */
}
public static Service getService() {
return new RealService();
}
public void doStuff() {
/* the public API side of the service */
}
}
public class RealService extends Service {
protected RealService() {
/* control creation */
}
public void setPermission(boolean permission) {
this.permission = permission;
}
}
A legitimate caller can do this:
public class Legitimate {
public void method() {
Service service = Service.getService();
RealService real = (RealService) service;
real.setPermission(true);
}
}
However, if all the legitimate callers can be put into the same package, and all the rest are outside the package, then package-private access (no access modifier) for setPermission() would be sufficient.
This doesn't prevent malicious callers from getting around the restriction, but it does avoid people calling setPermission without realizing they're not supposed to, because setPermission wouldn't show up in autocompletion (intellisense) in an IDE.
Sounds to me like you're looking for OSGi (en.wikipedia.org/wiki/OSGi). Third party developers should write bundles and with OSGi you can restrict capabilities of their bundles. Put your attention to: "Security The layer that handles the security aspects by limiting bundle functionality to pre-defined capabilities." Here is a thread discussing your case: Managing access to OSGI bundles