Tricky issue with django sessions: sometimes session information is erased - django

I have a weird bug with django sessions in my app: some times (about 10 times for ~20000 per day) session information for user is erased. I traced it via log files: at page A there is information for user's session, after it he submits the form and at the next page his session is empty. I tried two types of storage: memcached+db and db only and this problem is for both of them. I tried to reproduce these scenarios, but all works as expected, as I said, it happens very rare. I also checked that this problem exists for different users, and for them is doesn't reproduce each time. I don't have any ideas how to catch the root cause and I don't know what else post here as a description. If someone has any ideas, please let me know. If it is important, I'm running my app with django 1.2 + FastCGI.
Thanks!
UPD: I checked and see that session key from uses is not changed during two sequential requests, at first request there is an actual session state, and at second session variables are relaced with empty.

As a way to debug this problem, I would subclass the standard Django session middleware (or whatever you're currently using):
django.contrib.sessions.middleware.SessionMiddleware
and wrap process_request and (probably more importantly) process_response in some extra logging. Then install your subclassed session middleware in the MIDDLEWARE_CLASSES, rather than the stock Django one.
You could also validate that session.save() has actually committed its changes by attempting to read it back. It could be that the problem lies in session-state serialisation, and it's failing on a particular key or value that you're attempting to store.
None of this will fix your problem, but it might help you to establish what's going on.

As #Steve Mayne mentioned, it would be good to do some logging on the sessions middleware and sessions model save method. That's something I'd start with.
In addition I'd like to say that this could be a database related issue, especially if you're using MySQL database backend for sessions. You can check the log for database locks and other concurrency issues. I had to deal with similar issues before and the solution is clear: optimization and additional performance.
If you have some specific application middleware, you can check for functionality that interferes with Django sessions. Such parallel operations can cause problems, if not implemented properly.
Another thing I would do is to upgrade to the latest stable release of Django and migrate to a mod_wsgi setup.

Related

Login and template errors deploying meteor to Digital Ocean / modulus.io

Apologies if this question is not asked correctly but I actually can't pinpoint the problem. Hence the lack of code in the question itself. I'm struggling with this error so please go easy on me....
I was developing a meteor app locally without too much difficulty. It seems to run well on localhost. But then I decided to deploy it and have been running into some problems as outlined below. I have deployed the app "successfully" using both mup/DO and modulus.io (with compose hosting the DB in both instances) and whole thing sort of works, but...
You can register fine but when you try to log in the button doesn't work...press it again and you login but the usename and password are in the URL... how does this happen?
When you login you can begin by creating a supplier, then create products for that supplier. Only thing is the suppliers are saved to the DB and they are in the product count but they are nowhere to be seen in the middle section page.
Once you create a new supplier, the add new products for the existing suppliers is no longer accessible.
I am so confounded that I don't know what code to put up so I'm giving access to my codebase - it's on github here and this is the modulus site here. Go ahead and register and you can see for yourself.
You will easily be able to see the errors in the console when you start trying to log into the site so there is no point in posting them here.
Many, many thanks in advance guys.
I have reviewed your code and I don't think that the errors occur due to the deployment.
Here's a list with a few suggestions that should help you to fix your code:
In your /client/helpers/config.js file, you try to configure the behaviour of {{> loginButtons}}. That does not make any sense, since you do not have the accounts-ui package installed.
The /client/templates/includes/header.html file references with pathFor to homepage. This route is currently not available in your /lib/router.js.
Users are able to access the /loggedIn path even if they are not logged in. Furthermore, you always redirect users to this path if the submit form event in the register template occurs. This means, they can easily bypass the registration just by clicking on the submit button.
Watch your console logs. There are a lot of template helper exceptions.
Unfortunately, I could not check the login bug you described, because I received an exception when invoking the submit event. I recommend to use a rather defensive programming approach, you should at least check if the variable's value is not undefined and if it is, then you should handle those situations accordingly.
For example, in your /client/templates/includes/login.js file, you have the following code:
var userId = Meteor.userId();
var supplier = Suppliers.findOne({userId: userId});
var supplierId = supplier._id;
This will raise an exception if supplier is undefined.
All in all, you should rethink your release planning and deployment, since your app is far from working. Furthermore, please try to break your issue into chunks next time and provide a clear problem statement, because your question won't be useful to other readers without it.

Flask Login Sessions Not Working

I'm having an issue with Flask-Login where for some reason it seems to clear the data from my session. This issue only seem to happen to me when I run my application on AWS within a Docker container. There doesn't seem to be any issues when this is run locally within a Docker container. The container kick starts the application using supervisord to launch the nginx and gunicorn servers.
I'm using Flask-Login and SQLAlchemy to handle my user logins. I'm creating a custom token using the get_auth_token() method in my User model which stores the token with some session data in my database. I use the token_loader and user_loader callbacks to retrieve my User data from the database which works fine.
However, if I'm not actively using my application for a few minutes the session data seems to disappear when I change to a page that requires a login. My session cookie remains unchanged and my token_loader or user_loader callbacks never seem to be called. To work out what might be happening with the session I attached a #app.before_request handler to print the session contents:
[2015-09-29 14:47:21,348] DEBUG in __init__: <SecureCookieSession {u'csrf_token': '51b5b253c55ac954c1bc61dd2dca513e18c4d790', u'_fresh': True, u'user_id': 3, u'_id': 'd3adbd2ed3905986d515aeb04cd1ff7d'}>
[2015-09-29 14:47:21,382] DEBUG in __init__: <SecureCookieSession {u'_flashes': [('message', u'Please log in to access this page.')]}>
It appeared that all of the user information was there for me to be able to load my user but it has bailed out and re-directed to the login page with the Flask-Login flash error. This re-directs before it even touches my callbacks to load the user from the database.
Is this possibly just a set up issue with my server configs that is causing an issue with domains? I'm not really sure what I need to look at and try to debug this further.
This is a known bug in Flask-Login that was fixed around release 0.2.10 (by me). The bug reappeared in release 0.3.0 of Flask-Login, which as of today is the most current release. I submitted a new fix, plus a unit test to prevent this from ever happening again. The fix was merged a few days ago, but a 0.3.1 release has not been made yet.
Bug report: https://github.com/maxcountryman/flask-login/issues/231
My pull request with the fix: https://github.com/maxcountryman/flask-login/pull/237

Django - Runtime database switching

In my work we want to run a server with multiple databases. The databases switching should occur when you acces a url like http://myapp.webpage.com or http://other.webpage.com. We want to run only one server instance and at the moment of the HTTP request switch the database and return the corresponding response.
We've been looking for a mantainable and 'Django-friendly' solution. In our investigation we have found possible ways to do this, but we have not enough information about.
Option 1: Django middleware
The django middleware runs each time the server receive a HTTP request.
Making a database switch here could be the best option but using django database routers as far as I know only allow to change the database for a model or group or models.
Another option is to set a django model manager instance in the middleware and force all models to re-assign the objects attribute from an added attribute in the custom middleware.
My last option is to create a new attribute in the request object received by the middleware that return the database alias from settings.py and in each model query use the using method.
Option 2: Class-based View Mixin
Create a mixin that use the past three options, but I the mixin must be set in ALL the Class-based views. If a programmer forget to set the mixin and it comes to a production server, the data could be (or stop being) in the right database, and I don't wanna take the risk.
Option 3: Changing the database settings in runtime
This option works but Is not recommended and is too risky.
UPDATE:
How this works?
middlewares.py
import django.conf as conf
import os.path
class SelectDB(object):
def process_request(self, request):
print request.META['HTTP_REFERER']
file_database = open("booklog/database.txt", "r")
database = file_database.read(10)
file_database.close()
if database != 'default':
conf.settings.DATABASES['default']['NAME'] = database
Any information that help us to solve will be greatly appreciated.
Answer (it worked for me)
The question was already answered here, in stackoverflow. I'd love this functionality were in django. It was a bit hard to find the way to make this possible.
I think that is important to comment the great work that Wilduck made with the django plugin django-dynamic-db-router, it's a great plugin that makes possible this operation in (a bit) different way.
Thanks a lot to #JL Peyret and #ire_and_curses.
And as an answer to #ire_and_curses. At least in this moment, in the project I'm working it's what we need. In previous projects we needed a similar behavior and made one server per instance was terrible to mantain and update each server, even automating the process.

Why Django blocks simultaneous requests within the same session?

I tried to add sleep(30) at the first line of my view. After that I opened this page in two browser tabs. The first tab loaded the page after 30 seconds, and the second one loaded it in 60 seconds. In the meantime I was able to open pages from another pc just fine. So it looks like Django blocks the concurrent requests from the same client.
This is very well for my app. And I'd like to be sure my site will work this way in the future. However I have not found any documentation or articles describing such Django behaviour. So I'm still not sure if this is a feature or just fortune. Could somebody please explain how and why this works?
What I actually need is to block the session while view is processing. Of course I can use some flags or db transactions. But I'd not like to add a feature that is already implemented in Django.
I use python 2.6.5, django 1.4, ubuntu server, nginx and uwsgi. Tried both postgresql and sqlite.
My uwsgi settings:
<uwsgi>
<pythonpath>/home/admin/app/src</pythonpath>
<app mountpoint="/">
<script>deploy.wsgi</script>
</app>
<workers>4</workers><!-- Not sure this is needed -->
<processes>2</processes>
</uwsgi>
I also got same effect with runserver command.
Actually Django does not block simultaneous requests.
If I run two browsers (for example chrome and firefox) with the same session (by copying the sessionid cookie from the first browser to the second one), blocking does not happen. So, this is a browser feature, and it's not related to Django anyhow. This means I still need to add some blocking feature by myself to make the code safe.

Using nginx/fcgi/django, I have form posts that give a 504 gateway time-out

I have an app that uses Django with FCGI on nginx. I'm using the third-party apps like James Bennett's django-registration and django-messages from the Pinax Project. Both of these apps have forms that are submitted and save data into the database, then redirect on to a new URL.
My issue seems to be that the .save() method on any of the forms in these apps cause a 504 gateway time-out when the forms are submitted. All of the data is saved in the database as it should be, however neither seems to ever return anything to the app after the form is saved.
I've done some logging at various points in the code and there are no errors. It's as if the save() methods on the form or the models the forms are connected to simply never return anything--error or otherwise.
With this lack of detail, an answer might be a dream for me, but just a nudge in the right direction or a way to diagnose the issue more completely would be fantastic.
Typically 504's in nginx happen due to timeout between nginx and the fastcgi process. You may want to take a look at your nginx settings and up the fastcgi_read_timeout setting?
Your nginx error log will typically provide a bit more information as to why things are not working as well. If you're on a *nix distro it's typically in "/var/log/nginx/error.log"
Turns out the problem was completely unrelated to nginx, but was Django having a timeout when trying to send an email. Unfortunately, it doesn't drop an error message or any indication that it can't connect to the email server.