Тайм-аут ActiveResource не работает - PullRequest
0 голосов
/ 16 июля 2009

Я пытаюсь связаться с REST API, используя ActiveResource на Rails 2.3.2.

Я пытаюсь использовать функцию тайм-аута, чтобы, если ресурс, с которым я контактирую, не работал, я мог быстро потерпеть неудачу - я делаю это со следующим:

class WorkspaceResource < ActiveResource::Base
  self.timeout = 5
  self.site = "http://mysite.com/restAPI"
end

Однако, когда я пытаюсь связаться со службой, когда я знаю, что она недоступна, класс истекает только через 60 секунд по умолчанию. Я могу видеть из стека ошибок, что ошибка тайм-аута действительно происходит из класса ActiveResource в моей папке gem, который имеет надлежащие функции для разрешения настроек тайм-аута, но мой установленный тайм-аут никогда не работает.

Есть мысли?


Так что, очевидно, проблема не в том, что тайм-аут не работает. Я могу запустить сервер локально, сделать так, чтобы он не возвращал ответ в течение срока ожидания, и посмотреть, как работает тайм-аут.

Проблема в том, что если сервер не принимает соединение, тайм-аут не работает так, как я ожидал - он вообще не работает. Похоже, что тайм-аут работает только тогда, когда сервер принимает соединение, но слишком долго, чтобы ответить.

Мне кажется, это проблема - не должен ли работать тайм-аут, когда сервер, с которым я связываюсь, не работает? Если нет, то должен быть другой механизм, чтобы остановить зависание множества запросов ... кто-нибудь знает быстрый способ сделать это?

Ответы [ 3 ]

1 голос
/ 25 июля 2009

Собственно сам узнал ответ, обсуждая в другой ветке здесь:

Переопределение / изменение класса Rails (ActiveResource)

0 голосов
/ 17 мая 2017

В качестве альтернативы, вы можете попытаться перехватить эти ошибки соединения и повторить попытку один раз (через определенный промежуток времени), чтобы убедиться, что соединение действительно установлено.

      retried = false
      begin
        @businesses = Business.find(:all, :params => { :shop_domain => @shop.domain })
        retried = false
      rescue ActiveResource::TimeoutError => ex          

      #raise ex

      rescue ActiveResource::ConnectionError, ActiveResource::ServerError, ActiveResource::ClientError => ex
        unless retried           
          sleep(((ex.respond_to?(:response) && ex.response['Retry-After']) || 5).to_i)
          retried = true             
          retry
        else              
          # raise ex
        end
      end

Вдохновлен этим решением от Shopify для разбиения на страницы большого количества записей. https://ecommerce.shopify.com/c/shopify-apis-and-technology/t/paginate-api-results-113066

0 голосов
/ 16 июля 2009

проблема

Если вы работаете на Ruby 1.8.x, то проблема заключается в отсутствии реальных системных потоков.

Поскольку вы можете прочитать сначала здесь и , а затем здесь , в Ruby есть системные проблемы с таймаутами. Интересная дискуссия, но для вас, в частности, некоторые комментарии показывают, что время ожидания эффективно игнорируется и по умолчанию составляет 60 секунд - именно то, что вы видите.


Решения ...

У меня похожая проблема с нашим собственным продуктом при попытке отправить электронную почту - если почтовый сервер отключен, блокируется. Для меня решением было выделить запрос в отдельном потоке, и поэтому мой основной поток обработки запросов не блокируется.

Существуют неблокирующие библиотеки для Ruby, но, возможно, вы могли бы сначала взглянуть на этот System Timeout Gem .

Опция, открытая для всех, кто использует Rails за прокси-сервером, таким как nginx, будет заключаться в том, чтобы установить таймаут восходящего потока на меньшее число - таким образом вы будете получать уведомления, если сервер слишком долго. Я бы сделал это, только если бы я действительно застрял в решении.

И последнее, но не менее важное: вполне возможно, что запуск Rails 2.3.2 поверх Ruby 1.9.1 решит проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...