Python bottle кэширование на стороне сервера - PullRequest
0 голосов
/ 03 мая 2020

Допустим, у нас есть приложение, основанное на Bottle, например:

from bottle import route, run, request, template, response
import time

def long_processing_task(i):
    time.sleep(0.5)      # here some more 
    return int(i)+2      # complicated processing in reality

@route('/')
def index():
    i = request.params.get('id', '', type=str)
    a = long_processing_task(i)
    response.set_header("Cache-Control", "public, max-age=3600")   # does not seem to work
    return template('Hello {{a}}', a=a)     # here in reality it's: template('index.html', a=a, b=b, ...)  based on an external template file

run(port=80)

Очевидно, будет http://localhost/?id=1, http://localhost/?id=2, http://localhost/?id=3, et c. занимает не менее 500 мс на страницу для первой загрузки .

Как ускорить последующую загрузку этих страниц?

Точнее, есть ли способ иметь оба:

  • кэширование на стороне клиента: если пользователь A посетил http://localhost/?id=1 один раз, то если пользователь A посещает эту страницу секунду время будет быстрее

  • кэширование на стороне сервера: если пользователь A посетил http://localhost/?id=1 один раз, то если пользователь B посещает эту страницу позже (впервые для пользователя B!), Она тоже будет быстрее .
    Другими словами: если 500 мс будет потрачено на генерацию http://localhost/?id=1 для один пользователь, он будет кэширован для всех будущих пользователей , запрашивающих ту же страницу. (есть имя для этого?)

?

Примечания:

  • В моем коде response.set_header("Cache-Control", "public, max-age=3600") нет похоже, работает.

  • В этом руководстве упоминается о кэшировании шаблонов:

    Шаблоны кэшируются в памяти после компиляции. Изменения, внесенные в файлы шаблона, не будут влиять, пока вы не очистите кэш шаблона. Для этого вызовите bottle .TEMPLATES.clear (). Кэширование отключено в режиме отладки.

, но я думаю, что это не связано с кэшированием последней страницы, готовой к отправке клиенту.

1 Ответ

1 голос
/ 05 мая 2020

Сторона сервера

Вы хотите избежать повторного вызова своей длительной задачи. Наивное решение, которое будет работать в малом масштабе, - это запоминать long_processing_task:

from functools import lru_cache

@lru_cache(maxsize=1024)
def long_processing_task(i):
    time.sleep(0.5)      # here some more 
    return int(i)+2      # complicated processing in reality

Более сложные решения (лучше масштабируемые) включают настройку обратного прокси (кэша) перед вашим веб-сервером.

Клиентская сторона

Вы можете использовать заголовки ответов , чтобы контролировать, как клиенты кэшируют ваши ответы. (См. Заголовки Cache-Control и Expires.) Это широкая топика c, со многими нюансами альтернатив, которые выходят за рамки ответа SO - например, есть компромиссы, связанные с запросом клиентов на кеширование (они выиграли не обновлять результаты, пока не истечет срок их локального кэша.)

Альтернативой кэшированию является использование условных запросов : используйте заголовок ETag или Last-Modified для возврата HTTP 304 когда клиент уже получил последнюю версию ответа.

Вот полезный обзор различных стратегий кэширования на основе заголовков .

...