Использование Sinatra внутри Rails Metal
С версии 2.3 в Rails присутствует Rails Metal, который позволяет обработать запросы перед попаданием их в основное приложение. Для более удобного написания кода в Rails Metal можно использовать различные фреймворки, базирующиеся на Rack, в частности фреймворк Sinatra.
Сначала необходимо создать новый Rails Metal с помощью соответствующего генератора:
create app/metal/my_embedded_sinatra.rb
В результате получается следующий Rack обработчик:
require(File.dirname(__FILE__) + "/../../config/environment") unless defined?(Rails)
class MyEmbeddedSinatra
def self.call(env)
if env["PATH_INFO"] =~ /^\/my_embedded_sinatra/
[200, {"Content-Type" => "text/html"}, ["Hello, World!"]]
else
[404, {"Content-Type" => "text/html"}, ["Not Found"]]
end
end
end
Теперь вместо чистого Rack воспользуемся фреймворком Sinatra, для этого добавим в config/environment.rb подключение гема sinatra:
Содержимое файла app/metal/my_embedded_sinatra.rb заменим на:
require(File.dirname(__FILE__) + "/../../config/environment") unless defined?(Rails)
class MyEmbeddedSinatra < Sinatra::Application
get '/sinatra_test' do
@message = 'Hello from Sinatra'
erb :test_view
end
end
Благодаря этому ссылка /sinatra_test будет обрабатываться с помощью Sinatra. Создадим простой шаблон test_view.erb в директории app/metal/views и выведем там переменную @message:
<body>
<h1><%= @message %></h1>
</body>
</html>
Запускаем Rails приложение и открываем страницу http://наше_rails_приложение/sinatra_test, на которой будет выведен текст "Hello from Sinatra".
И напоследок небольшие тесты производительности (проводились с помощью ab на одном thin, запущенном в production окружении).
Sinatra Rails Metal, приведенный выше:
Time taken for tests: 2.360 seconds
Complete requests: 1000
Requests per second: 423.67 [#/sec] (mean)
Time per request: 23.603 [ms] (mean)
Time per request: 2.360 [ms] (mean, across all concurrent requests)
Обычный Rails контроллер, который делает тоже самое:
Time taken for tests: 5.387 seconds
Complete requests: 1000
Requests per second: 185.64 [#/sec] (mean)
Time per request: 53.866 [ms] (mean)
Time per request: 5.387 [ms] (mean, across all concurrent requests)
В результате получилось, что Rails Metal с Sinatra опережает по скорости обычный Rails контроллер в 2 раза. Соответственно, с помощью этой связки можно существенно понизить потребление ресурсов при обработке частых и несложных запросов.
Related posts: