【问题标题】:Rails reload routes through all passenger threadsRails 通过所有乘客线程重新加载路线
【发布时间】:2014-05-28 20:40:55
【问题描述】:

我有一个Redirect 模型,如果管理员不小心通过电子邮件发送了一个错误的路由,它可以让他们构建一个替换路由。例如,/documents/40 不小心被删除了,但他们通过电子邮件将其作为链接发送出去,因此构建了一个从 /documents/40 到 /documents/41 的重定向。

代码运行良好,大部分魔法都在路由文件中:

Tenant.includes(:redirects).each do |tenant|
  constraints(subdomain: tenant.domain[0...tenant.domain.index('.')]) do
    tenant.redirects.each do |redirect|
      get redirect.old_path, to: 'redirects#show', id: redirect.id
    end
  end
end

而且效果很好。当您尝试创建、更新或销毁 Redirect 类的实例时,就会出现问题。在RedirectsController 我已经得到它以便它执行:

Platform::Application.reload_routes!

当只有一个乘客进程在运行时,这很有效。但是,在生产中,我们在给定时间运行了 8 个以上的进程,因此这个 reload_routes! 调用只影响一个进程。

有谁知道我将如何在所有Passenger 进程中重新加载路由,而不是重新启动Passenger

【问题讨论】:

  • 你是在运行Passenger多线程,还是多进程单线程?
  • 好点。是后者。我已经更新了问题。
  • 您可以将文档实例设置为修改后的ID,而不是重定向,例如@document = Document.find(redirect.id)
  • 这用于许多可能的模型,而不仅仅是文档。

标签: ruby-on-rails passenger


【解决方案1】:

如果您想在进程之间共享数据,请使用专门用于该任务的层,例如 memcached、redis 或数据库。

Phusion Passenger 可能会产生多个应用程序进程。每个进程都有自己的内存,不能访问其他进程的内存。如他的架构中所述:

http://www.modrails.com/documentation/Architectural%20overview.html#spawn_server

【讨论】:

    【解决方案2】:

    我们终于找到了解决方案。我们利用线程的特性来跨多个请求保持状态,并创建了一个中间件,只要Thread.current 中保存的时间戳与最后一次路由更改的时间戳不匹配,就会强制当前线程运行Platform::Application.reload_routes!

    在此处查看完整代码:

    Rails reload dynamic routes on multiple instances/servers

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-24
      • 1970-01-01
      • 1970-01-01
      • 2019-01-14
      • 1970-01-01
      相关资源
      最近更新 更多