Connection pooling

Requests use urllib3 under the hood, which will create one pool of connectors per host you are calling and reuse them when the code calls a host.

In other words, if your service calls several other services, you don't need to worry about recycling connections made to those services; requests should handle it for you.

Flask is a synchronous framework, so if you are running with a single thread, which is the default behavior, then the requests library's connection pooling doesn't help you much. Every call will happen one after the other. Requests should only keep one connector open per remote host.

But if you run your Flask application with several threads and have a lot of concurrent connections, these pools can play a vital role in making sure you're controlling how many connections are made to other services. You don't want your app to open an unlimited number of simultaneous connections to another service. It's a recipe for disaster.

Our HTTPTimeoutAdapter class can be used to control the growth of our pools. The class inherits from HTTPAdapter, which surfaces urllib3 pool options.

You can pass these options to the constructor:

  • pool_connections: This helps you figure out how many simultaneous connections are kept open.
  • pool_maxsize: This helps you figure out the maximum number of connections the pool handles.
  • max_retries: This helps you figure out the maximum number of retries per connection.
  • pool_block: This helps you figure out whether the connection pool should block connections and when the pool_maxsize is reached. If set to False, it will create new connections even if the pool is full, but not add them in the pool. If set to True, it will not create new connections when the pool is full and wait. This is useful to maximize the number of connections open to a host.

For example, our adapter could hold 25 simultaneous connections if the app is executed with a web server that allows multiple threads:

    adapter = HTTPTimeoutAdapter(max_retries=retries,
timeout=timeout, pool_connections=25)

Allowing multiple threads can be a great way to improve your service performances, but it comes with most significant risks. With its thread-local mechanism, Flask will ensure that each thread gets its version of flask.g (the global), flask.request or flask.response, so you don't have to deal with thread-safety, but your views will be visited concurrently by several threads, so you need to be careful about what's happening in them.

If you don't share any states outside flask.g and just calling the ;Request ;session, it should work. Request's session is not thread-safe you should have one session per thread.

But if you are changing any shared state and don't do the proper locking work to avoid race conditions, you will be in trouble. If your views get too complicated to make sure it is thread-safe, it's best to run with a single thread and spawn multiple processes. In that case, each process will execute a Request ;session that has a single connection to the external service, and that will serialize the calls.

This serialization is a limiting factor synchronous frameworks have, and it forces us to make deployments that consume more memory to spawn all the processes or use implicit asynchronous tools such as ;Gevent.

In any case, if the single-threaded application is fast to respond, it mitigates this limitation a lot.

One way to speed up your application for calls to other services, is to make sure it uses HTTP cache headers.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset