-
Notifications
You must be signed in to change notification settings - Fork 0
gotcha with rack cache
А всегда ли добавление Rack::Cache увеличивает (или хотя бы не портит) производительность?
Рассмотрим такой случай:
-
есть сайт с картинками в обычных .jpg файликах
-
эти .jpg отдаются рельсами (нам это нужно из соображений красивых урлов или из-за авторизации - не столь важно)
-
догадываясь, что напрягать рельсо-сервер отдачей статики не есть хорошо, мы используем send_file
expires_in 1.year
if stale? :last_modified => File.mtime(path), :public => true
send_file path, :type => File.mime_type(path), :disposition => 'inline'
end
Все работает неплохо, картинки отдаются ngnix'ом через X-Accel-Redirect, кэшируются в браузере - девелопер почти счастлив.
Но теперь добавим сюда Rack::Cache (он нам нужен для каких-то других
страниц). Так как наши респонсы с картинками проходят через rack-cache
и имеют заголовок Cache-Control: max-age=..., public
, он их пытается
сохранять и использовать.
Проблема возникает, когда юзер, не имеющий копии картинки в кэше бразуера, обращается за сохраненным в rack-cache образцом. В этом случае действия библиотеки, в конце концов, сведутся к
File.open(path, 'rb') { |io| Marshal.load(io) }
path
в данном случае - путь к сохраненной в tmp/cache/
копии
Marshal.load
- вызов СИшной библиотеки, занимающейся сериализацией
То есть, вместо того, чтобы просто сказать фронтенду "отдай-ка юзеру вооон тот файлик" (X-Accel-Redirect), rack-cache открывает файл, читает его, десериализует и радостно отдает через рельсо-сервер.