Rails с Memcache возвращает неправильный кешированный объект? - PullRequest
6 голосов
/ 09 апреля 2009

У меня довольно большое приложение на Rails, которое использует memcached на отдельном сервере в качестве хранилища кеша.

Проблема в том, что я случайно получаю ошибки в производственной среде, которые кажутся , указывающими, что memcached возвращает неправильный объект.

Примеры:

В этом примере current_site - это вспомогательный метод, который обращается к методу в модели Site, который использует Rails.cache для кэширования модели

ActionView::TemplateError in ListingsController#edit
undefined method `settings' for #<String:0xb565f8a0>

On line #12 of app/views/layouts/site.html.erb

    9:         <meta name="robots" content="noodp, all" />
    10:         <meta name="distribution" content="Global" />
    11: 
    12:         <% unless current_site.settings[:google_webmaster_verification_code].blank? %>
    13:         <meta name="verify-v1" content="<%= current_site.settings[:google_webmaster_verification_code] %>" />
    14:         <% end %>
    15: 

по сравнению с ....

ActionView::TemplateError in ApplicationController#not_found
undefined method `settings' for #<Category:0xd5c6c34>

On line #12 of app/views/layouts/site.html.erb

    9:         <meta name="robots" content="noodp, all" />
    10:         <meta name="distribution" content="Global" />
    11: 
    12:         <% unless current_site.settings[:google_webmaster_verification_code].blank? %>
    13:         <meta name="verify-v1" content="<%= current_site.settings[:google_webmaster_verification_code] %>" />
    14:         <% end %>
    15: 

Когда оба должны возвращать Site модель!

Еще один пример странного поведения кеша:

ActionView::TemplateError in AccountsController#show
can't convert Category into String

On line #141 of app/views/layouts/site.html.erb

    138:                    <li<%=  class="first" if i == 0 %>><%= link_to top_level_category.title, top_level_category.path %></li><% end %>
    139:                </ul>
    140:            <% end %>
    141:            <% cache bottom_pages do %>
    142:                <ul><% Page.top_level.active.show_in_navigation.find(:all, :include => :slugs).each_with_index do |top_level_page, i| %>
    143:                    <li<%=  class="first" if i == 0 %>><%= link_to top_level_page.title, top_level_page.path %></li><% end %>
    144:                </ul>

Кто-нибудь сталкивался с чем-то подобным раньше? У кого-нибудь есть мысли по диагностике этой неустранимой проблемы !? Я попытался отключить клиентские гемы memcached, подумав, что это странная ошибка, но это никак не повлияло! Спасибо.

Ответы [ 5 ]

10 голосов
/ 14 апреля 2009

Это было вызвано тем, что Passenger разделяет свое соединение с сервером Memcached. Чек http://www.modrails.com/documentation/Users%20guide.html#_example_1_memcached_connection_sharing_harmful.

Исправление было просто изменить Spawn на Rails на conservative.

1 голос
/ 18 ноября 2010

У меня тоже были эти проблемы, и было решено добавить require_dependency для каждого класса / модели перед демаршальной операцией провайдера кэша. Возможно, в производственной среде это не требуется, поскольку для параметра config.cache_class установлено значение true, но при тестировании и разработке - false.

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

В этом посте есть немного лучшее решение этой проблемы: http://kballcodes.com/2009/09/05/rails-memcached-a-better-solution-to-the-undefined-classmodule-problem/

Привет!

1 голос
/ 09 апреля 2009

Несколько вещей, которые могут помочь:

  • Добавьте инструментарий / протоколирование к current_site, чтобы точно увидеть, что возвращается.
  • Как вы определяете ключи в memcache? Вы можете случайно использовать один и тот же ключ в двух разных местах для двух разных объектов.
  • Используйте memcached-tool host:port dump > /tmp/keys, чтобы посмотреть, что на самом деле находится в вашем memcache.
  • Ваш memcached находится за брандмауэром и не отображается на публичном IP, верно?
0 голосов
/ 14 февраля 2012

добавление комментария к этому на случай, если кто-нибудь еще придет ... URL kballcodes.com больше не действителен (хотя вы все равно можете получить к нему доступ через archive.org ). В комментариях к этому сообщению в блоге кто-то описал способ заставить Marshal попытаться загрузить рассматриваемый объект, если он сначала выдает ошибку «неопределенный класс / модуль». Я включил этот код ниже и сослался на оригинального автора под примером кода.

Добавьте это в файл инициализатора в вашей папке RAILS_ROOT / config / initializers /:

# 
# Marshal.load is a C-method built into Ruby; because it's so low-level, it
# bypasses the full classloading chain in Ruby, in particular the #const_missing
# hook that Rails uses to auto-load classes as they're referenced. This monkey
# patch catches the generated exceptions, parses the message to determine the
# offending constant name, loads the constant, and tries again.
#
# This solution is adapted from here:
# http://kballcodes.com/2009/09/05/rails-memcached-a-better-solution-to-the-undefined-classmodule-problem/
#
class <<Marshal
  def load_with_rails_classloader(*args)
    begin
      load_without_rails_classloader(*args)
    rescue ArgumentError, NameError => e
      if e.message =~ %r(undefined class/module)
        const = e.message.split(' ').last
        const.constantize
        retry
      else
        raise(e)
      end
    end
  end

  alias_method_chain :load, :rails_classloader
end

Вся заслуга в этом принадлежит Мэтту Брауну , который сделал этот код как наклейку и прокомментировал уже мертвую статью выше:

0 голосов
/ 19 ноября 2009

Да, у меня такое было. Со мной это было потому, что я делал Rails.cache.fetch(key), а ключ был пустым.

Я немного поиграл в консоли Rails со следующим:

Rails.cache.read validkey  # Get back the proper data
Rails.cache.fetch('') { 'abc' } # Error in rails log: 'MemCacheError ():'
Rails.cache.read validkey # Get back nil
Rails.cache.read validkey # May get back proper data
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...