Understanding multiple web workers and multiple users of your website

Over the years, we’ve found that one regular source of confusion for people who are just getting started with web development is how to handle what we call “global state”. We’ve written a help page explaining how to solve problems like this and wanted to expand on it here.

The problem

Keeping stuff separate

You might have lots of different people accessing your website, and you want to display different sets of consistent data to them – user A sees all of their stuff, user B sees their stuff, and user C their stuff. Let’s say it’s a to-do list – each user should see all of their own to-do items, and not anyone else’s.

In a simple Python script that each user runs for themselves on their own computer, that’s easy enough – because each person has their own copy of the script running, you can just use variables. For example, a to-do list script might have a global list called to_do_items.

But for a website, you only have one copy of the script running on our servers, handling requests for all of your users – so how do you keep everyone separate?

But not too separate!

For larger websites, there’s a different – but related – problem.

Let’s say you solved the problem of keeping data for different users separate, but were keeping the data inside variables in your website’s process. Maybe you use a dictionary keyed on the user ID, with the value being a list of to-do items for the user in question.

If you upgrade your account on PythonAnywhere so that it can handle more traffic, we provide that extra power by having different instances of your website’s code (we call them “workers”) running. But that means that you have different variables in each worker, so you could wind up in a situation where user A makes a request to your site and sees the data from one worker, but on the next request they see the data from another.

Let’s take that to-do list example again – they make a request to your site to see their list of to-do items, and get a response from worker 1. They add an item, and that “add” action gets routed to worker 2. Then when they view the list again, if the view request goes to worker 2 they will see the added item, but if it goes to worker 1, they will not.

What you want is to be able to provide different users of your site their own separate – but consistent – view of their data over time.

The solution

To address all these questions we have a new help page about “Global State and Web Apps”.

Of course, it can be hard for a beginner to know what the problem they’re having is related to this kind of thing. So that this blog post becomes a good result for the kind of problem that people actually search for, here are some examples of problems that were related:

Global variables in website code

People have asked on our forums about global variables in Flask, global variables issue, and global variables shared among users.

Similarly on Stack Overflow, people have posted about similar problems: how to share state in bottle, how to deal with global variables in python flask web app or data across clients is not separating.

Inconsistent results in websites

One of the very first threads on our EU forums was the result of someone getting inconsistent results when they kept their data for a multi-worker website in a global variable. There has also been a post in our US forum.

But people have also hit similar problems with webhook-based Telegram bots.

That’s it!

Thanks for reading :-) We’re planning to publish more here about new help pages we create for common problems, and any suggestions would be much appreciated.

Do you want to improve one of our help pages? You can submit a pull request! There are more than 40 authors who have contributed to our help pages so far.

comments powered by Disqus