【问题标题】:Rails: Persist the client from Twitter gem by sferikRails:从 sferik 的 Twitter gem 中持久化客户端
【发布时间】:2015-07-25 18:03:51
【问题描述】:
我正在使用 Twitter gem 和 Devise/Omniauth 代表用户执行操作。一切都很顺利,我可以成功地为人们发推文。但是,感觉有些恶心。
你们如何坚持使用 Twitter 客户端?即
client = Twitter::REST::Client.new do |config|
config.consumer_key = Rails.application.secrets.twitter_consumer_key
config.consumer_secret = Rails.application.secrets.twitter_consumer_secret
config.access_token = 'xxxx'
config.access_token_secret = 'xxxx'
end
在我的大脑中,在每次后续 API 调用之前实例化客户端是没有意义的。如您所知,Twitter 会在一段时间后限制您的速率。
那么,在整个会话中保持“客户”的最佳方式是什么?
【问题讨论】:
标签:
ruby-on-rails
twitter
devise
omniauth
【解决方案1】:
实际上,将客户端实例化 100 次并不比实例化一次涉及更多的与 Twitter 的通信;这是调用网络流量的客户端的实际使用,因此很重要。但是,您并没有错,没有真正的理由每次都重新实例化它。您有几个选择,具体取决于您的用例:
- 使用 Rails 初始化程序。也就是说,您可以在
config/initializers/twitter.rb 中构建您的客户端实例,并将其分配给全局可访问的对象,例如常量 (TwitterClient = Twitter::REST::Client.new do ...)。除非您重新部署应用程序,并且 - 重要的是 - 如果 Twitter 客户端是 thread-safe,否则这只有在您的配置永远不会更改的情况下才可以。对于 Ruby gems,这通常不是一个有效的假设,但如果您在 MRI 上运行,您可能不需要担心它。
-
在您使用 twitter 客户端的任何对象中,缓存该实例。最简单的方法是这样的:
def twitter_client
@twitter_client ||= Twitter::REST::Client.new do ...
end
# ...
def other_method
twitter_client.do_something(foo: "bar")
end
但是,您的工作量可能会有所不同——实例变量缓存仅在对象存在时才会存在,对于控制器而言,这仅在一个请求期间存在。您也可以将其缓存到类变量中,但这实际上与上面的第一个选项相同。
最终,实例化 Ruby 对象非常便宜,所以我不会太担心。试图避免实例化对象通常会导致您在开发中浪费更多的时间,而不是在生产中实际节省的时间(就像大多数过早的优化一样)。
【讨论】:
-
如果实例化一个新的 Twitter 客户端不计入您的 API 调用,那么我完全同意您的第二个要点。事实上,这就是我的工作方式。我认为创建一个 Twitter 客户端点击 this 这可能是一个糟糕的假设,它只允许很少的请求。 15 分钟内 15 个。谢谢。我会像以前一样继续前进!
【解决方案2】:
在初始化器中初始化 Twitter 客户端时,最好不要在初始化器中包含访问令牌和访问秘密令牌,因为此值会因用户而异。并且在将其初始化为任何本地/实例变量时,请尝试使用 TWITTERCLIENT。 dup 因为它会为您的实例创建不同的对象 ID,如果您将使用相同的常量,那么对实例变量的任何更改都会影响常量。