ScheduledExecutorService is expected to execute Producer every second with initial delay of 2 seconds.
service
public ScheduledExecutorService writeTimestampPeriodically() {
executorService = Executors.newScheduledThreadPool(3);
scheduleAtFixedRate(Producer.class);
return executorService;
}
Producer
#Slf4j
public class Producer extends AbstractActor {
public Producer(String name) {
super(name);
}
#Override
public void run() {
Thread.currentThread().setName(name);
Timestamp timestamp = Timestamp.from(Instant.now());
log.info("Produced {}", timestamp);
queue.put(timestamp);
}
}
AbstractActor
#RequiredArgsConstructor
public abstract class AbstractActor implements Actor, Runnable {
protected final String name;
#Autowired
protected Queue queue;
#Autowired
protected TimestampService timestampService;
}
Actor
public interface Actor extends Runnable {
#Override
void run();
}
application.yml
app:
actor:
producer:
initial-delay: 2s
period: 1s
UPDATE:
It seems like Spring not autowired correctly queue since it is null.
Moving
#Autowired
protected Queue queue;
to Producer didn't help.
Queue
#Slf4j
#Component
public class Queue {//...}
UPDATE 2
I think the problem is in the implementation of factory that creates Producer with new
#Component
public class ActorFactory {
public Actor create(String name) {
if (name.indexOf("consumer") == 0)
return new Consumer(name);
else if (name.indexOf("producer") == 0)
return new Producer(name);
else if (name.indexOf("monitor") == 0)
return new Monitor(name);
else
throw new UnsupportedOperationException("Actor Factory cannot create " + name);
}
}
Seems like Spring's Factory Beans and AbstractFactoryBean cannot help in my case so I solved it like this:
ActorFactoryConfig
#Configuration
public class ActorFactoryConfig {
#Bean
public ActorFactory<String, Actor> actor() {
return this::create;
}
#Bean
#Scope(value = "prototype")
#SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
Actor create(String name) {
if (name.indexOf("consumer") == 0)
return new Consumer(name);
else if (name.indexOf("producer") == 0)
return new Producer(name);
else if (name.indexOf("monitor") == 0)
return new Monitor(name);
else
throw new UnsupportedOperationException("Actor Factory cannot create " + name);
}
}
ActorFactory
#FunctionalInterface
public interface ActorFactory<String, Actor> {
Runnable apply(String name);
}
Actor
public interface Actor extends Runnable {
}
ActorService
#Autowired
ActorFactoryConfig actorFactoryConfig;
#Autowired
private ActorFactory actorFactory;
private void scheduleAtFixedRate(Class<? extends Actor> actorType) {
executorService.scheduleAtFixedRate(
actorFactoryF.apply(actorType.getSimpleName().toLowerCase() + "-1"),
getProperty(actorType, SETTING_TYPE.DELAY),
getProperty(actorType, SETTING_TYPE.PERIOD),
TimeUnit.SECONDS);
}
Related
I have a Factory class:
#Service
class AffectedObjectServiceFactory {
private static final Map<String, AffectedObjectService> affectedObjectServiceMap = new HashMap<>();
#Autowired
private AffectedObjectServiceFactory(List<AffectedObjectService> services) {
for(AffectedObjectService service : services) {
String[] supportedSubTypes = service.func1();
for (String subType: supportedSubTypes) {
affectedObjectServiceMap.put(subType, service);
}
}
}
public static AffectedObjectService getAffectedObject(String type) {
AffectedObjectService affectedObjectService = affectedObjectServiceMap.get(type);
if(affectedObjectService == null) throw new IllegalArgumentException("Unknown service type: " + type);
return affectedObjectService;
}
}
here are the interfaces and its implementations
interface AffectedObjectService {
String func1();
}
#Component
class AffectedObjectServiceImpl1 implements AffectedObjectService {
#Override
String func1() { //.... }
}
#Component
class AffectedObjectServiceImpl2 implements AffectedObjectService {
#Override
String func1() { //.... }
}
#Component
class AffectedObjectServiceImpl3 implements AffectedObjectService {
XYZInterface type;
#Autowired
AffectedObjectServiceImpl3(XYZInterface type) {
this.type = type;
}
#Override
String func1() { //.... }
}
Interface XYZInterface {
String func2();
}
#Component
class XYZInterfaceImpl1 extends XYZInterface {
#Override
String func2() { // .... }
}
#Component
class XYZInterfaceImpl2 extends XYZInterface {
#Override
String func2() { // .... }
}
The AffectedObjectService is an interface which is implemented by multiple classes. Some classes have further a constructor which takes another interface implementation as parameters.
How can I pass every possible AffectedObjectServiceImpl3 (one with XYZInterfaceImpl1 as parameter, and one with XYZInterfaceImpl2 as parameter) as dependency to the constructor of the Factory class?
I have this async method in Spring Boot:
#Async
public void calculateResult(List matrix) {
//do calculation
}
This method is invoked at the controller.
I want to reduce the priority of this calculation method threads. How do I do that?
With async anotation u can not acheive this. #Async take only custom task executor.. No way to set priority. But u can do it manualy like this:
Create this bean:
#Bean("CustomTaskExecutor")
public TaskExecutor threadPoolTaskExecutor(
#Value("${spring.async.core-pool-size}") int corePoolSize,
#Value("${spring.async.max-pool-size}") int maxPoolSize,
#Value("${spring.async.queue-capacity}") int queueCapacity) {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor() {
#Override
protected BlockingQueue<Runnable> createQueue(int queueCapacity) {
return new PriorityBlockingQueue<Runnable>(queueCapacity);
}
};
executor.setCorePoolSize(corePoolSize);
executor.setMaxPoolSize(maxPoolSize);
executor.setQueueCapacity(queueCapacity);
return executor;
}
Task with priorities:
public class Task implements Runnable {
private Consumer<Job> jobConsumer;
private Job job;
public Job getJob() {
return this.job;
}
public Task(Consumer<Job> jobConsumer, Job job) {
this.jobConsumer = jobConsumer;
this.job = job;
}
#Override
public void run() {
this.jobConsumer.accept(job);
}
}
Future custom task:
public class FutureCustomTask extends FutureTask<FutureCustomTask> implements Comparable<FutureCustomTask> {
private Task task;
public FutureCustomTask(Task task) {
super(task, null);
this.task = task;
}
#Override
public int compareTo(FutureCustomTask o) {
return task.getJob().getPriority().compareTo(o.task.getJob().getPriority());
}
}
Finaly set priority like this:
#Autowired
private TaskExecutor taskExecutor;
#Autowired
private JobBusiness jobBusiness;
...
Task task = new Task(jobBusiness::performSomethingOn, job);
taskExecutor.execute(new FutureCustomTask(task));
I took this answer from here
Look at this tutorial also....
I'm using Akka actor in our product. We wrote some code:
#Singleton
public class SingletonObj {
private Map<String, Integer> cached = new HashMap();
public void set(String key, Integer value) {
cached.put(key, value);
}
public void delete(String key){
cached.delete(key}
}
}
public class MyActor extends AbstractActor implements InjectedActorSupport {
#Inject SingletonObj singletonObj;
public static Props props(Injector injector) {
return Props.create(MyActor.class, injector);
}
public MyActor(Injector injector) {
this.injector = injector;
receive(ReceiveBuilder.create()
.match(AddEvent.class, this::addEvent)
.match(DeteteEvent.class, this::deleteEvent))
.build());
}
private void addEvent(AddEvent addEvent) {singletonObj.set(addEvent.key, addEvent.value);}
private void deteleEvent(DeteteEvent event){singletonObj.detele(event.key);}
}
public class Controller {
private Injector injector;
private ActorSystem actorSystem;
public void handleAdd()...
public void handleDelete()...
}
Then when I wrote some test in junit for these class
#Test public void testMethod(){
sendAddRequest(...);
sendDeteleRequest(...)
...
...
assertThat(singletonObj.get("someString")).isEqual(42)
}
Then this test is unreliable because when I do assertion, then all events was not handled yet.
How can I wait utils all events in actor system finish?
Import the below package and then you can await till you process all the events or the test will fail after timeout.
testCompile 'org.awaitility:awaitility:3.1.0'
import org.awaitility.Awaitility;
And before your assertThat use
await().pollInterval(5, TimeUnit.MILLISECONDS).until(() -> !isProcessed());
The isProcessed method will look something like below
protected Callable<Boolean> isProcessed() {
return () -> {
return singletonObj.getCacheCount()==2;
};
}
Regards,
Vinoth
Suppose I have two real implementations A and B of some interface. And there is also a Delegate-implemenation of that interface that delegates to either A or B dependending on some logic.
I want to have the Delegate injected into my client class so I marked A and B as #Alternatives to make that unambiguous. However, now the injection into the Delegate does not work since A and B are alternatives.
Any suggestions on how to solve this?
import org.jglue.cdiunit.AdditionalClasses;
import org.jglue.cdiunit.CdiRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
import javax.enterprise.inject.Alternative;
import javax.inject.Inject;
#RunWith(CdiRunner.class)
#AdditionalClasses({ CdiTest.A.class, CdiTest.B.class, CdiTest.Delegate.class })
public class CdiTest {
public interface Service {
void run();
}
#Alternative
public static class A implements CdiTest.Service {
#Override
public void run() {
System.out.println("Hi from A");
}
}
#Alternative
public static class B implements CdiTest.Service {
#Override
public void run() {
System.out.println("Hi from B");
}
}
public static class Delegate implements CdiTest.Service {
int counter = 0;
#Inject A a;
#Inject B b;
#Override
public void run() {
System.out.println("Hi from Delegate");
if ((counter++) % 2 == 0) a.run();
else b.run();
}
}
#Inject
private Service service;
#Test
public void test() {
service.run();
}
}
I think tha you need qualifiers instead of alternatives.
Have you tried using two qualifiers ServiceA and ServiceB? You could inject in the delegate both implementations and in real test the delegate.
EDIT
I don't think you should replace the delegate with a producer (from your example I understood that the delegate has some functional role in your application and is not only a
test/production switch).
I think that you could create another class with a producer method like this:
public class ServiceProducer {
private static final String SERVICE_A = "service-a";
private static final String SERVICE_B = "service-a";
private static final String SERVICE_DELEGATE = "service-delegate";
#Produces
#Chosen
public CdiTest.Service getService(#SystemProperty("service.choose.key") String chosenKey,
#ServiceA Instance<Service> a,
#ServiceB Instance<Service> b,
#ServiceDelegate Instance<Service> delegate) {
switch(chosenKey) {
case SERVICE_A:
return a.get();
case SERVICE_B:
return b.get();
case SERVICE_DELEGATE:
return delegate.get();
default:
throw new IllegalStateException("No Service implementation for type " + chosenKey);
}
}
}
The #SystemProperty is a useful solution to inject system properties found at http://juraj.blahunka.eu/2014/05/17/inject-jboss-system-properties/
So you example code could be changed in:
public class CdiTest {
public interface Service {
void run();
}
#ServiceA
public static class A implements CdiTest.Service {
#Override
public void run() {
System.out.println("Hi from A");
}
}
#ServiceB
public static class B implements CdiTest.Service {
#Override
public void run() {
System.out.println("Hi from B");
}
}
#ServiceDelegate
public static class Delegate implements CdiTest.Service {
int counter = 0;
#Inject #ServiceA Service a;
#Inject #ServiceB Service b;
#Override
public void run() {
System.out.println("Hi from Delegate");
if ((counter++) % 2 == 0) a.run();
else b.run();
}
}
#Inject
#Chosen
private Service service;
#Test
public void test() {
service.run();
}
}
This way you inject implementations A and B inside the delegate (without using the producer) and the produced one in your test class (choosing the correct implementation with a system property named "service.choose.key").
I'm getting null pointer exception on the field injection of a server which is started as an akka actor.
Schedular part:
private ActorRef myActor = Akka.system().actorOf(
new Props(Retreiver.class));
#Override
public void onStart(Application app) {
log.info("Starting schedular.....!");
Akka.system()
.scheduler()
.schedule(Duration.create(0, TimeUnit.MILLISECONDS),
Duration.create(30, TimeUnit.MINUTES), myActor, "tick",
Akka.system().dispatcher());
}
Retreiver class part:
public class Retreiver extends UntypedActor {
private Logger.ALogger log = Logger.of(Retreiver .class);
#Inject
private myDataService dataService;
#Override
public void onReceive(Object arg0) throws Exception {
if (0 != dataService.getDataCount()) {
....
....
....
}
}
I'm getting null for dataService. Please advice me on this.
Thanks.
For anyone who needs this:
public class GuiceInjectedActor implements IndirectActorProducer {
final Injector injector;
final Class<? extends Actor> actorClass;
public GuiceInjectedActor(Injector injector, Class<? extends Actor> actorClass) {
this.injector = injector;
this.actorClass = actorClass;
}
#Override
public Class<? extends Actor> actorClass() {
return actorClass;
}
#Override
public Actor produce() {
return injector.getInstance(actorClass);
}
}
AND
Akka.system().actorOf(Props.create(GuiceInjectedActor.class, INJECTOR,Retreiver.class))
Thats it...!!!
You're getting the NullPointerException because Akka is instantiating your Retriever actor and not Guice. You need to get Guice to construct your instance and then pass that to Akka, IndirectActorProducer can help you achieve this, e.g.:
class RetrieverDependencyInjector implements IndirectActorProducer {
final Injector injector;
public RetrieverDependencyInjector(Injector injector) {
this.injector = injector;
}
#Override
public Class<? extends Actor> actorClass() {
return Retriever.class;
}
#Override
public Retriever produce() {
return injector.getInstance(Retriever.class);
}
}
Note that produce() must create a new Actor instance each time it is invoked, it cannot return the same instance.
You can then get Akka to retrieve your actor through the RetrieverDependencyInjector, e.g.:
ActorRef myActor = Akka.system().actorOf(
Props.create(RetrieverDependencyInjector.class, injector)
);
UPDATE
I thought about you comment further, you might be able to turn RetrieverDependencyInjector into a GenericDependencyInjector by providing the class of the Actor you want as a constructor parameter, that perhaps will allow you to do something like:
Props.create(GenericDependencyInjector.class, injector, Retriever.class)
I haven't tried this, but it might give you a starting point.
There can be other ways, eg, you can put a static injector handle in Boot or Some-Injector-Holder-class, and inject when you create the actor by call the inherited method: preStart ()
public class Retreiver extends UntypedActor {
private Logger.ALogger log = Logger.of(Retreiver .class);
#Override
public void preStart () {
super.preStart ();
Boot.injector.injectMembers (this);
//Some-Injector-holder.injectMembers (this);
}
#Inject
private myDataService dataService;
#Override
public void onReceive(Object arg0) throws Exception {
if (0 != dataService.getDataCount()) {
....
....
....
}
}
and also, you can also inject the injector in actor provider to initialize the actor by the injector in a scope of UntypedActorFactory:
public class InjectingActorProvider implements Provider<ActorRef> {
#Inject
private Injector injector;
#SuppressWarnings("serial")
#Override
public final ActorRef get() {
Props props = new Props(new UntypedActorFactory() {
#Override
public Actor create() {
return injector.getInstance(actorClass);
}
});
props = props.withRouter(...);
props = props.withDispatcher(...);
actor = system.actorOf(props, actorName);
return actor;
}
}