Vaadin notification in UI with Akka actor - java

I'm working on integrating an akka actors based backend within a vaadin application.
the problem i'm facing is i dare say simple (bear with me i'm a vaadin first timer :P).
Project structure (simplified)
2 modules front and backend.
my backEnd has an actor system that manages all the backend actors.
-> and a service class that has all relevant methods for necessary computations.
my frontEnd contains a single UI with a bunch of views.
-> and a second actor system that manages one UIActor (since backend actors can't access the UI)
needless to say the back-end is part of the front-end's dependencies.
The problem
In one of my views i have a click event handler that sends a message through the UIActor to one of the backEnd actors which in turn answers back once computations are done.
this is the "onReceive" method in the UIActor
public void onReceive(Object message) throws Exception {
if (message == "test") {
System.out.println("showing notification by "+currentUI);
currentUI.testMethod();
} else if (message instanceof MyUI) {
System.out.println("this is the ui actor test request forwarded");
currentUI = (MyUI) message;
backEndAgent.tell("check",getSelf());
} else {
unhandled(message);
}
}
the currentUI contains the return value of (MyUI) getCurrent(), sent as an message by the handler, in case you're wondering.
as for the testMethod it's pretty basic.
public void testMethod() {
Notification.show("Success", Notification.Type.HUMANIZED_MESSAGE);
}
unfortunately this call generates a null pointer in the Show method resulting from the Page.getCurrent() returning null.
So my question is why do i get a null pointer here?
also in my actor i send the currentUI reference as message because otherwise calling the getCurrent inside the UIActor returns null. any idea why?
EDIT
This is the new test method the page parameter is currentUI.getPage()
public void testMethod(final Page page) {
this.access(new Runnable() {
#Override
public void run() {
new Notification("Success",Notification.Type.HUMANIZED_MESSAGE).show(page);
}
});
}
this solves the problem somehow but only shows the notification after i click the button a second time but not the first time.
This is driving me crazy.

Notification.show() uses Page.getCurrent() to fetch the current page. Page.getCurrent() is a ThreadLocal which is set during a traditional HTTP request-response cycle meaning that Notification.show() works (doesn't return null) during the HTTP request-response thread.
In you case Notification.show() is called outside the HTTP request-response thread and that's why it returns null. If I understand correctly from your code, currentUI is reference to your current UI and it's not null. In that case you could change your code from
public void testMethod() {
Notification.show("Success", Notification.Type.HUMANIZED_MESSAGE);
}
to
public void testMethod() {
new Notification("Success", Notification.Type.HUMANIZED_MESSAGE).show(getPage());
}
The modified version doesn't use Page.getCurrent() anymore but gets the current page from the getPage() method of your UI instance.
EDIT. Forgot to add important information related to actors / external threads accessing Vaadin code:
The actor calling the method to show a notification is an external thread from the Vaadin point of view. Vaadin assumes that access to Vaadin components and Vaadin related other objects is locked/syncronized properly. A proper locking/syncronization is in place when the traditional HTTP request-response thread is used but when an external thread (e.g. actor) is accessing those, the developer must ensure locking. One way to ensure locking is to use UI.access:
getUI().access(new Runnable() {
#Override
public void run() {
// insert your code accessing Vaadin related objects here
}
});
The reason why you see the notification after clicking a button is that browser doesn't know that there is something to show when an actor calls Notification.show. The request caused by a button click pulls changes from the server to the browser and then the notification is show. To see changes from actors / external threads without user interaction (e.g. a button click) the application must use polling or push. To enable polling, setPollInterval for your ui.

Related

Business Logic in Netty?

I'm developing a server based on the Netty libraby and I'm having a problem with how to structure the application with regards to business Logic.
currenty I have the business logic in the last handler and that's where I access the database. The thing I can't wrap my head around is the latency of accessing the database(blocking code). Is it advisable to do it in the handler or is there an alternative? code below:
public void channelRead(ChannelHandlerContext ctx, Object msg)
throws Exception {
super.channelRead(ctx, msg);
Msg message = (Msg)msg;
switch(message.messageType){
case MType.SIGN_UP:
userReg.signUp(message.user);// blocking database access
break;
}
}
you should execute the blocking calls in DefaultEventExecutorGroup or your custom threadpool that can be added to when the handler is added
pipeline.addLast(new DefaultEventExecutorGroup(50),"BUSSINESS_LOGIC_HANDLER", new BHandler());
ctx.executor().execute(new Runnable() {
#Override
public void run() {
//Blocking call
}});
Your custom handler is initialized by Netty everytime the Server receives a request, hence one instance of the handler is responsible for handling one Client.
So, it is perfectly fine for issuing blocking calls in your handler. It will not affect other Client's, as long as you don't block it indefinitely (or atleast not for very long time), thereby not blocking Netty's Thread for long and you do not get too much load on your server instance.
However, if you want to go for asynchronous design, then there can be more than a few design patterns that you can use.
For eg. with Netty, if you can implement WebSockets, then perhaps you can make the blocking calls in a separate Thread, and when the results are available, you can push them to the client through the WebSocket already established.

In GWT the RPC call is Synchronous or Asynchronous

I'm getting confused a bit when it comes to Synchronous calls, and Asynchronous calls in GWT.
I am sure that GWT is makes Async calls.
It's clear to me that Synchronous is just waiting for the response, and after getting that response, executing the next command.
It is not in the case of Asynchronous, because it never waits for the response. Before getting the response it executes the next command right away.
But I can see in some blogs is says that RPC is Synchronous.....
Whereas GWT which uses RPC is not Synchronous. I understand that whenever I send the request it never waits.
Is RPC really synchronous?
If so how does GWT make Async RPCs?
or did I misunderstand anything?
GWT RPC(Remote Procedure Calls) is Asnyc for sure. Actually, All of implementations which are based on AJAX are all Asnyc.
Let's take a look on the example below:
emailService.emptyMyInbox(fUsername, fPassword, new AsyncCallback() {
public void onSuccess(Void result) {
// do some UI stuff to show success
}
public void onFailure(Throwable caught) {
// do some UI stuff to show failure
}
};
// do something more
We call the service on first line, right after the execution, the browser will execute the line // do something more, regardless of if the result returned or not.
For more information, see Dev Guide Server Communication

how to implement an event-drive consumer in camel

I am very new to Camel, and have been struggling to understand how to use camel in a specific scenario.
In this scenario, there is a (Java-based) agent that generates actions from time to time. I need an event-driven consumer to get notified of these events. These events will be routed to a 'file' producer (for the time being).
In the camel book, the example is for a polling consumer. I could not find a generic solution for an event-driven consumer.
I came across a similar implementation for JMX :
public class JMXConsumer extends DefaultConsumer implements NotificationListener {
JMXEndpoint jmxEndpoint;
public JMXConsumer(JMXEndpoint endpoint, Processor processor) {
super(endpoint, processor);
this.jmxEndpoint = endpoint;
}
public void handleNotification(Notification notification, Object handback) {
try {
getProcessor().process(jmxEndpoint.createExchange(notification));
} catch (Throwable e) {
handleException(e);
}
}
}
Here, the handleNotification is invoked whenever a JMX notification arrives.
I believe I have to do something similar to get my consumer notified whenever the agent generates an action. However, the above handleNotification method is specific to JMX. The web page says: " When implementing your own event-driven consumer, you must identify an analogous event listener method to implement in your custom consumer."
I want to know: How can I identify an analogous event listener, so that my consumer will be notified whenever my agent has an action.
Any advice/link to a web page is very much appreciated.
I know this is an old question, but I've been struggling with it and just thought I would document my findings for anyone else searching for an answer.
When you create an Endpoint class (extending DefaultEndpoint) you override the following method for creating a consumer:
public Consumer createConsumer(Processor processor)
In your consumer then, you have access to a Processor - calling 'process' on this processor will create an event and trigger the route.
For example, say you have some Java API that listens for messages, and has some sort of Listener. In my case, the Listener puts incoming messages onto a LinkedBlockingQueue, and my Consumer 'doStart' method looks like this (add your own error handling):
#Override
protected void doStart() throws Exception {
super.doStart();
// Spawn a new thread that submits exchanges to the Processor
Runnable runnable = new Runnable() {
#Override
public void run() {
while(true) {
IMessage incomingMessage = myLinkedBlockingQueue.take();
Exchange exchange = getEndpoint().createExchange();
exchange.getIn().setBody(incomingMessage);
myProcessor.process(exchange);
}
}
};
new Thread(runnable).start();
}
Now I can put the Component that creates the Endpoint that creates this Consumer in my CamelContext, and use it like this:
from("mycomponent:incoming").to("log:messages");
And the log message fires every time a new message arrives from the Java API.
Hope that helps someone!
Event driven is what camel is.
Any route is actually an event listener.
given the route:
from("activemq:SomeQueue").
bean(MyClass.class);
public class MyBean{
public void handleEvent(MyEventObject eventPayload){ // Given MyEventObject was sent to this "SomeQueue".
// whatever processing.
}
}
That would put up an event driven consumer. How to send events then? If you have camel embedded in your app and access to the CamelContext from your event action generator, then you could grab a Producer Template from it and just fire of your event to whatever endpoint you defined in Camel, such as "seda:SomeQueue".
Otherwise, if your Camel instance is running in another server or instance than your application, then you should use some other transport rather than SEDA. Preferably JMS, but others will do as well, pick and choose. ActiveMQ is my favourite. You can start an embedded activemq instance (intra JVM) easily and connect it to camel by:
camelContext.addComponent("activemq", activeMQComponent("vm://localhost"));

Fake a GWT Synchronous RPC call

First of all, I know that doing a synchronous call is "wrong", and know that "is not possible".
But, in a situation a lot complex (i dont know how to explain), i need to wait the response from server, I'am using the GWT-Platform command implementation for the GWT RPC calls.
I was looking for some kind of "hack" for doing this.
Thanks in advance.
Usually, by handling stuff in the onSuccess() function of your RPC request, you'll automatically "wait the response from server". So I assume you want to block all the code currently running? Since JavaScript is single-threaded that won't be easy, there is no sleep function that just halts the program.
But it might be that a hack using a timer does what you want:
Timer checkRPCResponse = new Timer() {
#Override
public void run() {
if (!serverResponseReceived) {
this.schedule(100);
} else {
proceedWithProgram();
}
}
};
checkRPCResponse.schedule(100);
I haven't tried out if the this.schedule(100) works in the above example, but you get the idea, which is a check if the server has responded every 100 ms. Of course you have to set serverResponseReceived = true yourself in the onSuccess() function. Call the timer right after the RPC.
There is a solution but it is not easy (e.g. you cannot flip a single parameter to make it work). GWT is using normal JS XMLHttpRequest under the hood. In GWT there is an overlay type for it called com.google.gwt.xhr.client.XMLHttpRequest. This class is used to send requests to the server over HTTP. Each JS XMLHttpRequest is first initialized by calling method open. This method has few parameters, but the third parameter specifies if the request should be asynchronous. If you change it to false, request will be synchronous.
But GWT-RPC doesn't use this class directly, it using it via RpcRequestBuilder, and this class is not using XMLHttpRequest directly as well, it is using RequestBuilder.
So what you'll need to do is to create customized version of RpcRequestBuilder and RequestBuilder (which will use XMLHttpRequest initialized to be synchronous).
The you can set RPCRequest builder to your GWT-RPC service instance, by casting it to the ServiceDefTarget.
Do you still want to have synchronous GWT-RPC requests?
GWT calls XMLHttpRequest.open() whith true as its third parameter which means the call will be asynchronous. I solved a similar need for testing purposes just forcing this third parameter to be always false:
private static native void fakeXMLHttpRequestOpen() /*-{
var proxied = $wnd.XMLHttpRequest.prototype.open;
(function() {
$wnd.XMLHttpRequest.prototype.open =
function() {
arguments[2] = false;
return proxied.apply(this, [].slice.call(arguments));
};
})();
}-*/;
After invoking fakeXMLHttpRequestOpen(), any further use of XMLHttpRequest will act synchronously. For instance:
remoteSvc.getResult(new AsyncCallback<String>() {
#Override
public void onSuccess(String result) {
GWT.log("Service called!");
}
#Override
public void onFailure(Throwable caught) {
GWT.log("Service failed...");
}
}
GWT.log("Last message");
will allways render:
Service called!
Last message
See https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/open for XMLHttpRequest.open() specification.

Using an Android Service to handle a network connection

I'm working on an Android app that needs to maintain a network connection to a chat server. I understand that I can create a service to initiate the connection to the server, but how would the service notify an Android Activity of new incoming messages? The Activity would need to update the view to show the new messages. I'm pretty new to Android, so any help is appreciated. Thanks!
Can you pass a handler to your service?
First, define your handler as an interface. This is an example, so yours may be more complex.
public interface ServerResponseHandler {
public void success(Message[] msgs); // msgs may be null if no new messages
public void error();
}
Define an instance of your handler in your activity. Since it's an interface you'll provide the implementation here in the activity, so you can reference the enclosing activity's fields and methods from within the handler.
public class YourActivity extends Activity {
// ... class implementation here ...
updateUI() {
// TODO: UI update work here
}
ServerResponseHandler callback = new ServerResponseHandler() {
#Override
public void success(Message[] msgs) {
// TODO: update UI with messages from msgs[]
YourActivity.this.updateUI();
}
#Override
public void error() {
// TODO: show error dialog here? (or handle error differently)
}
}
void onCheckForMessages() {
networkService.checkForMessages(callback);
}
and NetworkService would contain something like:
void checkForMessages(ServerResponseHandler callback) {
// TODO: contact server, check for new messages here
// call back to UI
if (successful) {
callback.success(msgs);
} else {
callback.error();
}
}
Also, as Aleadam says, you should also be away that a service runs on the same thread by default. This is often not preferred behavior for something like networking. The Android Fundamentals Page on Services explicitly warns against networking without separate threads:
Caution: A service runs in the main thread of its hosting process—the service does not
create its own thread and does not run in a separate process (unless you specify
otherwise). This means that, if your service is going to do any CPU intensive work or
blocking operations (such as MP3 playback or networking), you should create a new thread
within the service to do that work. By using a separate thread, you will reduce the
risk of Application Not Responding (ANR) errors and the application's main thread can remain dedicated to user interaction with your activities.
For more information on using threads in your service, check out the SO articles Application threads vs Service threads and How to start service in new thread in android
Did you check the Service API page: http://developer.android.com/reference/android/app/Service.html ?
It has a couple of examples on how to interact with a Service.
The service runs on the same thread and the same Context as the Activity. Check also here: http://developer.android.com/reference/android/content/Context.html#bindService%28android.content.Intent,%20android.content.ServiceConnection,%20int%29
Finally, take a look also at Lars Vogel's article: http://www.vogella.de/articles/AndroidServices/article.html
One common and useful approach is to register a broadcast receiver in your Activity, and have the Service send out notification events when it has useful data. I find this to be easier to manage than implementing a handler via a callback, mainly because it makes it easier and safer when there is a configuration change. If you pass a direct Activity-reference to the Service then you have to be very careful to clear it when the Activity is destroyed (during rotation, or backgrounding), otherwise you get a leak.
With a Broadcast Receiver you still have to unregister when the Activity is being destroyed, however the Service never has a direct reference to the Activity so if you forget the Activity will not be leaked. It is also easier to have the Activity register to listen to a topic when it is created, since it never has to obtain a direct reference to the Service...
Lars Vogel's article discusses this approach, it is definitely worth reading! http://www.vogella.com/tutorials/AndroidServices/article.html#using-receiver

Categories

Resources