3

I have a pretty straightforward question, but I haven’t found a very straightforward answer: When should I use start_background_task() over starting a Python thread “normally”? Flask-SocketIO documentation states:

This function returns an object compatible with the Thread class in the Python standard library. The start() method on this object is already called by this function.

It doesn’t say much about whether it’s necessary to use this over initializing and starting a thread per the threading module.

star8163264
  • 148
  • 2
  • 8

1 Answers1

7

The reason start_background_task() exists is that depending on what web server you use the threading model changes. For example, if you are using eventlet or gevent, then a background task needs to be started as a greenlet, not as a Thread instance.

If you use start_background_task() you will be guaranteed that a task object that is compatible with your environment will be used.

Miguel Grinberg
  • 65,299
  • 14
  • 133
  • 152
  • So if I am using eventlet, is it that I shouldn’t be using Thread instances at all, or I shouldn’t use Thread instances when I am going to be running a background task that performs actions such as emit? In other words, is it safe to use a Thread instance to do some sort of I/O on the server completely unrelated to client-server connection? – star8163264 Jun 17 '20 at 18:55
  • Normally an eventlet application does not use regular threads at all, because it is very difficult to make a normal thread interact with the eventlet server without blocking it. – Miguel Grinberg Jun 17 '20 at 21:47
  • So do you recommend being careful about which modules you import in case they may use Thread instances as well? In my case, I was wondering because I have an app running just locally for me that saves data to a text tile, and I have that save operation happening on a Thread instance. I haven’t noticed any problems and I’ve been running it for a while. I also never join that thread back to the main thread. I’m not sure if that makes a difference. If it’s a problem, would I have to pass the SocketIO object to any other custom module I create if I want that module to run background tasks? – star8163264 Jun 17 '20 at 23:40
  • 1
    If your thread just does some work on its own and never communicates with the rest of the application, I think it will not cause problems. For the case of using code that starts threads, eventlet provides the monkey patching option, which adapts the `Thread` class to use greenlets. See https://eventlet.net/doc/patching.html. – Miguel Grinberg Jun 18 '20 at 09:51
  • By communicating with the rest of the application, what do you mean? My understanding right now is that if your task will be communicating with the client, a greenlet is necessary. But what about the case when you grab data from a different API/URL. Is a normal thread safe to use, as long as that thread itself isn’t going to be sending data directly to the client? Essentially, I’d like to know when it’s absolutely necessary to use greenlets. – star8163264 Jun 18 '20 at 17:10
  • I actually just ran through some test cases and found that if anything, using a Thread over the socketio background task function makes blocking less likely, even if I emit data in a continuous loop. Maybe this is out of scope of the question I asked, but I’m just not quite sure what issues it could be causing when I use the threading module. – star8163264 Jun 18 '20 at 18:47
  • 1
    The communication thing I mentioned is when this background thread needs to interact in any way with the eventlet thread. If the thread is independent, then it should be fine. If it needs to coordinate or pass data to the eventlet side then you will probably run into issues. – Miguel Grinberg Jun 18 '20 at 22:35