I'm a Fedora user currently making use of inotify-java to implement directory polling. I have the following code snippet:
InotifyEventListener inel = new InotifyEventListener() {
#Override
public void filesystemEventOccurred (InotifyEvent ine) {
// code to handle - done
}
#Override
public void queueFull (EventQueueFull eqf) {
// this is the part when I'm not sure what I should do
}
}
You should perform the recovery actions specific to your application.
The "queue full" event happens if you're not retrieving events fast enough. Excess events are dropped, but you're notified of this.
You should think what would be the consequences for your application if you miss an event or two, and plan the recovery actions (e.g. clean the queue fast and do the rescan of the directory).
Related
I have page with grid. I am loading data through service to grid. Loading and computing all data takes about 20-40 seconds. When I press button to get data, page start loading (classical in vaadin top loading indicator start loading).
My question is, how can I stop loading/waiting for data?
I can't stop searching process on that server I am getting data from, it dont have this functionality, I can only request for data, and wait for them.
Should I stop some thread? should i use something like this.getUI... and somewhere here stop it?
I am using vaadin 7.7.4
Thank you :)
You should use threads for this.
You will need to separate your logic, that the main thread does add all components to the UI.
This thread then also needs to spawn a new thread which does fetch the data and then updates the UI accordingly.
To update the UI once the data has been fetched from the backend you will need to activate push in your UI.
Don't forget to synchronise thread access to the UI with something like:
ui.access(new Runnable() {
#Override
public void run() {
...grid_update_with_new_data... ;
}
});
The fetching of the data should occur outside the ui.access method, otherwise your UI will freeze during backend data loading.
See this post for more technical details
Using Thread with Vaadin? and https://vaadin.com/docs/v7/framework/advanced/advanced-push.html
#André Schild This is simplified code. When I hit search button, app start searching, no problem with that. Problem is how to STOP searching, before its done. Enough for me is to stop waiting for response, and stop loading bar at top of the page, but I dont know how to achive this.
#SpringComponent
#UIScope
#Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class DistraintSearchComponent extends CustomComponent {
#Autowired
private Service service
private Button searchButton = new Button("Search");
public void init(){
searchButton.addClickListener(new ClickListener() {
#Override
public void buttonClick(ClickEvent event) {
List<Results> results = service.findByFilter(filter);
refreshGrid(results);
}
});
}
}
I'm learning java-rx. I am developing an application and I want to consider the following points
The user can work offline or where the connection is very bad.
Always display updated data to the user
I want to prioritize the visualization of the data. With this I mean that I don't like to wait the timeout of the network and then go to consult the data to disk.
I developed the following observables in the application
Observable<Data> disk = ...;
Observable<Data> network = ...;
Observable<Data> networkWithSave = network.doOnNext(data -> {
saveToDisk(data);
});
I have also declared the following subscriber
new Observer<List<Items>>() {
#Override
public void onCompleted() {
mView.hideProgressBar();
}
#Override
public void onError(Throwable e) {
mView.showLoadingError();
}
#Override
public void onNext(List<Vault> vaults) {
processItems(vaults);
}
}
I would like to receive some advice as to the correct way of concatenating these Observables.
I want the data on the disk to be displayed first. Then check the network and if there is new data then update them.
The network query might be in parallel, but If it to run before the disk does not display the disk data.
Thank you very much.
Sorry for my English
Perhaps Dan Lew Blog Post can give you ideas.
I think disk.concatWith(networkWithSave).subscribe(ui) will do.
Disk data (if any) will always come first, though.
In case there is no data on disk, your disk source must complete without sending any messages. Disk source must never complete with error as this will effectively block your network source.
In your UI subscriber you may want to silently ignore onError (coming from network) if it has already got data from disk.
I just wondering - where the JSONObject or JSONArray received from the web-server should be parsed in Android app - in the main UI or should be delivered to the another one ?
For example, I'm using Volley library :
private void fetchResults(){
RequestQueue queue = Volley.newRequestQueue(mContext);
String url = AuthenticationRequester.URL_GET_ALL_ORDERS;
JsonArrayRequest jsonDepartureObj = new JsonArrayRequest(url, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray jsonArray) {
iVolleyCallback.onJSONArraySuccess(jsonArray);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
// hide the progress dialog
}
});
queue.add(jsonDepartureObj);
}
So should I put the iVolleyCallback.onJSONArraySuccess(jsonArray); in another thread execution or can be maintained the the main UI thread ?
Let's imagine that the incoming JSON is big and needs some time to be proceeded ?
The same question relates to the AsyncTask and to other possible ways working with the web-services in Android.
It is prefered that, every task that takes long time, should be proccessed in another thread to avoid overloading MainThread:
AsyncTasks should ideally be used for short operations (a few seconds at the most.) If you need to keep threads running for long periods of time, it is highly recommended you use the various APIs provided by the java.util.concurrent package such as Executor, ThreadPoolExecutor and FutureTask.
So if you know that you have big data and it will take time, you will use new thread, but if the data are small and takes less time, why take the risk? Move that to the new thread too
If, as you say yourself, the JSON data could be huge, and it could take some time to process, I think you could (or should?) try to process it in an AsyncTask. By doing this your UI thread will not be frozen during the processing.
In most GUI designs (not just Android), there are several threads having different roles and responsibilities:
The "main thread," running at "normal" dispatching priority, basically has nothing else to do but to respond promptly to the demands of the user-interface system. When "messages" arrive for its consumption, this thread immediately pre-empts the other threads so that the message can be processed quickly. Like any good manager ... ;-) ... they don't do the work themselves. They pass it off to other people.
When asynchronous requests (JSON ... etc.) are involved, there's usually a small "pool" of threads who are responsible for sending those to the host, receiving the response, doing the encoding/decoding, and then either acting-on the response or passing it along. These threads spend nearly all their time waiting on the host. They operate at a slightly-inferior dispatching priority.
Worker threads, operating at an even-more inferior priority, do any work that is computationally time-consuming. As much as possible, these threads don't do much I/O. They give-up their time slices quickly and readily to any other thread, but they usually consume their entire time slice when they can get one.
Potentially long running operations should always happen on a separate thread, or really any work (within reason...) that can be done on a separate thread should.
In your case, you're using Volley, so it's very easy for you to override your Request<T>'s parseNetworkResponse(NetworkResponse response); method, and parse the response on a background thread (since this method already runs on a background thread) before it's delivered. Since it's relatively seamless to do so, there really isn't a reason to not parse the response on a background thread.
Try this https://github.com/yakivmospan/volley-request-manager
//Queue using custom listener
RequestManager.queue()
.useBackgroundQueue()
.addRequest(new TestJsonRequest(), mRequestCallback)
.start();
private RequestCallback mRequestCallback = new RequestCallback<JSONObject, ResultType>() {
#Override
public ResultType doInBackground(JSONObject response) {
//parse and save response data
return new ResultType();
}
#Override
public void onPostExecute(ResultType result) {
//update UI here
Toast.makeText(getApplicationContext(), "Toast from UI", Toast.LENGTH_SHORT).show();
}
#Override
public void onError(VolleyError error) {
//handle errors here (UI thread)
L.e(error.toString());
}
};
I am using the new Couchbase Java Client API 2.1.1 and therefore JavaRx to access my Couchbase cluster.
When using asynchronous getAndLock on an already locked document, getAndLock fails with a TemporaryLockFailureException. In another SO question (rxjava: Can I use retry() but with delay?) I found out how to retry with delay.
Here is my adopted code:
CountDownLatchWithResultData<JsonDocument> resultCdl = new CountDownLatchWithResultData<>(1);
couchbaseBucket.async().getAndLock(key, LOCK_TIME).retryWhen((errorObserver) -> {
return errorObserver.flatMap((Throwable t) -> {
if (t instanceof TemporaryLockFailureException) {
return Observable.timer(RETRY_DELAY_MS, TimeUnit.MILLISECONDS);
}
return Observable.error(t);
});
}).subscribe(new Subscriber<JsonDocument>() {
#Override
public void onCompleted() {
resultCdl.countDown();
}
#Override
public void onError(Throwable e) {
resultCdl.countDown();
}
#Override
public void onNext(JsonDocument t) {
resultCdl.setInformation(t);
}
});
........
resultCdl.await();
if (resultCdl.getInformation() == null) {
//do stuff
} else ....
(CountDownLatchWithResultData simply extends a normal CountDownLatch and adds two methods to store some information before the count has reached 0 and retrieve it afterwards)
So basically I'd like this code to
try to get the lock infinitely once every RETRY_DELAY_MS milliseconds if a TemporaryLockFailureException occured and then call onNext
or to fail completely on other exceptions
or to directly call onNext if there is no exception at all
The problem now is that when retrying, it only retries once and the JsonDocument from resultCdl.getInformation() is always null in this case even though the document exists. It seems onNext is never called.
If there is no exception, the code works fine.
So apparently I am doing something wrong here but I have no clue as to where the problem might be. Does returning Observable.timer imply that with this new Obervable also the previously associated retryWhen is executed again? Is it the CountDownLatch with count 1 getting in the way?
This one is subtle. Up to version 2.2.0, the Observables from the SDK are in the "hot" category. In effect that means that even if no subscription is made, they start emitting. They will also emit the same data to every newcoming Subscriber, so in effect they cache the data.
So what you retry does is resubscribe to an Observable that will always emit the same thing (in this case an error). I suspect it comes out of the retry loop just because the lock maximum duration is LOCK_TIME...
Try wrapping the call to asyncBucket.getAndLock inside an Observable.defer (or migrate to the 2.2.x SDK if that's something you could do, see release and migration notes starting from 2.2.0).
I am writing an Eclipse RCP application that will have other plugin contributions besides my own, and need to determine when the application is idle (i.e. no activity for a period of time, application is minimized, etc.), and when that changes (i.e. application is brought back to the foreground, a mouse is clicked, etc.).
The problem I'm having is that I was going to capture all application keystrokes and mouse moves/clicks...using that to reset a timer, and when the timer is hit, then some idle processing can occur (i.e. informing a server of the idleness - and then again when we switch to active - nothing intensive). However, the application window shell does not receive child events for the various views, etc. so either I'm missing something, or this is the wrong approach.
Can anyone offer a solution? I'm not looking for system-wide idleness - just application idleness.
Thanks.
The Eclipse IDE already has something similar to perform Garbage Collection, take a look at the class org.eclipse.ui.internal.ide.application.IDEIdleHelper in Bundle org.eclipse.ui.ide.application
Maybe that
display.addFilter(SWT.MouseDown, new Listener() {
#Override
public void handleEvent(Event event) {
}
});
is what you're looking for (you can add other events, too)?
This is executed before event handling is done component wise...
But its use is not generally recommended - it should be a very restricted use case, so.
You can use the fact that the readAndDispatch method will return false when there are no more messages to process. Something like this:
long lastActivityAt = 0;
int idleThresholdSecs = 5;
while (true)
{
while (display.readAndDispatch())
{
lastActivityAt = System.nanoTime();
}
if (System.nanoTime() - lastActivityAt > idleThresholdSecs * 1000 * 1000 * 1000)
{
// we have been idle for at least "idleThresholdSecs"
...
}
else
{
Thread.sleep(50);
}
}