Hi everybody,
I need some advise about the safeness of what I’m doing. Besides reading the docs and
this related
couple of forum posts
, I’m testing it empirically, to an extent that hasn’t caused any problems yet.
Some background info on how I’ve come to this point:
My webapp uses user authentication. That is, the user has to log in in order to use it. By imposition, each one is not in a “users” table, but is a database user. When a user tries to authenticate in my app, a connection to the database is attempted with those credentials, and the successfulness of this operations is what determines if the user is logged in the app. Each app/database users will get different sets of data at the database level, which is going to determine the operations he’s allowed to do.
At the beginning, I was initalizing my database class as an instance object and was passing it via dependency injection to the classes that needed it. After a short time it became obvious that this wasn’t the best approach, bot for efficiency and for code cleanless.
When I tried to switch to a static connection connection pool which could be “pooled”, making connections available via the typical static getConnectionFromPool() (and also the typical returnConnToPool() after ending the database operations, and so on), I soon realized that this approach would not work for me because once the static pool object was initialized it was shared between all the instances of the app being accessed by different users. Replacing it with a newly created pool with different credentials would affect also each current user. In practice, a refresh (done by a background thread) in, let’s say, a table displaying some listing, would change the set of records being displayed for all users to the set of information available for the permissions of the last user that logged in to the app (that is, into the database).
After considering some solutions, I determined the easiest and quickest solution would be to change my database class to, instead of a single pool, use a set or collection of connections pools, one for each authenticated user. It could be the beast also in terms of efficiency, as it is allowed that the same user can use several instances of the app in several computers at once. Finally, I ended having a static HashMap of connections pools. I’d just need to change my code in the “getConnectionFromPool()” method (and so on) to access the HashMap and return the proper connection pool for the user and then grabbing a connection from it, as usual.
I was already storing the username in the session and using it for several operations, so my db pool HashMap is indexed by name, and my aim was to access it each time I needed a db operation by grabbing it from the session.
This was working fine until I realized some table/grid which refreshes periodically was throwing exceptions. I could track it down to the refresher thread. The code I was using everywhere for getting the username I stored in the session was:
VaadinRequest request = VaadinService.getCurrentRequest();
Then, once I had the request, I could easily try a .getWrappedSession(), and finally easily get the username attribute.
But when running this code from the background thread, VaadinService.getCurrentRequest() returns null, which is consistent with what it’s stated, for instance, in
the javadoc for this method
:
I remembered some other way of getting the session, so I attempted simply to use it in case VaadinService.getCurrentRequest() was returning null:
VaadinSession.getCurrent();
and after that, “again”, a .getSession(), to finally retrieve the username attribute from it.
Apparently, this is running fine. This is what the javadoc says about the getCurrent() method:
What does mean “at a point when the current session is defined”? Can I assume that if this method is returning a value (not null), it’s returning the “proper” session? I’ve never got a null from it, but my fear is that the returned session is not the correct one for that background thread. I’ve done extensively testing and don’t notice any “mix of information” in tables being refreshed with several different users, each one with different sets of results, logged in the app at once in several different browser instances… appart from the FIRST testing I did, in which I SEEMED to notice some “leaking” between users, although I’m not sure and haven’t been able to reproduce it.
Is this a safe approach? My refreshing code is inside the run() method inside a TimerTask() which is turned on at the beginning of the app. It looks like this:
countDowner = new Timer();
countDowner.schedule(new TimerTask(){
@Override
public void run() {
UI.getCurrent().access(new Runnable() {
@Override
public void run() {
getANewResultSetAndPaintItInTable();
}
});
}
}, new Date(), 60000);
As you see, the aim of this is to refresh an info table each minute.
In the end: is this guaranteed to work as expected?
Does enveloping getANewResultSetAndPaintItInTable() in a
UI.getCurrent().access(new Runnable() {
@Override
public void run() {
// call to method here
}
});
block should provide any extra robustness / safeness? (I tried it already but didn’t notice any difference).
Do you have any other comments/suggestions about my approach?