-
Notifications
You must be signed in to change notification settings - Fork 140
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Session incorrectly times out early if there is a long running request #1
Comments
By default, django stores session data in the database. However, it probably only does so at the end of the request. To fix this, we could make the middleware force a database write i think with Ideally, SESSION_SECURITY_EXPIRE_AFTER should be higher than the longest possible request on your website. Can't you set it that way ? I could reproduce the problem on /sleep/ (new url in the test project). Did not test it with your pull request thought. What do you suggest ? Also, thanks a lot for your feedback ! |
Yes you are right, I assumed the session data was stored on the client side because of the behavior, but I just confirmed that the cookie only contains a session ID. I don't really have any suggestions and I was hoping you would lol. I have increased SESSION_SECURITY_EXPIRE_AFTER on my site and I was using the low values just for testing. I think this can probably be documented as a trivial bug that won't need to be fixed as long as SESSION_SECURITY_EXPIRE_AFTER is longer than the timeout for a request. The tests doesn't run on my machine because it's missing selenium and I haven't had a chance to figure out how to set that up yet:
|
On Thu, Mar 28, 2013 at 5:52 PM, yscumc notifications@github.com wrote:
I'm thinking that maybe we could have a setting that forces writing This should be documented indeed.
Oops, sounds like you need to pip install selenium :) |
Wow Turns out I also needed Not sure if this was supposed to happen but four tests failed:
First time I used selenium... pretty cool stuff. |
Did you run it from your own project ? It should be run from the test_project in this repo ... ... but yeah, it tries to be good, here's a nice link if you're thirsty of knowledge ;) http://www.tdd-django-tutorial.com/ |
Nope, I ran it within django-session-security as
From one of the command prompt you showed earlier, I'm guessing you're using Linux, cygwin, etc but I'm running Windows. Do you think this would make a difference? Thanks for the link, I'd love to read it and hopefully I'll be able to get around to it lol |
Try On Mon, Apr 1, 2013 at 4:10 PM, yscumc notifications@github.com wrote:
http://yourlabs.org http://blog.yourlabs.org |
Still got same failure...
...
|
Interresting, it might be all due to jquery.js not being found. In the test_project, try this command: It should output something like this:
If it doesn't then that might be the problem to fix windows OS support. On Tue, Apr 2, 2013 at 3:53 PM, yscumc notifications@github.com wrote:
http://yourlabs.org http://blog.yourlabs.org |
Seems to have found it
|
Ok, I have changed the test_project template to use On Tue, Apr 2, 2013 at 4:53 PM, yscumc notifications@github.com wrote:
http://yourlabs.org http://blog.yourlabs.org |
How long does the tests normally take? I no longer get the ValueError exceptions, but it seems to be hung on the 3rd or 4th test case (after the 3rd period):
It's been about 15 mins and there's been no change. Btw, I'm using Django 1.5. |
It depends, but ~3 minutes on travis which is pretty slow: |
Ok it was still running after 2 hours so I closed the browser window and it finally moved on. Here are the results:
Much better than before, but not sure why that test froze |
Does it manage to open 2 firefox windows ? "double" tests should spawn a second window. |
Yes I think there's one point where there's more than one window open. However, I already had FF open when I was running the tests and perhaps this situation affects the tests. I thought I saw some commands the first time I ran that test that looked as if a new FF profile was being created but it doesn't seem to be the case looking at Process Explorer. I have too many tabs open and don't want to close them yet but I guess I should try it again sometime when I have no tabs open. |
Selenium should create a new profile per test, so your current session On Thu, Apr 4, 2013 at 3:58 PM, yscumc notifications@github.com wrote:
http://yourlabs.org http://blog.yourlabs.org |
Ok I guess that wasn't the issue then. It doesn't bother me that the test failed though as long as it works normally so I'll just leave it as is unless you want to look into it and want more info. |
I have nothing against windows, but it doesn't like me very much so I try On Thu, Apr 4, 2013 at 4:46 PM, yscumc notifications@github.com wrote:
http://yourlabs.org http://blog.yourlabs.org |
Haha understood |
Did you try again with recent selenium, firefox and django updates ? Maybe tests will run better on windows nowadays ... |
Hi @yscumc, Did you find a solution ? Thanks |
Thanks for the follow up. Unfortunately I haven't found a real solution for the actual problem. I did find a solution for our specific case though; after the programmer who wrote the long running request left, I just modified it to poll at an interval instead lol. Regarding the testing with selenium, sorry I forgot to reply. I meant to try it again and get back to you but I haven't gotten around to it yet and I'm not sure there would be time to in the near future. |
Did you try just calling It worked for #38 |
Nope I haven't, but I doubt it would work in this case. If I remember correctly, the problem was due to Django persisting the session data to the db at the END of the request. The long running request, which is started early, will overwrite the session data from the later requests, even if the later requests indicate activity. In #38, the user doesn't move the mouse because the main interaction with the page is listening to the audio. Therefore, no activity indication was sent to the server. In this case, the user actually moves the mouse during the long running requests and sends off activity data to the server. However, when the long running request returns, it overwrites all the previous session data, leading the next request to trigger the logout response. Unfortunately, I'm not sure there can be a fix for this, as it's an inherent behavior of how Django handles the session data. If there's a way to flush the session data periodically during the long running request, that should fix the problem. |
On Wed, Feb 11, 2015 at 5:05 PM, yscumc notifications@github.com wrote:
http://yourlabs.org http://blog.yourlabs.org |
I don't think this would work either, though I'm less certain this time. Django writes all the session data encoding in a single string as However, this is all conjectures so maybe it'll behave differently? |
I was thinking:
Would that work ? On Wed, Feb 11, 2015 at 5:40 PM, yscumc notifications@github.com wrote:
http://yourlabs.org http://blog.yourlabs.org |
It's alright if you can't test it, as long as this proposal looks good enough for you then we can close this issue ;) |
Unfortunately, I don't think that would work. Sorry if I wasn't clear in my explanation before but I have interpreted it as you have said and based on what I've seen and tried previously, I do not believe it would work. From my understanding, Django writes the entire encoded session dict to the database at the end of the request, regardless of whether you have manually changed the last activity information in that request or not. PASSIVE_URL only prevent session_security from processing the request, but it does not prevent the regular Django session handling. Therefore, session_security's last activity information will get overwritten with stale data at the end of the long request, because the entire session data is overwritten. Now I have not tested this hypothesis directly, so I am not 100% certain this is the case, but at the time I encountered this problem, I did a bunch of testing on this issue and this was my conclusion. It seems to be an inherent problem in the way Django handles the saving of session data and the only way I can think of to fix this is to somehow tell Django to update the session data to/from the database periodically before the end of the long request so that it will share the data more nicely with other concurrent requests. I believe the root of this issue is actually a concurrency problem. I don't have any qualms about this issue being closed as I have worked around it, but it could still be an issue for others. But from the lack of activity on this issue, it looks like this is a rare problem that no one else encountered. It would probably be a good idea to document this known problem somewhere if you wish to close this issue. |
I just did a quick search and it looks like this issue is known by Django: #10760 Some session data gets lost between multiple concurrent request Unfortunately, it seems there's not much love on this issue since it doesn't affect most people :( |
Perhaps #75 fixes this |
The app utilizes too many database connections. In my project when I use Django-security-session and log in to my project, there are at least 8-7 idle connections. I'm using Django 1.11 with Postgres as my DB |
Using:
Firefox 19.0.2 with Firebug
Django (1.5)
django-session-security (2.0.3)
Problem:
If there's a long running request, the last activity stored in
request.session['_session_security']
is immediately set during the beginning of the request, but it is not returned to the client browser until the request is completed 45 seconds later. Since the session values are stored as cookies on the client side, all the ping requests during this 45 seconds which updated the last activity will be overwritten.When the long running request is finally completed, the last activity stored in
request.session['_session_security']
will be set to 45 seconds ago. If the next request is to the ping view, then all will be fine as the ping view updates the last activity. However, the the request request is another long running request, or something else which does NOT have theidleFor
parameter (which means anything other than the ping request), thendelta.seconds
would be larger thanEXPIRE_AFTER
andlogout(request)
would be called. Any subsequent ping requests would return "logout" as a response, although the page the user is viewing would not immediately be logged out.To reproduce:
Settings for session_security
SESSION_SECURITY_WARN_AFTER = 10 # Default 540
SESSION_SECURITY_EXPIRE_AFTER = 30 # Default 600
SESSION_EXPIRE_AT_BROWSER_CLOSE = True
Here's an example of the requests to the ping view found from Firebug
First Request
Second Request, after long running request finished and started again
Two things are wrong here:
The text was updated successfully, but these errors were encountered: