SlideShare a Scribd company logo
1
Построение событийно
управляемого веб-сервиса
на Ruby
Онлайн: http://bit.ly/devconf-slides




Иван Касатенко

ivan@uniqsystems.ru
http://twitter.com/sky31338
13 игровых клубов                                                                        2


                               Клуб
                                4
                  Клуб                     Клуб
                   3                        5                       Асинхронная multi-
                                                                    master репликация
     Клуб                                              Клуб
       2                                                6



Клуб
                                                            Клуб    Централизованная
 1
                              Центр                             7      аналитика

 Клуб
  13                                                    Клуб
                                                            8

           Клуб                                                        Лучи добра
            12                                  Клуб
                                                  9
                       Клуб         Клуб
                         11           10
Внутри клуба                                                     3

                        Игровая консоль




                            XML-RPC
                                                         Нас 200




                          Сервер
                           клуба
                    C                     XM
               - RP                         L-
                                              RP
            L                                   C
          XM




                                                    Компьютер
Пианино
Превед, участнеги!                          4



Компьютер                          Сервер



              Начать сессию
                 (START)

            "Я тут,
                   что но
                          вого?"
                  (PIPE)


            Завершить сессию
                 (END)
Do you speak XML-RPC?                          5




<array>
  <data>
    <value><i4>1404</i4></value>
    <value><string>Что-нибудь</string></value>
    <value><i4>1</i4></value>
  </data>
</array>
Запрос авторизации                          6


                            Вернуть отказ



                                   нет


 Начать     Проверить
                               Все ОК?
 сессию   пароль и баланс


                                    да


                            Начать сессию




                               Вернуть
                            идентификатор
                                сессии
Запрос «я здесь»                                                 7

                                                         Уведомить об
                                                       окончании сессии


                                                                да
                                 30-секундный цикл

Начать             Проверить            Рассчитать        Кончились
запрос              баланс           остаток времени       деньги?



                                                          нет


                                                           Таймаут
                               нет                         запроса?



                                                                да

                                                       Вернуть баланс
         HTTP-соединение с клиентом                       и оценку
              поддерживается                            оставшегося
                                                          времени
Слишком много нитей!   8
Да придет Спаситель!   9
Ммм, спагетти...                               10

... или какие демоны ждут Вас в асинхронных закоулках


                                             «Спагетти-код»


Конец        Делай два       Делай раз




   Инвертированный поток выполнения




          Невыносимая боль
          тестирования
Да придет Спаситель 2!                               11




  Генератор             Потребитель
   событий                событий




              Элемент
              системы

                                 Раздел «Выделение
                                 событийно-
                                 управляемых
                                 абстраций»
Да придет Спаситель 2!   12




         Элемент
         системы
Да придет Спаситель 2!      12

      Модуль тестирования




           Элемент
           системы
Не стоит увлекаться...                       13

  ... или все ли стоит делать асинхронным?




    CPU-intensive вызовы



    Запросы, проводящие значительную
    часть времени в ожидании событий
Не стоит увлекаться...                       13

  ... или все ли стоит делать асинхронным?




    CPU-intensive вызовы



    Запросы, проводящие значительную
    часть времени в ожидании событий
Не стоит увлекаться...                       13

  ... или все ли стоит делать асинхронным?




    CPU-intensive вызовы



    Запросы, проводящие значительную
    часть времени в ожидании событий
И рыбку съесть, и   14


аквариум выпить
Асинхронный вызов                                                  15

                                         Ядро системы



                                               Проверка баланса
                      Баланс изменился




                                             Калькулятор времени
                     Остаток времени
                        изменился
Обработчик запроса



                                               Генератор пульса
                       Наступил таймаут




                                               XML-RPC сервер
                        Появился ответ
Синхронный вызов                                   16




Thread-обработчик                    XML-RPC сервер
                    Появился ответ
Есть, из чего выбрать...   17
Реализация сервера                                18



 Синхронный                       Асинхронные
 обработчик                       обработчики
  SyncExecutor                         Executor


          Обработчик XML-RPC
                 XMLRPC::BasicServer


             Приложение Rack
                 OmgServerFoundation



                       Thin
Server Foundation Gem                                                        19



               Executor                              SyncExecutor
+ handle(response_callback, параметры)   + handle(response_callback, параметры)
                                         + sync_handle(параметры)




# Инициализирует callback'и и            # Инициализирует callback'и, создает
# возвращает управление.                 # блок EM.defer и возвращает
def handle(response_callback, *params)   # управление.
                                         def handle(response_callback, *params)

                                         # Выполняется в отдельном треде
                                         def sync_handle(*params)
Синхронное плавание                                            20




class Auth < SyncExecutor
  def sync_handle(username, password, computer_number)
    return { :error => "Wrong password" } if username != 'test'
    session = Session.create(:login => login,
                             :computer => computer)
    return { :id => session.id }
  end
end
Асинхронное плавание                                     21


class Pipe < Executor
  include SubscriberRoutines

  attr_accessor :response_callback

  def handle(response_callback, session_id)
    self.response_callback = response_callback
    session = Session.find(session_id)
    subscribe_on_timeout(session)
  end

  def subscribe_on_timeout(session)
    subscribe_to(UnsubscribableTimer.on_timeout(30) do
      unsubscribe_from_everything
      self.response_callback.({ :result => "OK" })
    end)
  end
end
SubscriberRoutines                             22


module SubscriberRoutines
  def subscribe_to(unsubscribe_proc)
    raise "Not expecting a block!" if block_given?
    subscriptions << unsubscribe_proc
  end

  def unsubscribe_from_everything
    subscriptions.each { |s| s.() }
  end

protected
  def subscriptions
    @subscriptions ||= [ ]
  end
end
Генератор событий                                   23




class UnsubscribableTimer
  def self.on_timeout(time_period, &block)
    timer = EventMachine::Timer.new(time_period) { block.() }
    ->() { timer.cancel }
  end
end
Пришло ли счастье?          24



                             До:
                     37 клиентов до
                   100% загрузки ЦП




После:
500+ клиентов до
100% загрузки ЦП
Спасибо   25
26
         Отвечайте на мой
             конкретно
        поставленный ответ!

«Построение событийно управляемого веб-сервиса на Ruby»
                          Онлайн: http://slideshare.com/test123/bla


Иван Касатенко

ivan@uniqsystems.ru
http://twitter.com/sky31338

More Related Content

Similar to Построение событийно управляемого веб-сервиса на Ruby

Грамотная работа с дефект-трекером
Грамотная работа с дефект-трекеромГрамотная работа с дефект-трекером
Грамотная работа с дефект-трекером
Alexey Lyanguzov
 
Жизнь проекта на production советы по эксплуатации / Николай Сивко (okmeter.io)
Жизнь проекта на production советы по эксплуатации / Николай Сивко (okmeter.io)Жизнь проекта на production советы по эксплуатации / Николай Сивко (okmeter.io)
Жизнь проекта на production советы по эксплуатации / Николай Сивко (okmeter.io)
Ontico
 
Жизнь проекта на production
Жизнь проекта на productionЖизнь проекта на production
Жизнь проекта на production
Nikolay Sivko
 
CodeFest 2012. Корсаков С. — Cucumber. Некоторые советы по приготовлению
CodeFest 2012. Корсаков С. — Cucumber. Некоторые советы по приготовлениюCodeFest 2012. Корсаков С. — Cucumber. Некоторые советы по приготовлению
CodeFest 2012. Корсаков С. — Cucumber. Некоторые советы по приготовлениюCodeFest
 
Magento performance
Magento performanceMagento performance
Magento performance
aheadWorks
 
Другая виртуализация
Другая виртуализацияДругая виртуализация
Другая виртуализация
Yandex
 
20120218 model checking_karpov_lecture02
20120218 model checking_karpov_lecture0220120218 model checking_karpov_lecture02
20120218 model checking_karpov_lecture02Computer Science Club
 

Similar to Построение событийно управляемого веб-сервиса на Ruby (7)

Грамотная работа с дефект-трекером
Грамотная работа с дефект-трекеромГрамотная работа с дефект-трекером
Грамотная работа с дефект-трекером
 
Жизнь проекта на production советы по эксплуатации / Николай Сивко (okmeter.io)
Жизнь проекта на production советы по эксплуатации / Николай Сивко (okmeter.io)Жизнь проекта на production советы по эксплуатации / Николай Сивко (okmeter.io)
Жизнь проекта на production советы по эксплуатации / Николай Сивко (okmeter.io)
 
Жизнь проекта на production
Жизнь проекта на productionЖизнь проекта на production
Жизнь проекта на production
 
CodeFest 2012. Корсаков С. — Cucumber. Некоторые советы по приготовлению
CodeFest 2012. Корсаков С. — Cucumber. Некоторые советы по приготовлениюCodeFest 2012. Корсаков С. — Cucumber. Некоторые советы по приготовлению
CodeFest 2012. Корсаков С. — Cucumber. Некоторые советы по приготовлению
 
Magento performance
Magento performanceMagento performance
Magento performance
 
Другая виртуализация
Другая виртуализацияДругая виртуализация
Другая виртуализация
 
20120218 model checking_karpov_lecture02
20120218 model checking_karpov_lecture0220120218 model checking_karpov_lecture02
20120218 model checking_karpov_lecture02
 

Построение событийно управляемого веб-сервиса на Ruby

  • 1. 1 Построение событийно управляемого веб-сервиса на Ruby Онлайн: http://bit.ly/devconf-slides Иван Касатенко ivan@uniqsystems.ru http://twitter.com/sky31338
  • 2. 13 игровых клубов 2 Клуб 4 Клуб Клуб 3 5 Асинхронная multi- master репликация Клуб Клуб 2 6 Клуб Клуб Централизованная 1 Центр 7 аналитика Клуб 13 Клуб 8 Клуб Лучи добра 12 Клуб 9 Клуб Клуб 11 10
  • 3. Внутри клуба 3 Игровая консоль XML-RPC Нас 200 Сервер клуба C XM - RP L- RP L C XM Компьютер Пианино
  • 4. Превед, участнеги! 4 Компьютер Сервер Начать сессию (START) "Я тут, что но вого?" (PIPE) Завершить сессию (END)
  • 5. Do you speak XML-RPC? 5 <array> <data> <value><i4>1404</i4></value> <value><string>Что-нибудь</string></value> <value><i4>1</i4></value> </data> </array>
  • 6. Запрос авторизации 6 Вернуть отказ нет Начать Проверить Все ОК? сессию пароль и баланс да Начать сессию Вернуть идентификатор сессии
  • 7. Запрос «я здесь» 7 Уведомить об окончании сессии да 30-секундный цикл Начать Проверить Рассчитать Кончились запрос баланс остаток времени деньги? нет Таймаут нет запроса? да Вернуть баланс HTTP-соединение с клиентом и оценку поддерживается оставшегося времени
  • 10. Ммм, спагетти... 10 ... или какие демоны ждут Вас в асинхронных закоулках «Спагетти-код» Конец Делай два Делай раз Инвертированный поток выполнения Невыносимая боль тестирования
  • 11. Да придет Спаситель 2! 11 Генератор Потребитель событий событий Элемент системы Раздел «Выделение событийно- управляемых абстраций»
  • 12. Да придет Спаситель 2! 12 Элемент системы
  • 13. Да придет Спаситель 2! 12 Модуль тестирования Элемент системы
  • 14. Не стоит увлекаться... 13 ... или все ли стоит делать асинхронным? CPU-intensive вызовы Запросы, проводящие значительную часть времени в ожидании событий
  • 15. Не стоит увлекаться... 13 ... или все ли стоит делать асинхронным? CPU-intensive вызовы Запросы, проводящие значительную часть времени в ожидании событий
  • 16. Не стоит увлекаться... 13 ... или все ли стоит делать асинхронным? CPU-intensive вызовы Запросы, проводящие значительную часть времени в ожидании событий
  • 17. И рыбку съесть, и 14 аквариум выпить
  • 18. Асинхронный вызов 15 Ядро системы Проверка баланса Баланс изменился Калькулятор времени Остаток времени изменился Обработчик запроса Генератор пульса Наступил таймаут XML-RPC сервер Появился ответ
  • 19. Синхронный вызов 16 Thread-обработчик XML-RPC сервер Появился ответ
  • 20. Есть, из чего выбрать... 17
  • 21. Реализация сервера 18 Синхронный Асинхронные обработчик обработчики SyncExecutor Executor Обработчик XML-RPC XMLRPC::BasicServer Приложение Rack OmgServerFoundation Thin
  • 22. Server Foundation Gem 19 Executor SyncExecutor + handle(response_callback, параметры) + handle(response_callback, параметры) + sync_handle(параметры) # Инициализирует callback'и и # Инициализирует callback'и, создает # возвращает управление. # блок EM.defer и возвращает def handle(response_callback, *params) # управление. def handle(response_callback, *params) # Выполняется в отдельном треде def sync_handle(*params)
  • 23. Синхронное плавание 20 class Auth < SyncExecutor def sync_handle(username, password, computer_number) return { :error => "Wrong password" } if username != 'test' session = Session.create(:login => login, :computer => computer) return { :id => session.id } end end
  • 24. Асинхронное плавание 21 class Pipe < Executor include SubscriberRoutines attr_accessor :response_callback def handle(response_callback, session_id) self.response_callback = response_callback session = Session.find(session_id) subscribe_on_timeout(session) end def subscribe_on_timeout(session) subscribe_to(UnsubscribableTimer.on_timeout(30) do unsubscribe_from_everything self.response_callback.({ :result => "OK" }) end) end end
  • 25. SubscriberRoutines 22 module SubscriberRoutines def subscribe_to(unsubscribe_proc) raise "Not expecting a block!" if block_given? subscriptions << unsubscribe_proc end def unsubscribe_from_everything subscriptions.each { |s| s.() } end protected def subscriptions @subscriptions ||= [ ] end end
  • 26. Генератор событий 23 class UnsubscribableTimer def self.on_timeout(time_period, &block) timer = EventMachine::Timer.new(time_period) { block.() } ->() { timer.cancel } end end
  • 27. Пришло ли счастье? 24 До: 37 клиентов до 100% загрузки ЦП После: 500+ клиентов до 100% загрузки ЦП
  • 29. 26 Отвечайте на мой конкретно поставленный ответ! «Построение событийно управляемого веб-сервиса на Ruby» Онлайн: http://slideshare.com/test123/bla Иван Касатенко ivan@uniqsystems.ru http://twitter.com/sky31338

Editor's Notes

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n