I have the following situation:
I have a Service that checks periodically for new data over the internet,
when new data are available they are downloaded and saved on sqlite.
when the save to db is complete the service broadcasts an intent so that the activity knows to pull the new data from the db.
The user might want to request an immediate update...
...in that case I use a Messenger to request the Service to look for new data
Here is the problem:
the user is notified that a request is ongoing, but it might take a while, can be unsuccessful, could never return...
currently I get a message (using a Messenger) back from the Service to the Activity informing of the result of the request, or, if I get no message, in x seconds I inform the user that the request was unsuccessful.
Please can you suggest a different approach?
I don't like to wait
for a message and if after x seconds none is received inform the
user, is there a better way?
You've got the basics, so not much else to recommend. I'll just show you a few alternatives:
You can use ContentObserver and update the UI once there is new data in the database (no need to wait for a message from the service).
If you've got a lot of communication between Service <-> UI components, it might be easier if you take a look at Otto, EventBus or just restructure your code around Observables / RxJava.
You can move the Timeout logic to the service (it will be easier this way since all the error handling will be in a single place) and just return the error message to the UI. Most network frameworks allow you to set a Connection Timeout parameter and will fail the request after this time is reached. If you haven't looked at network frameworks yet - Retrofit + OkHttp is a great starting point.
You might consider optimistic rendering/optimistic updates- A pattern in which you update the UI on client as if it has being successful on the server.
Once you get response from the server you update the UI accordingly.You can refer apps with new designs like google hangouts.
For more info refer this discussions:
what is `optimistic updates` in front-end development
https://ux.stackexchange.com/questions/17514/should-we-be-optimistic-or-pessimistic-with-ui-updates-on-ajax-requests
I guess using this approach will give better usability to your app.
The current implementation looks ok. However you can improve it by following this talk-https://www.youtube.com/watch?v=BlkJzgjzL0c
If you think about this as a Model View Controller problem, the issue here is the lack of a model to represent the state of the Service. When the Service is performing the refresh, this "state" needs to reflected in your UI. Thus the Service needs to record this somewhere that the UI can access.
One option is simply a piece of shared memory, such as a Singleton object or even a static member variable (not recommended). Another option is to keep that state in your database.
Another issue is notifying the UI when this state changes. As mentioned by other posts there are multiple ways of doing this such as a LocalBroadcast, message bus like Otto, ContentObservers, etc.
Related
I'm currently working on an Android App which calls HTTPS Requests (like Login, etc.) to a Rest API. My first approach was to use AsyncTask to do this work not on the Main Thread. Unfortunately, I need to know if the Login was successful or not in order to proceed with the code, because if you are not logged in you have only limited access to other parts of the app.
I've tried it with AsyncTask because I used it in a previous project, but I noticed the problem with the return value a little bit to late and now I don't know what technology I should use in order to:
Don't block the main UI
Wait for a response
Evaluate the response with a boolean or something similar
I would appreciate if someone could help me with choosing the best way of accomplishing my problem
Use Retrofit for API calls.
But, it will be async as well. That's something you can't avoid.
If you have to wait for call finishes, and process to the app/dashboard, there is no other way.
Practice is to show loader over the screen, send request in async task, wait for response, hide loader, process to the app.
Not sure about your implementation, but other approach could be:
set as user is not logged in
process to the app handle user as he isn't logged in yet
when login request is successful, set some global variable that he's logged in
I am trying to have a auto refresh feature for the grid which basically, updates the grid with latest data from the server every 'n' seconds.
I was able to implement the PollListner whenever the user enables Auto-Refresh.
UI ui= TestUI.getCurrent();
Boolean value = isRefreshChkBox.getValue();
PollListener listener = e -> {
explorer.reloadUI();
};
if (value) {
String refreshRateValue = refreshRateTxtField.getValue();
int refreshRate = Integer.valueOf(refreshRateValue);
int millis = (int) TimeUnit.SECONDS.toMillis(refreshRate);
absUI.setPollInterval(millis);
absUI.addPollListener(listener);
} else {
absUI.setPollInterval(-1);
absUI.removePollListener(listener);
}
With the above code, I add PollListener everytime autorefresh is enabled and I remove it on disable.
I found similar question here VAADIN 7: What is the simplest way to refresh a Vaadin View in 5 minute intervals?
But what I want to understand, is there a better approach to achieve a simple usecase AutoRefresh UI?? where should PollListener be implemented?? I thought of creating PollListener once for the view and just update the PollInterval everytime user changes the refresh rate.
Any pointers on which approach is better or is there completely new concept in Vaadin to achieve this?
TIA
See the correct Answer by Leif Åstrand. I will add a bit of discussion, and a complete example app using both Polling and Push.
Vaadin 8 has two ways to automatically update the display of information without the user making a gesture: Polling & Push.
Polling
In Vaadin 8’s Polling feature, you set a polling interval of milliseconds on your UI subclass. The default value of -1 disables Polling.
myUI.setPollInterval( ( int ) TimeUnit.MINUTES.toMillis( 1 ) ); // Specify milliseconds for polling interval.
When enabled, the Vaadin JavaScript library installed in the user’s web browser checks in with the Vaadin server. Being a PollNotifier, the UI checking-in causes an event to be fired on the server-side.
If you define a class that implements the PollListener interface, your instance will have its poll method invoked.
Upon registering your PollListener. get back a Registration object. That object provides a remove method to unregister your listener, if need be.
You have your choice of defining your PollListener using lambda syntax, an anonymous inner class, or a separately-defined class.
Registration registration = this.addPollListener( new UIEvents.PollListener() {
#Override
public void poll ( UIEvents.PollEvent pollEvent ) {
System.out.println( "TRACE - PollListener::poll running. " + Instant.now() );
…
}
} );
Or, lambda syntax:
Registration registration = this.addPollListener( ( UIEvents.PollListener ) pollEvent -> {
System.out.println( "TRACE - PollListener::poll running. " + Instant.now() );
…
} );
During this invocation, your code can register a Runnable to be invoked at a convenient time with your UI subclass.
That Runnable does the work of updating widgets contained in your UI subclass. Remember to never access or modify widgets from a background thread. You may get away with it, or you may cause terrible things to happen. Be safe: Always call UI::access to pass a Runnable that accesses the widgets. That Runnable will be run on the main user-interface thread of your web app, the thread in charge of your UI subclass instance.
getUI().access( new Runnable() {
#Override
public void run ( ) {
subscriber.refresh( new ArrayList <>( statusList ) ); // Copy the list in case the `Grid` modifies it, such as sorting.
}
} );
Pros
The upside of using the Polling feature is that the programming you must do is simpler than with Push (discussed below). Polling is likely a better route to take when learning about automated non-user-generated updates.
One simple aspect is that each instance of your UI subclass is in charge of its own polling, choosing if and when to do polling and controlling how often to poll. Each UI subclass instance calls its own setPollInterval method. More polling may be nice for the user, but the chattiness increases network traffic, thereby making your network admin cranky. So you can tune the frequency by UI subclass instance. Remember that not only does each user have their own UI subclass instance, but also, Vaadin 8 is capable of multi-window/tab apps. One web app in each web browser can have multiple windows/tabs open, each running their own instance of the same or different UI subclasses.
Cons
One downside aesthetically is that polling breaks the request-response elegance of the HTTP design. While this is a pet-peeve of mine, that ship has sailed long ago, so I'll not waste bytes here ranting about using a document-delivery system as an interactive client-server app architecture.
A more practical downside is unnecessary traffic on the network. If you are able to use Push via WebSocket or Webpush, then an open connection is maintained between client and server with very little traffic all the while until the server generates an event to be communicated to the client. But be aware that WebSocket is easily defeated by firewalls & proxies, and Webpush may not be implemented/supported, in which case the Push implementation in Vaadin (the Atmosphere Framework library by async-io.org) may fall back to polling techniques.
Another downside is inefficiency of each client doing its own repeated polling and each triggering a separate execution on the server-side such as the search for fresh data in the database. If you have many clients all consuming the same set of immutable objects, then Push can be more efficient doing a single search for fresh data and delivering the same bunch of data objects to all the clients.
Push
The combination of Vaadin with Atmosphere (linked above) vastly simplifies using Push technology in your web app. Nevertheless, it is a bit more complicated with more moving parts than seen with the Polling feature.
Firstly, enable Push with the #Push annotation on your UI subclass.
Then schedule the firing of an event every minute using a ScheduledExecutorService. Set up that executor with a ServletContextListener. See example code below for all this.
Pros
Push can be quite efficient in terms of network traffic able to use WebSocket technology or Webpush, as mentioned above.
Cons
Unfortunately WebSocket can be defeated by firewalls & proxies. And Webpush is new and may not be widely supported. In this case, Vaadin/Atmosphere may fall-back to using a polling approach.
Another downside is that the coding is a bit more complex. A programmer new to this work may take a while to grasp the various moving pieces.
You need a background thread on the server-side to track the time, in our case firing every minute. The modern approach to that is using a ScheduledExecutorService to handle the threading and firing schedule.
To setup that executor service, you will need to implement a ServletContextListener as discussed below.
Be aware that some of the push approaches, especially WebSocket, involve maintaining an open network connection. So this consumes resources such as port numbers on your server machine.
Example app
I built a complete working example app using Vaadin 8.6beta1. This app supports both Polling and Push. Not sure if you would ever mix both in a real web app, but perhaps.
Access the main files on my Google Drive. Add to a project created via the Maven archetype vaadin-archetype-application provided by Vaadin Ltd.
Caveat: This example was cobbled together part-time over days. So it may or may not be production-ready code, and may or may not show proper technique. But hopefully it will help to guide a newbie.
Caveat: I am not an expert in this arena. So take all my discussion above and my example code here with a grain-of-salt. Do your own research and study.
This app allows you to enable and disable each approach via radio buttons. You can also force an immediate refresh by clicking the Refresh manually now button.
The green-shading indicates changed values since the last refresh.
You can run multiple windows. Watch them update together or separately or not all, depending on your radio button settings.
Database
The main idea of this example app is to simulate a database maintaining a current status of some ten pieces of equipment/processes/people/whatever. Each status in identified by a number 1-10. Each has a status with a domain of ten values, 1-9. And each status records the moment it was last updated.
These ten status records are displayed as rows in a Vaadin Grid widget.
All this data is recorded in a relational database, the H2 Database Engine. As a demo, we’ve no need for persistence, so the database is in-memory. A background thread randomly updates the status rows in the database.
MyDbService.java
This database-service code establishes our in-memory H2 database, defining the table for our Status, and populating ten rows. This class also can randomly update the value of some of the rows. And you can ask to retrieve a List of Status objects representing the currently stored values.
Status.java
Each status record is represented in Java by the Status class, a simple POJO.
Lifecycle
Vaadin is based on Java Servlet technology. Your Vaadin app is one big Servlet implementation. As a servlet, it responds to incoming requests by the users’ web browsers.
Before that first incoming request, we need to do some set-up work. For one thing, we need to establish and populate that database with our ten status records.
The Servlet specification requires all web containers to support the ServletContextListener interface. If you write a class implementing that interface, and declare it to the web container, then it will be invoked before the first request and after the last request.
In our example, we use that hook to establish the database. We also set up a background thread that randomly changes our stored status records to simulate either users’ updates or fresh data from a feed.
Context listener
Here is our example ServletContextListener.
The easiest way to declare its presence to our web container is by the #WebListener annotation but you can choose other routes as needed in your deployment scenario.
#WebListener
public class MyServletContextListener implements ServletContextListener {
…
MyUI.java
The entry point into this Vaadin web app is our subclass of UI, MyUI.java. It has two jobs: (a) Get our user-interface content on-screen, and (b) Register itself as a PollListener to react to polling updates.
DataDisplayLayout.java
Here is our user-interface content. This is the centerpiece of this example app. It displays the Vaadin Grid whose display is to be updated with fresh data.
DataDisplayLayoutRefreshManager.java
This manager oversees the pub-sub (Publish-Subscribe) model of signing up instances of our DataDisplayLayout that want to be updated via Push.
A collection of weak references are used here to track the subscribers. So the subscribing DataDisplayLayout instance can gracefully notify of their desire to no longer be updated, or the instance can simply go out-of-scope to eventually be dropped as a subscriber.
The Polling approach does not need this manager, as each instance of our UI subclass (MyUI) is individually polling the server.
mytheme.scss
The green coloring of the cell in the Vaadin Grid denoting a fresh value is set via CSS. In Vaadin 8, we do this by editing the mytheme.scss file found buried in your project’s webapp folder.
Here we define the style name fresh_row.
#import "../valo/valo.scss";
#mixin mytheme {
#include valo;
// Insert your own theme rules here
.v-grid-row.fresh_row > td:nth-child(2) {
background-color: honeydew;
}
}
We must assign that style name to our Vaadin Grid rows by implementing a style generator.
this.grid.setStyleGenerator( ( StyleGenerator ) o -> {
Status s = ( Status ) o;
if ( s.getUpdated().isAfter( this.whenRowLastUpdated ) ) {
return "fresh_row";
} else {
return null;
}
} );
There are basically two ways of updating a Vaadin UI from background activity: poll and push. Each has their own pros and cons.
Polling is the technically more simple approach. It's based on a timer in the browser that triggers a request at a regular interval. Any pending changes will be delivered to the client in the response to that request. In addition, you can add a listener that gets run for every such request so that you can manually check for changes and if needed, update the UI.
Push is based on keeping a persistent connection open between the client and the server, so that the server can send changes to the client immediately instead of having to wait until the client opens a connection and asks for changes. The benefit here is that changes can be sent to the client immediately when they happen, instead of only at regular intervals.
Which to use depends on your requirements. Polling may use slightly less resources because there's no need to keep a connection open all the time. Polling may also be beneficial if there is no server-side trigger when the data changes, but instead, the server-side logic would still have to periodically explicitly check whether anything has changed. The main benefit of push is that changes can be sent immediately when something happens.
What I am doing:
I am using play 2.5.7 (java) and trying to build a REST application.
When I get a call on my controller I ask the first actor, this actor can only solve part of the problem (getting additional data), which needs to be forwarded to another actor which uses the request data and additional data to update some more data, send an async void call (tell) to another actor and respond to the controller. All these (4) actors are #Injected in other actors or controller with Guice.
Flow of calls:
controller --(Patterns.ask)--> actor1 --(actor.forward)--> actor2 --(actor.forward)--> actor3 (-tell-> actor4) and --(sender().tell)--> controller.
Issue:
This works for first 4 calls. Then on actor1.forward keeps failing on every consecutive request; Patterns.ask times out. System.out on the line before actor1.forward works but not the actual forward. No matter the timeout value (tried even 20s). No change done in the request; I just hit the send button in postman every time.
I have two questions:
Why 4? Why does it fail after 4th request? Is it some config? What should I look for in config?
Is what I am doing with actors correct way to build a REST web service?
Update: I found the issue; it was caused due to consumption of Redis connections through the pool and never freeing them. But the second question I had still remains, is what I am doing here advisable?
Sure, this could be a reasonable design. But I would consider though whether it would be more maintainable to work with Future returning methods, unless your workflow requires some complex protocol between multiple moving pieces or internal state. It may also be worth considering Akka Streams, if your processing doesn't map well to async method calls.
Basically, actors are a pretty low-level tool. To the extent that you need them, I would try to minimize the surface area of your application where they are being directly used. Higher-level abstractions are better, where possible.
I have a requirement in my java web application where I need to send email alerts for certain conditions. For this I have used javax mail api and sending email works just fine. But the problem is the programs executions waits until the methods for sending the email are executed. As there are hundreds of email to be sent at various points ... this reduces the performance significantly.
I am using spring and have also used spring aop. Can anyone suggest me how can I separate my business logic and sending email functionality. It should be like -
Sending emails is my advice which gets executed when xyz method is called - So main execution should not wait for advice to finish its execution rather it should return back and execute further business logic thus email sending executed separately.
Here creating new threads seems obvious choice. But I think there could be some better way, is there? Thanks.
You can make the mail sending method #Async. This way Spring will execute this in a seperate thread. Read this blog post about it: Creating Asynchronous Methods
What you describe is asynchronous execution and natural way to do async execution is Java is to use threads.
You can introduce some Executor, e.g., Executors.newFixedThreadPool(), and use it to offload mailing task into separate threads.
Aspect itself is a unsuitable place for this, since this would introduce state into aspect, for example, you may want to check if mail task was successful by using returned Future:
class Mailer {
private final ExecutorService executor = Executors.newFixedThreadPool(maxMailingThreads);
//...
public void doMail(MailTask anEmail) {
Future<MailTaskResult> future = executor.submit(new MailTask(anEmail));
future.get().isSuccessful(); // handle success or failure somehow
}
Better move this logic into separate class and call it from aspect somehow.
Treat the email sending functionality like an IO device. Make it a plugin to your business logic. Do not allow any knowledge of the fact that you're even talking to the email code into your business logic. Make the email logic depend on the business logic. Never the other way around.
Here's a very good talk about this kind of architecture:
https://vimeo.com/97530863
Here's a series debating it:
https://www.youtube.com/watch?v=z9quxZsLcfo
Here's a ruby master demonstrating it with real code. We miss him.
https://www.youtube.com/watch?v=tg5RFeSfBM4
If your business rules are interesting enough to be worth respecting than this is the way to make them the masters of your application. Express them only using java. Don't accept any help. No spring, no weird annotations, just business rules. Push all that "help" out to the mail code.
Do this and your app will scale well. I think this is the best way to put it:
That's from a hexagonal architecture post. But the idea of giving your business rules a safe place to live removed from implementation detail shows up in many architectures. This answer rounds them up nicely.
Use a localhost MTA (like OpenSMTPD) and then relay to your real SMTP server, like Amazon SES ("Satellite" mode). It won't block.
I did a test, and sent 1000 emails in 2.8 seconds this way
It's simpler than doing async in java, and is useful across multiple applications.
As for separating logic, raise a Spring Application Event when needed, and make another class to listen to it, and send your email from there. Or consider something like Guava's EventBus
Consider creating a separate thread to send emails within your application. This will allow parallel execution(application+email sending).
If you would want another approach you can create a separate back end application that only sends emails. Although you will need to submit the email messages to the application. An asynchronous way to do this is to send a JMS message to the email application.
I'm using the Java AWS SDK to make EC2 spot instance requests. As opposed to on demand instances, the API for spot requests does not have anything similar to ClientToken and thus does not support idempotency out of the box.
The most straightforward way I could think of to do this was to set the LaunchGroup property to a unique UUID; when I check for that I call DescribeSpotInstanceRequests and see if I already have a request with the same launch group.
To my surprise, it seems that there's a delay before the describe call returns the spot requests sent before. I wrote a JUnit test for this and it seems that in order for it to be consistent I would have to set a timeout of at least 60s between the two calls (request spot instance and describe spot instance requests). I need to have a granularity of 10s, because my requests can get repeated by the application at this interval, in case of any failure - i.e. something breaks after I sent the request but before I could read the result I got back from Amazon. In that case I don't want to have the request repeated, I just want to see that it got registered and move on.
#Test
public void testRunSpotInstances() throws Exception {
activity.execute(execution);
timeout(TIMEOUT);
// shouldn't do anything
activity.execute(execution);
timeout(TIMEOUT);
DescribeSpotInstanceRequestsResult result = client.describeSpotInstanceRequests(
new DescribeSpotInstanceRequestsRequest().withFilters(new Filter()
.withName("launch-group").withValues(BUSINESS_KEY)));
assertThat(result.getSpotInstanceRequests()).hasSize(1);
timeout(TIMEOUT);
}
The test works every time if TIMEOUT is set to 60s; for 40-50s it works intermittently. Anything below this fails every time.
Has anyone managed to work around this delay? Is implementing idempotency for spot requests possible using just the AWS API and not having state saved in the client application?
In that case I don't want to have the request repeated, I just want to see that it got registered and move on.
If you got a 200 back, then it's registered. It may not show up right away, but it's registered and you can move on in your flow.
Is implementing idempotency for spot requests possible using just the AWS API and not having state saved in the client application?
I don't believe so. I have the same sort of issue with Amazon's EMR. The way that I work around it is to have a component who's job it is to observe clusters. When I make a request for an EMR cluster, I get back a cluster id, which I then pass off to some observer. The observer will then call my other components when that cluster changes state. Not being acknowledged by EMR right away is a valid case and is not treated like an exception.
I have no idea if that's appropriate for you. Perhaps you could try maintaining the SpotInstanceRequestId. In my case, I only keep them in memory, but you could keep them somewhere persistent if need be.