Guava EventBus Multiple subscribers same tpe - guava

import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
public class Test {
public static class Processing { }
public static class ProcessingResults { }
public static class ProcessingFinished { }
public static EventBus bus = new EventBus();
#Subscribe
public void receiveStartRequest(Processing evt) {
System.out.println("Got processing request - starting processing");
}
#Subscribe
public void processingStarted(Processing evt) {
System.out.println("Processing has started");
}
#Subscribe
public void resultsReceived(ProcessingResults evt) {
System.out.println("got results");
}
#Subscribe
public void processingComplete(ProcessingFinished evt) {
System.out.println("Processing has completed");
}
public static void main(String[] args) {
Test t = new Test();
bus.register(t);
bus.post(new Processing());
}
}
So, in above example, it can be seen that there are 2 subscribers accepting same type Processing. Now, at the time of post(), which all functions will get called? If the 2 functions receiveStartRequest and processingStarted will get called, then in which order they will be get called?

Both your methods will be called and in no predefinite order.
To counter this, just create two extra classes: ProcessingStarted and ProcessingRequested.
public class ProcessingStarted {
private Processing processing;
// Constructors
// Getters/Setters
}
public class ProcessingStarted {
private Processing processing;
// Constructors
// Getters/Setters
}
Then call post(new ProcessingRequested(processing)) and post(new ProcessingStarted(processing)) when needed, instead of a single post(processing).

Related

Dynamic Merge of Infinite Reactor streams

