代码之家  ›  专栏  ›  技术社区  ›  Daniel Beardsley

在RubyonRails中,哪些数据(如果有的话)在Web请求之间持续存在?

  •  18
  • Daniel Beardsley  · 技术社区  · 15 年前

    我决定用 独生子女 创建视图助手类时的设计模式。这让我想到,单身汉会吗? 实例 跨请求生存?这引出了另一个问题, 哪些变量(如果有的话)可以跨Web请求生存 这是否会随着部署而改变?(FastCGI,Mongrel,乘客,…)

    我知道控制器实例变量不会持久化。我知道常量是持久的(还是重新加载的?)但是我不知道类变量、类上的实例变量、特征类……

    3 回复  |  直到 7 年前
        1
  •  18
  •   tadman    15 年前

    简单的答案是没有。每个请求都被视为一个独立的事件,除了存储在用户会话和任何外部数据库、缓存或文件存储中的内容之外,没有状态信息被传递。最好是在设计应用程序时考虑到这一点,而不要仅仅因为设置了它们就期望事情能够持续下去。

    更复杂的情况是有些事情确实会持续下去。例如,您可以在一个控制器上创建一个类变量,它将按预期从一个请求传递到下一个请求。关键是,这只适用于包含在该进程中的控制器的单一实例,而不适用于由其他进程提供服务的请求。如果需要缓存,请使用rails.cache基础设施,并避免自己的黑客攻击。

    一个典型的生产环境是一个复杂的、不断变化的事物,在那里过程不断地被创建和破坏,并且没有办法提前确定哪一个过程最终将服务于一个特定的请求。由于许多部署不仅涉及一台机器上的多个进程,而且涉及多台机器,因此实际上没有实际的方法来创建应用程序范围的单例对象。

    你能做的最好的事情就是在缓存引擎上构建一个层,在这个层中,你的singleton对象仅仅是一个包装器,用于从缓存中获取和写入函数。这使您在保持进程间一致性的同时获得了singleton对象的外观。

        2
  •  0
  •   D.Nogueira    7 年前

    我知道这篇文章很旧,但是对于谁在寻找解决方案,可以使用rails.cache,如下所示:

    class TestEventsController < ApplicationController
      require 'httparty'
    
      @@cache = ActiveSupport::Cache::MemoryStore.new(expires_in: 5.minutes)
    
      before_action :get_data, only: [:get]
      before_action :get_response, only: [:set]
    
      def get
        uri = "https://hooks.zapier.com/hooks/catch/zap_id/"
        event_id = event_id_generate()
        @@cache.write(event_id, "")
    
        result = HTTParty.post(uri.to_str,
        :body => {id: event_id, data: @data}.to_json,
        :headers => {'content-Type' => 'application/json'})
        sleep 2
        render json: { 'value': @@cache.read(event_id) }, status: 200
      end
    
      def set
        @@cache.write(@id, @value)
        render json: { 'value': @@cache.read(@id) }, status: 200
      end
    
      def get_data
        @data = params["data"]
      end
      def get_response
        @id = params["id"]
        @value = params["value"]
      end
    
      def event_id_generate
        token = SecureRandom.urlsafe_base64(10, false)
      end
    end
    

    我要做的是在一条路线上接收一个请求,发送一个GET到Zapier,然后在另一条路线上等待答案。Rails为每个请求打开一个新的线程,因此我在RAM中以“key:value”格式写入数据。

    Rails.cache in different threads not caching?

        3
  •  -4
  •   Warren    15 年前

    网络是一种无状态的媒介。除非您有目的地在会话中保存数据或在GET或POST中传递数据,否则每个Web请求都以空白的石板开始。一旦页面被传递到Web浏览器,用当前请求创建的任何对象都将被销毁。