5

我们有一个在 Rails 3 Spree 平台上运行的在线商店。最近客户在结账时开始报告奇怪的错误,在分析生产日志后,我发现了以下错误:

Errno::ENAMETOOLONG(文件名太长 - /var/www/store/tmp/cache/UPS-R43362140-US-NJ-FlorhamPark07932-1025786194_1%7C1025786087_1%7C1025786089_15%7C1025786146_4%7C1025786147_3%7C1025786098_3%7C1025786099_4%7C1025786100_2%7C1025786114_1%7C1025786120_1%7C1025786121_1%7C1025786181_1%7C1025786182_1%7C1025786208_120110412-2105-1e14pq5.lock)

我不确定为什么这个文件名这么长,以及这个错误是否特定于 Rails 或 Spree。另外我对 Rails 缓存系统不是很熟悉。对于如何解决此问题,我将不胜感激。

4

5 回答 5

5

我猜您正在使用 spree_active_shipping,因为它看起来像是 UPS 运输报价的缓存 ID。当有人创建包含大量订单项的订单时,就会发生这种情况。有了足够的行项目,这当然会为缓存创建一个非常大的文件名,从而给你错误。

一种选择是为 Rails.cache 使用 memcache 或 redis,而不是使用文件系统缓存。另一种方法是修改在 spree_active_shipping gem 中的 app/models/active_shipping.rb 中生成 cache_key 的算法。

后一个选项可能是最好的,您可以简单地让生成的缓存密钥通过 MD5 或 SHA1 之类的散列运行。这样,您将获得可预测的缓存键长度。

实际上,这应该在 spree_active_shipping 中修复,它不应该生成不可预测的长缓存键,即使您使用了键值存储,那也是浪费内存。

于 2011-06-19T20:27:12.487 回答
3

它与您的文件系统更相关。要么设置一个支持更长文件名的文件系统,要么更改软件以制作更好的(md5?timestamp?unique id?)文件名。

于 2011-04-13T21:55:43.323 回答
2

可能是这样的帮助:

config.assets.digestconfig.assets.debug 不能同时为真

这是一个错误:https ://github.com/rails/jquery-rails/issues/33

于 2012-01-13T13:15:33.277 回答
0

我正在使用 rails 3.2.x 并遇到同样的问题。我最终在用于生成缓存键的视图辅助方法中生成 MD5 摘要。

FILENAME_MAX_SIZE = 200    
def cache_key(prefix, params)
  params = Array.wrap(params) if params.instance_of?(String)
  key = "#{prefix}/" << params.entries.sort { |a,b| a[0].to_s <=> b[0].to_s }.map { |k,v| "#{k}:#{v}"}.join(',').to_s
  if URI.encode_www_form_component(key).size > FILENAME_MAX_SIZE
    key = Digest::MD5.hexdigest(key)
  end
  key
end

在这里,我必须检查 URI 编码键值的长度, URI.encode_www_form_component(key).size因为正如您在我的例子中看到的那样,缓存键是使用:,分隔符生成的。Rails 在缓存结果之前对密钥进行编码。

我参考了pull request

于 2015-07-29T13:36:58.100 回答
0

你在用回形针宝石吗?如果是,则此问题已解决:https ://github.com/thoughtbot/paperclip/issues/1246 。

请将您的回形针 gem 更新到最新版本。

于 2015-10-13T15:29:07.313 回答