Selectively prevent Session from being created - grails

In my app, I have an external monitor that pings the app ever few minutes and measures its uptime / response time Every time the monitor connects, a new server session is created, so when I look at the number of sessions, it's always a minimum of 15, even during times where there are no actual users.
I tried to address this with putting the session creation code into a filter, but that doesn't seem to do it - I guess session automatically gets created when the user opens the first page?
all() {
before = {
if (actionName=='signin') {
def session = request.session //creates session if not exists
}
}
}
I can configure the monitor to pass in a paramter if I need to (i.e. http://servername.com/?nosession, but not sure how to make sure the session isn't created.

Right now there is nothing you can do to prevent the session creation. See: http://jira.codehaus.org/browse/GRAILS-1238
Fortunately, until you are hitting high numbers of requests per second, this isn't a huge problem. One thing we did to get around the false data in our "currently active users" report, was to log the sessions to the database. We create a session record only when the user logs in. Then on specifically mapped URLs, we will "touch" that session record to update the last accessed time. The session record keeps track of user agent, IP, etc and is useful for many reasons. Doing something like this would get around the bogus session count.

Related

CloudKit : How to handle account changes with local persistent store?

In my application i have to maintain a local persistent store in sync with cloud kit private database. So I just wanted to know how can I handle account changes that may happen.
Confusion I have is as below:
say a set of records belong to user A now if user B log's in to the same phone I can do the following of the 2 things:
Ignore user and let data sync to B account too but that way A's data will get sync to B's private account too. Here the record change tag and all get a bit mess up since am saving CKRecord encoded fields to database.
I can maintain a user table and link each record to the user that is logged in that way user data will get separated. So should I maintain a user field along with all records ?
How can this be best handled even apart from above 2 things.
Of course in your local persistence store you could add the userID to personalize all records. An other mechanism is to remove all local data and fetch the users data when a change is detected. If you want to keep the users data on the device you could also create separate data stores for each user.
You can detect a changed login by adding the following code in your app delegate or root view controller:
NSNotificationCenter.defaultCenter().addObserverForName(NSUbiquityIdentityDidChangeNotification, object: nil, queue: nil) { _ in
/// remove local data and fetch user data
}
You should also refresh all user related data in memory and refresh the loaded views.

Why I lose my session variable?

I´m on MVC and using KnockoputJS. I select the value from 2 select. In the first select i choose IDCompany, and the second select i choose IDSubsidiary.
I send the model in Json to JsonResult in the controller and I create a variable session and a cookie and save IDCompany in the Session variable and in the cookie with the same name.
I do the same with IDSubsidiary. Finally, I return to the ajax function (which call "Save" at first)
[HttpPost]
public JsonResult Save(ViewModel viewModel)
{
Session["IDCompany"] = viewModel.IDCompany.ToString();
Response.Cookies["IDCompany"].Value = viewModel.IDCompany.ToString();
Response.Cookies["IDCompany"].Expires = DateTime.Now.AddDays(1);
Session["IDSubsidiary"] = viewModel.IDSubsidiary.ToString();
Response.Cookies["IDSubsidiary"].Value = viewModel.IDSubsidiary.ToString();
Response.Cookies["IDSubsidiary"].Expires = DateTime.Now.AddDays(1);
return Json(true);
}
The problem is that after a while (30 mins approximately), i lose Session["IDCompany"] and Session["IDSubsidiary"] (becomes null).
The problem can be that, for example, Session["IDSubsidiary"] and Response.Cookies["IDSubsidiary"] has the same name?
There are two reasons this could be happening. 1) The session is timing out, or 2) you are using "In Process" session state.
If the user sits on a page for thirty minutes, and then the value is gone the next time they refresh or go to another page, its likely a timeout problem. You could try increasing the sessionState timeout; however, you'll probably start running into the issue described below. If you are determined to use Session variables, you should probably switch to a different state mode than "in process" which is the default.
If it is not timing out, the reason your value is lost is because "In Process" session state, goes away when the App Pool recycles. This can happen for a variety of reasons. You probably want to change your session state mode to State Server or SQL Server. This will keep your session data around between app pool recycles, but you will need to enable the "ASP.NET Session State Service" on the web server if you go the State Server route.
There are several state modes, each with different behaviors. You can read about them here on MSDN.

How to avoid calling a method multiple times when the method takes long time to complete

