1

We know that requests.Session keeps a single TCP connection alive for multiple HTTP requests/responses sent through it. But what happens when requests is patched by gevent.monkey?

Since we can concurrently launch multiple HTTP requests through a single session (which has not yet built any TCP connection with the target server), would these concurrently launched requests be delivered through multiple TCP connections? Then would the session always build a new TCP connection for any new request?

Then, with gevent and requests, what to do if I want to establish a limited number of TCP connections and keep reusing them concurrently? Does gevent.pool only limit the number of concurrently running greenlets, not the number of alive TCP connections?

With preliminary experiments on Windows, I found that gevent initializes new TCP connections if multiple requests are launched concurrently from a single session. An example test code is given below:

from gevent import monkey, pool
monkey.patch_all()
import gevent
import requests

s = requests.Session()


def launch_one_request(url='https://www.baidu.com'):
    s.get(url)


def launch_serial_requests(count=3):
    for i in range(count):
        launch_one_request()
        gevent.sleep(1)


p = pool.Pool(5)
tasks = [p.spawn(launch_serial_requests) for _ in range(10)]
gevent.joinall(tasks)
tasks = [p.spawn(launch_serial_requests) for _ in range(10)]
gevent.joinall(tasks)

With the code above, we can use Windows resource monitor to insepct that 5 TCP connections are established, corresponding to the pool size. No additional TCP connection is established during the 2nd run of tasks.

2474101468
  • 328
  • 2
  • 9
  • Please add the code you used to experiment with on Windows. – David K. Hess Jan 21 '22 at 14:53
  • Also, note that the requests library is not thread safe (https://stackoverflow.com/questions/18188044/is-the-session-object-from-pythons-requests-library-thread-safe). So, if you want to use the same session from multiple greenlets, you'll need to put your own locking and serialization around it. – David K. Hess Jan 21 '22 at 14:56
  • @DavidK.Hess Thanks for the advice! Experiment codes attached. – 2474101468 Jan 24 '22 at 02:27
  • Ok, this code is definitely very risky. You are trying to use the requests library in a multi-threaded fashion (use the same session in multiple greenlets) when requests doesn't support that. I think you have two options: 1) Allocate a session per greenlet or 2) use an actor model (google it) and serialize the requests to it on a Queue. – David K. Hess Jan 24 '22 at 13:49

0 Answers0