Usecase:
There is a module which Listens for events in synchronous mode. In the same module using the EmitterProccessor, the event is converted to Flux and made as infinite stream of events. Now there is a upstream module which can subscribes for these event streams. The problem here is how can I dynamically merge these streams to one and then subscribe in a single stream. A simple example is, let us say there are N number of sensors, we can dynamically register these sensors and start listening for measurements as stream of data in single stream after merging them into one stream. Here is the code sample written to mock this behavior.
Create callback and start listening for events
public interface CallBack {
void callBack(int name);
void done();
}
#Slf4j
#RequiredArgsConstructor
public class CallBackService {
private CallBack callBack;
private final Function<Integer, Integer> func;
public void register(CallBack intf) {
this.callBack = intf;
}
public void startServer() {
log.info("Callback started..");
IntStream.range(0, 10).forEach(i -> {
callBack.callBack(func.apply(i));
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
log.info("Callback finished..");
callBack.done();
}
}
Convert the events to streams using event proccessor
#Slf4j
public class EmitterService implements CallBack {
private EmitterProcessor<Integer> emitterProcessor;
public EmitterService(){
emitterProcessor = EmitterProcessor.create();
}
public EmitterProcessor<Integer> getEmmitor() {
return emitterProcessor;
}
#Override
public void callBack(int name) {
log.info("callbakc {} invoked", name);
//fluxSink.next(name);
emitterProcessor.onNext(name);
}
public void done() {
//fluxSink.complete();
emitterProcessor.onComplete();
}
}
public class WrapperService {
EmitterService service1;
ExecutorService service2;
public Flux<Integer> startService(Function<Integer, Integer> func) {
CallBackService service = new CallBackService(func);
service1 = new EmitterService();
service.register(service1);
service2 = Executors.newSingleThreadExecutor();
service2.submit(service::startServer);
return service1.getEmmitor();
}
public void shutDown() {
service1.getEmmitor().onComplete();
service2.shutdown();
}
}
Subscribe for the events
#Slf4j
public class MainService {
public static void main(String[] args) throws InterruptedException {
TopicProcessor<Integer> stealer = TopicProcessor.<Integer>builder().share(true).build();
CountDownLatch latch = new CountDownLatch(20);
WrapperService n1 =new WrapperService();
WrapperService n2 =new WrapperService();
// n1.startService(i->i).mergeWith(n2.startService(i->i*2)).subscribe(stealer);
n1.startService(i->i).subscribe(stealer);
n2.startService(i->i*2).subscribe(stealer);
stealer.subscribeOn(Schedulers.boundedElastic())
.subscribe(x->{
log.info("Stole=>{}", x);
latch.countDown();
log.info("Latch count=>{}", latch.getCount());
});
latch.await();
n1.shutDown();
n2.shutDown();
stealer.shutdown();
}
}
Tried to use TopicProccessor with no success. In the above code subscription happens for first source, for second source there is no subscription. however if use n1.startService(i->i).mergeWith(n2.startService(i->i*2)).subscribe(stealer); subscription works, but there is no dynamic behavior in this case. Need to change subscriber every time.

Interface in java

interface A {
public void eg1();
}
interface B {
public void eg1();
}
public class SomeOtherClassName implements A, B {
#Override
public void eg1() {
System.out.println("test.eg1()");
}
}
What is the output and what occurs if method is overriden in interface?
First of all it's of no use to implement both class A and B as both
of them has same method signature i.e both has same method name and
return type.
Secondly you'll need a main method to run the program.
Also in interface you can only declare the methods, the implementation
has to be done in the class which implements it.
interface A {
public void eg1();
}
interface B {
public void eg1();
}
public class Test implements A{
#Override
public void eg1() {
System.out.println("test.eg1()");
}
public static void main (String args[]) {
A a = new test();
a.eg1();
}
}
Output : test.eg1()

Where to setup my actors in a play app?

I want to setup my actors inside of a play app, for example, I have an actor that will poll a message queue or run every x minutes.
I renamed the actor system in my play app, so I now how to get the actor system.
play.akka.actor-system = "myAkka"
I know I can get the actor system using dependency injection inside of a controller but I don't need it at the controller level, I need to do this when my application starts outside of the request/response level.
One of the the way is to crate your actors in an eager singleton.
Create singleton like this:
package com.app;
import akka.actor.ActorRef;
import akka.actor.ActorSystem;
import javax.inject.Inject;
import javax.inject.Singleton;
#Singleton
public class ActorBootstrap {
private ActorRef somaActor;
#Inject
public ActorBootstrap(ActorSystem system) {
// Craete actors here: somaActor = system.actorOf()
}
public ActorRef getSomaActor() {
return somaActor;
}
}
Define the singleton as eager in guice module as follows:
package com.app;
import com.google.inject.AbstractModule;
public class AppModule extends AbstractModule {
#Override
protected void configure() {
bind(ActorBootstrap.class).asEagerSingleton();
}
}
See https://www.playframework.com/documentation/2.5.x/JavaDependencyInjection#Eager-bindings for details.
Register your module with Play (add the following line to application.conf):
play.modules.enabled += "com.app.AppModule"
See https://www.playframework.com/documentation/2.5.x/JavaDependencyInjection#Programmatic-bindings for details.
Here is a basic example of a scheduled actor implementation.
The actor schedules some periodic work:
public class ScheduledActor extends AbstractActor {
// Protocol
private static final String CANCEL = "cancel";
private static final String TICK = "tick";
// The first polling in 30 sec after the start
private static final int TICK_INTERVAL_SEC = 90;
private static final int TICK_INTERVAL_SEC = 90;
private Cancellable scheduler;
public static Props props() {
return Props.create(ScheduledActor.class, ()->new ScheduledActor());
}
public ScheduledActor() {
receive(ReceiveBuilder
.matchEquals(TICK, m -> onTick())
.matchEquals(CANCEL, this::cancelTick)
.matchAny(this::unhandled)
.build());
}
#Override
public void preStart() throws Exception {
getContext().system().scheduler().scheduleOnce(
Duration.create(ON_START_POLL_INTERVAL, TimeUnit.SECONDS),
self(),
TICK,
getContext().dispatcher(),
null);
}
#Override
public void postRestart(Throwable reason) throws Exception {
// No call to preStart
}
private void onTick() {
// do here the periodic stuff
...
getContext().system().scheduler().scheduleOnce(
Duration.create(TICK_INTERVAL_SEC, TimeUnit.SECONDS),
self(),
TICK,
getContext().dispatcher(),
null);
}
public void cancelTick(String string) {
if (scheduler != null) {
scheduler.cancel();
}
}
}
The actor life-cycle handler creates and actor and cancels it upon application stop:
public class ScheduledActorMonitor {
private ActorRef scheduler;
private ActorSystem system;
#Inject
public ScheduledActorMonitor(ActorSystem system, ApplicationLifecycle lifeCycle) {
this.system = system;
initStopHook(lifeCycle);
}
public void startPolling() {
scheduler = system.actorOf(ScheduledActor.props();
}
public void cancelTick() {
if (scheduler != null) {
scheduler.tell(HelloScheduler.CANCEL, null);
}
}
private void initStopHook(ApplicationLifecycle lifeCycle) {
lifeCycle.addStopHook(() -> {
cancelTick();
return CompletableFuture.completedFuture(null);
});
}
}
The StartupHandler is injected as a singleton; it receives in the constructor an actor monitor and starts polling:
#Singleton
public class StartupHandler {
#Inject
public StartupHandler(final ScheduledActorMonitor schedularMonitor) {
schedularMonitor.startPolling();
}
}
The StartupHandler is registered for injection by the default module Play Module:
public class Module extends AbstractModule {
#Override
public void configure() {
bind(StartupHandler.class).asEagerSingleton();
}
}
You can read more here.

Injecting a Factory that accepts a Parameter with AutoFac

I've read over several examples that were more complex then I needed and I'm having trouble distilling this down to a simple, concise pattern.
Let's say I have an interface names ICustomService and multiple implementations of ICustomService. I also have a class Consumer that needs to determine at run time which ICustomService to use based upon a parameter.
So I create a classes as follows:
public class Consumer
{
private CustomServiceFactory customServiceFactory;
public Consumer(CustomServiceFactory _customServiceFactory)
{
customServiceFactory = _customServiceFactory;
}
public void Execute(string parameter)
{
ICustomService Service = customServiceFactory.GetService(parameter);
Service.DoSomething();
}
}
public class CustomServiceFactory
{
private IComponentContext context;
public CustomServiceFactory(IComponentContext _context)
{
context = _context;
}
public ICustomService GetService(string p)
{
return context.Resolve<ICustomService>(p); // not correct
}
}
public class ServiceA : ICustomService
{
public void DoSomething()
{
}
}
public class ServiceB : ICustomService
{
public void DoSomething()
{
}
}
Is there an advantage to having my factory implement an interface? How do I fix my factory and register these classes with Autofac so that Consumer.Execute("A") calls DoSomething on WorkerA and Consumer.Execute("B") calls DoSomething on WorkerB?
Thank you
You would register your implementations of ICustomService with keys. For example:
builder.RegisterType<FooService>.Keyed<ICustomService>("someKey");
builder.RegisterType<BarService>.Keyed<ICustomService>("anotherKey");
and then your factory method would be:
public ICustomService GetService(string p)
{
return context.ResolveKeyed<ICustomService>(p);
}
But, you can take this a step further and decouple CustomServiceFactory from IComponentContext:
public class CustomServiceFactory
{
private Func<string, ICustomService> _create;
public CustomServiceFactory(Func<string, ICustomService> create)
{
_create = create;
}
public ICustomService GetService(string p)
{
return _create(p);
}
}
which you would register like so:
builder.Register(c => {
var ctx = c.Resolve<IComponentContext>();
return new CustomServiceFactory(key => ctx.ResolveKeyed<ICustomService>(key));
});
And at that point, assuming CustomServiceFactory doesn't have any other behavior that was omitted for the question, then you as might as well just use and register Func<string, ICustomService> directly.

CDI - Injecting objects dynamically at runtime

How do I inject objects at runtime? For example, if I want to inject DerviedOne, DerivedTwo objects at runtime into the Test class in the following example, how do I do that? I found a few examples in Spring, but I'm not using Spring. This is a Dynamic Web Project with CDI using Java EE 6.
public abstract class Base
{
public Base(String initiator)
{
this.initiator = initiator;
}
public abstract void process();
public void baseProcess()
{
System.out.println("base process");
process();
}
public String getInitiator()
{
return initiator;
}
private String initiator;
}
public class BaseUtil
{
public long start()
{
return System.currentTimeMillis();
}
public long stop()
{
return System.currentTimeMillis();
}
}
public class DerivedOne extends Base
{
public DerivedOne(String initiator)
{
super(initiator);
}
#Override
public void process()
{
long start = baseUtil.start();
System.out.println(getInitiator() + " process");
long stop = baseUtil.stop();
System.out.println(stop - start);
}
#javax.inject.Inject
private BaseUtil baseUtil;
}
public class DerivedTwo extends Base
{
public DerivedTwo(String initiator)
{
super(initiator);
}
#Override
public void process()
{
long start = baseUtil.start();
System.out.println(getInitiator() + " process");
long stop = baseUtil.stop();
System.out.println(stop - start);
}
#javax.inject.Inject
private BaseUtil baseUtil;
}
#Startup
#Singleton
public class Test
{
#PostConstruct
public void init()
{
String initiator = "two";
Base base = null;
if("one".equals(initiator))
{
base = new DerivedOne("DerivedOne");
}
else if("two".equals(initiator))
{
base = new DerivedTwo("DerivedTwo");
}
base.baseProcess();
}
}
If you want to select one implementation based on runtime conditions You can use a producer method with qualifiers.
For testing CDI application I highly recommend Arquillian.
http://arquillian.org/