Какие есть хорошие способы сделать асинхронное веб-приложение на ruby ​​в наши дни?

Я собираюсь создать веб-приложение с компонентом WebSocket и запустить внешний интерфейс на основе стоек. Мой первоначальный план состоял в том, чтобы использовать Camping для внешнего интерфейса, запустить сервер на тонком, со стойкой config.ru выглядит так:

require 'rack'
require './parts/web-frontend'
require './parts/websocket'

AppStationary = Rack::File.new("./stationary")
run Rack::Cascade.new(AppWebSockets, AppWebPages, AppStationary)

AppWebSockets предоставляется websocket-rack и отлично работает. В отсутствие Upgrade: WebSocket запросить его просто 404 и запрос бежит вниз по каскаду к приложению кемпинга, AppWebPages,

Становится ясно, что этому веб-приложению для кемпинга неизбежно требуется доступ к IO, чтобы общаться с базой данных CouchDB с помощью регулярных http-запросов. Существует множество способов выполнения http-запросов, в том числе некоторые асинхронные библиотеки, совместимые с eventmachine. Если я подписываюсь на обратный вызов, стойка возвращается, и страница уже отвечает к тому времени, когда я готов создать ответ. Я хотел бы иметь возможность использовать em-synchrony для получения некоторого параллелизма через волокна Ruby 1.9 - о которых я только что подумал - но не могу найти никакой документации о том, как использовать em-синхронность с Thin,

Я столкнулся с веб-сервером под названием Goliath, который утверждает, что он похож на thin, с встроенной поддержкой em-synchrony, но в нем отсутствует утилита командной строки для запуска и тестирования сервера, и, похоже, требуется, чтобы я записал файл другого типа в рэкап, который довольно неприятен. Также неясно, будет ли он поддерживать websocket-rack, который в настоящее время указывает только на поддержку Thin.

Какие есть хорошие способы избежать блокировки ввода-вывода, в то же время используя знакомые инструменты на основе стоек, такие как кемпинг, и имея доступ к WebSockets?

3 ответа

Решение

Вот пример того, как добавить асинхронную поддержку в Camping: https://gist.github.com/1192720 (см. 65 для кода, который вы должны будете использовать в своем приложении). Может быть, мы должны завернуть это в драгоценный камень или что-то...

Что касается Голиафа, Голиаф основан на Thin (я начал с тонкого кода и когда оттуда). Большая часть кода изменилась (например, с использованием http_parser.rb вместо парсера mongrel), но исходной основой был Thin.

Запуск сервера - это всего лишь вопрос запуска вашего файла.rb. Система такая же, как в Sinatra (я позаимствовал код у Sinatra, чтобы он работал). Вы также можете написать свой собственный сервер, если хотите, в репозитории есть примеры, если вам нужен дополнительный контроль. Для нас мы хотели, чтобы запуск был максимально простым и требовал как можно меньше создаваемых файлов. Итак, запуск файла.rb и использование Бога для запуска / перезапуска серверов работали хорошо.

Тесты, которые вы пишете с помощью RSpec/Test::Unit и запускаете тестовый файл, как обычно. Тесты для Голиафа запустят реактор и отправят реальные запросы API от ваших модульных тестов (обратите внимание, что это не форк, он использует EM для запуска реактора в том же процессе, что и тесты). Все это упаковано в test_helper, который предоставляет Голиаф.

У Голиафа нет файла рэпа. Вы запускаете файл.rb напрямую. В приложении Голиафа есть команды использования промежуточного программного обеспечения, встроенные прямо в файл.rb. Для нас в PostRank это был самый простой и понятный способ определения сервера. Все ваши операторы использования (с любыми дополнительными битами, которые они используют) были видны во время работы с файлом, а не с несколькими файлами. Для нас это была победа, ваш пробег может отличаться.

Я понятия не имею, будет ли работать websocket-rack, но в репозитории есть ветка для отправки поддержки websocket прямо в Голиафа. Я не смотрел на это некоторое время (были исправлены некоторые вышестоящие ошибки, которые требовались), но его не должно быть слишком сложно, чтобы его запустить и запустить и, с исправленным вышестоящим, слить в master.

На ваш вопрос о em-synchrony и thin у вас должна быть возможность обернуть блок EM.synchrony {} вокруг кода. Метод syny просто вызывает EM.run и оборачивает ваш блок в новое волокно. Если реактор уже работает, EM просто немедленно выполнит пройденный блок. Пока Тонкий уже запустил реактор, он должен работать нормально.

Обновление: ветвь websockets была объединена с основной линией Голиафа, так что есть поддержка WebSocket, встроенная прямо в Голиафа, если вы работаете с HEAD.

Вы смотрели на Cramp - http://cramp.in/? Cramp полностью асинхронен и имеет встроенную поддержку веб-сокетов.

Другие вопросы по тегам