I have an online shop with cart that stores its content in the request session.
While the server runs locally, it works smoothly and accuretly. The content of the cart remains the same for decades. But once the app is deployed, the cart’s ecosystem gets chaotic. After adding one product, it doesn’t appear in the cart. Reload the page - it’s there. Reload again - nothing. After a few reloadings the cart becomes utterly unpredictable.
It’s my first DRF API deployed, please help me figure it out, or suggest another way of handling carts, I know nothing.
This is most certainly happening because your session storage is not shared between your machines. So when you use one machine only, the session storage is kept on that machine and things are always there when pages load; it’s all served by the same machine.
When you add more machines, requests can get randomly distributed to each of your machines. Here’s the problem: if the user created their cart session with a request to machine A, but machine B serves the next request, it does not have the session information (since it’s in the session stored in machine A) and it can’t show the cart.
That’s generally the situation. As to how to solve it - by default Django stores session data in the database (How to use sessions | Django documentation | Django). So as long as your database is shared between your machines, this should just work . If it doesn’t just work, it’s likely your database is not shared between your machines.
How to achieve a shared database / data store is a relatively large topic, but for pointers, if you’re using SQLite you can probably leverage LiteFS (LiteFS - Distributed SQLite · Fly Docs). If you’re not using SQLite, you can look into using Postgres (Getting Started · Fly Docs).
Let me know if these pointers help you research a solution to “sharing data and state between machines” - that’s the underlying problem you’ll be trying to solve.
Thank you for your reply! Now I understand what is wrong, I think. I am using PostgreSQL through ElephantSQL, but it seems not to matter much, since I’ve tried storing sessions in different ways and yet the problem persists.
Do you happen to know some way of working around such a situation? I can’t yet see a solution that wouldn’t mean making registration obligatory for carts usage and thus storing them in the database…
Thank you again!
My app was running in 2 machines, so I had to destroy one of them. But it did’t do alone. Also I had to reduce the number of gunicorn workers from 2 to 1, both in Dockerfile and fly.toml. Now it works, even though not too fast.