There are several view controllers in my app where I need to sync the local contents with server using a method running in a background thread. Sometimes I need to insert data to my database on server if user has created any. The approach I am using here is to set a flag(something like isSynced = NO) on objects that I need to sync with server (there objects are in Core Data). When the syncing is complete my method will get rid of the flag(e.g. isSynced = YES) so it won't be sent again next time.
Now the problems is that the syncing method takes very long to complete(1 or 2seconds.). If now user pops out this particular view controller and swiftly comes back the previous call is still in progress and next one will be kicked off. The consequence is that there might be duplication in database.
My approach now is the make the syncing method to be called by a Singleton object:
#property (nonatomic) BOOL isSyncing;
//every time before syncing. check if object is available for syncing
if (!isSyncing) {
isSyncing = YES;
// sync server
// when complete
isSyncing = NO;
// post notification to view controller to reload table
} else {
// cancel because previous call is not finished
}
My concern is that if the call is cancelled my view controller will not be able to receive the notification is waiting for. I can fix this by posting another notification in the event of cancelation. I am wondering if this is the right to do this because I think that this problem should be pretty common in iOS development and there should be a standard way to deal with it
Your singleton approach may not be necessary. I don't see the harm in sending a database insert for each new object. You will still need to ensure each object is synched. That is, update the "isSynched" flag. Keep each object that needs to be synced in a "need to synch" list.
Then, update the "isSynced" flag by performing a background query on the database to check if the object exits. Then, use the result of the query to set the isSynched flag.
If the query result indicates the object is not in the database you then resend the object and leave it's "isSynced" flag set to NO.
If the query result indicates the object is in the database, set the "isSynced" flag to YES and remove it from your "need to synch" list.
An approach for preventing duplicate database entries is to make a unique key. For example, tag each with a hash based on the time and date. Then configure the table to ensure each key is unique.

Zend\Session\Container annoyingly locks while in use, what's your workaround?

I have a controller with two actions. One performs a very long computation, and at several steps, stores status in a session container:
public function longAction()
{
$session = new Container('SessionContainer');
$session->finished = 0;
$session->status = "A";
// do something long
$session->status = "B";
// do more long jobs
$session->status = "C";
// ...
}
The second controller:
public function shortAction()
{
$session = new Container('SessionContainer');
return new JsonModel(
array(
'status' => $session->status
)
);
}
These are both called via AJAX, but I can evidence the same behavior in just using browser tabs. I first call /module/long which does its thing. While it completes its tasks, calling /module/short (I thought would just echo JSON) stalls /module/long is done!
Bringing this up, some ZFers felt this was a valid protection against race conditions; but I can't be the only one with this use case that really doesn't care about the latter.
Any cheap tricks that avoid heading towards queues, databases, or memory caches? Trying to keep it lightweight.
this is the expected behavior. this is why:
Sessions are identified using a cookie to store the session id, this allows your browser to pickup the same session on the next request.
As you long process is using sessions, it will not call session_write_close() until the whole process execution is complete, meaning the session is still open while the long process is running.
when you connect with another browser tab the browser will try and pickup the same session (using the same cookie) which is still open and running the long process.
If you open the link using a different browser you will see the page will load fine and not wait around for the session_write_close() to be called, this is because it's opening a separate session (however you will not see the text you want as it's a separate session)
You could try and manually write and close (session_write_close()) the session, but that's probably not the best way to go about things.
It's definitely worth looking at something like Gearman for this, there's not that much extra work, and it's designed especially for this kind of async job processing. Even writing status to the database would be better, but that's still not ideal.

How can I store user information in MVC between requests

I have an MVC2-site using Windows authentication.
When the user requests a page I pull some user information from the database. The class I retrieve is a Person class.
How can get this from the database when the user enters the site, and pick up the same class without touching the db on all subsequent page requests?
I must admit, I am pretty lost when it comes to session handling in ASP.net MVC.
You can store that kind of information in HttpContextBase.Session.
One option is to retrieve the Person object from your database on the first hit and store it in System.Web.HttpContext.Current.Cache, this will allow extremely fast access and your Person data will be temporarily stored in RAM on the web server.
But be careful: If you are storing significantly large amount of user data in this way, you could eat up a lot of memory. Nevertheless, this will be perfectly fine if you only need to cache a few thousand or so. Clearly, it depends upon how many users you expect to be using your app.
You could add like this:
private void CachePersonData (Person data, string storageKey)
{
if (HttpContext.Current.Cache[storageKey] == null)
{
HttpContext.Current.Cache.Add(storageKey,
data,
null,
Cache.NoAbsoluteExpiration,
TimeSpan.FromDays(1),
CacheItemPriority.High,
null);
}
}
... and retrieve like this:
// Grab data from the cache
Person p = HttpContext.Current.Cache[storageKey];
Don't forget that the object returned from the cache could be null, so you should check for this and load from the database as necessary (then cache).
First of all, if you are using a load balanced environment, I wouldn't recommend any solution that you try without storing it in a database, because it will eventually fail.
If you are not in a load balancing environment, you can use TempData to store your object and then retrieve it in the subsequent request.
HttpContext.Current.Session[key];

Resources