- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
来自Best Practices Guide对于使用 Sidekiq,我知道最好将“字符串、整数、 float 、 bool 值、null(nil)、数组和散列”作为参数传递给作业。
我通常只是将持久对象的 ID 传递给我的作业,但由于延迟限制,我需要在运行作业后保存该对象。
我正在使用的非持久化对象包含多种数据类型:
#MyObject<00x000>{
id: nil
start_time: Fri, 11 Dec 2020 08:45:00 PST -08:00 (*this is a TimeWithZone object)
rate: 18.0 (*this is a BigDecimal object)
...
}
我计划先将此对象转换为散列,然后将其传递给我的作业:
MyJob.perform_async(my_object.attributes)
然后像这样持久化对象:
MyObject.new(my_object_hash).save
我的问题是,这样安全吗?即使我将“简单”数据类型传递给 Sidekiq,它实际上包含复杂的对象。我会失去精度吗?
谢谢!
最佳答案
这听起来像是“potayto, potahto”解决方案。你不是不用Sidekiq的序列化,而是自己序列化。
让我们看看为什么 sidekiq 有这个规则:
Even if they did serialize correctly, what happens if your queue backs up and that quote object changes in the meantime? [...]Don't pass symbols, named parameters, keyword arguments or complex Ruby objects (like Date or Time!) as those will not survive the dump/load round trip correctly.
我想添加第三个:
Serializing state makes it impossible to distinguish between persisted and ethereal (in-memory, memoized, lazy-loaded etc) data. E.g. a
def sent_mails; @sent_mails ||= Mail.for(user_id: id); end
now gets serialized: do you want that?
sidekiq也提供了解决方案:
Don't save state to Sidekiq, save simple identifiers. Look up the objects once you actually need them in your perform method.
您的真正问题不是在何处或如何序列化状态。因为 sidekiq 警告不要序列化状态,无论您在何处以及如何执行此操作。
您需要解决的问题是如何将状态存储在可以正确存储的地方。或者根本避免存储状态:不在 redis/sidekiq 中,也不在给您带来问题的存储中。
您的存储速度慢吗?难道不是验证、序列化、缓慢的存储副作用吗?
您能否通过两步来改进它:插入状态并稍后更新/丰富/验证它异步?如果您使用的是 Rails,它在这里对您没有帮助,甚至可能对您不利,但一个常见的模型是将对象存储在一个特殊的“队列”表或事件队列中;例如kafka 以此闻名。
当例如存储通过慢速网络发生在慢速 API 上,这可能无法解决,但是当存储发生在本地数据库中时,您可以使用数十年的解决方案来提高写入性能。无论是在你的数据库中,还是在一些专门的状态存储队列中(sidekiq 不是这样一个专门的存储队列),这取决于用于存储的技术。例如。 Linux 将允许您通过内存进行存储,从而使写入磁盘的速度非常快,但无法保证它确实已写入磁盘。
例如在簿记 API 中,我们会将经过验证的对象存储在 PostgreSQL 中,然后让异步作业稍后为其添加昂贵的属性(例如,必须从遗留 API 或通过复杂计算检索的状态)。
例如在写入量大的 GIS 系统中,我们会将对象存储到“to_process_places”表中,该表由处理 Places 的工具监控。这完全取决于您的领域和要求。
一个常见的解决方案是不制作对象,而是使用客户的实际负载。只需发送 HTTP 有效负载(在 rails 中,params
)并保留它。也许合并到一个 header 中(如 Request Date )或过滤掉一些数据( header 标记或 cookie)。
如果您的 Controller 可以使用这些数据进行操作,那么延迟作业也可以。不要在 Controller 中构建对象,而是将其留给延迟的工作。这甚至可以产生真正整洁和精简的 Controller :它们所做的只是(一些身份验证和授权,然后)调用适当的作业并向其传递经过净化的 params
。
显然,这需要权衡,比如不能同步验证,而是通过电子邮件、推送通知或延迟响应提供此类信息,具体取决于您的要求(例如,大型 CSV 导入可以通过电子邮件发送任何验证问题,但如果登录无效,登录请求可能需要立即得到响应。
还需要考虑一下:您可能不想将 Base64 编码的 CSV 一起发送到 sidekiq,而是将文件写入(临时)存储并传递文件名/url。这听起来很明显,因为它是:文件上传本质上是前面提到的“临时状态存储”的实现:你不会将整个 PDF/high-res-header-image/CSV 传递给 sidekiq,而是存储它某个地方,这样 sidekiq 以后可以把它捡起来进行处理。如果将其他属性传递给 sidekiq 存在问题,为什么其他属性不采用相同的模式?
关于ruby-on-rails - 将复杂的哈希传递给 Sidekiq 作业,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65252608/
以下是一个非常简单的ruby服务器。 require 'socket' local_socket = Socket.new(:INET, :STREAM) local_addr = Socket.
我正在使用 OS X(使用 bash),并且是 unix 的新手。我想知道是否可以修改一些文件以便运行 ruby 程序,我不需要“ruby file.rb”,而是可以运行“ruby.rb”。 有理
我在用 Ruby 替换字符串时遇到一些问题。 我的原文:人之所为不如兽之所为。 我想替换为:==What== human does is not like ==what== animal does.
我想在一个循环中从 Ruby 脚本做这样的事情: 写一个文件a.rb(每次迭代都会改变) 执行系统(ruby 'a.rb') a.rb 将带有结果的字符串写入文件“results” a.rb 完成并且
我的问题是尝试创建一个本地服务器,以便我可以理解由我的新团队开发的应用程序。我的问题是我使用的是 Ruby 2.3.3,而 Gemfile 需要 2.3.1。我无法编辑 Gemfile,因为我被告知很
我有一个使用 GLI 框架用 Ruby 编写的命令行实用程序。我想在我的主目录中配置我的命令行实用程序,使用 Ruby 本身作为 DSL 来处理它(类似于 Gemfile 或 Rakefile)。 我
我的 Rails 应用 Controller 中有这段代码: def delete object = model.datamapper_class.first(:sourced_id =>
我正在寻找的解析器应该: 对 Ruby 解析友好, 规则设计优雅, 产生用户友好的解析错误, 用户文档的数量应该比计算器示例多, UPD:允许在编写语法时省略可选的空格。 快速解析不是一个重要的特性。
我刚开始使用 Ruby,听说有一种“Ruby 方式”编码。除了 Ruby on Rails 之外,还有哪些项目适合学习并被认可且设计良好? 最佳答案 Prawn被明确地创建为不仅是一个该死的好 PDF
我知道之前有人问过类似的问题,但是我该如何构建一个无需在前面输入“ruby”就可以在终端中运行的 Ruby 文件呢? 这里的最终目标是创建一个命令行工具包类型的东西。现在,为了执行我希望用户能够执行的
例如哈希a是{:name=>'mike',:age=>27,:gender=>'male'}哈希 b 是 {:name=>'mike'} 我想知道是否有更好的方法来判断 b 哈希是否在 a 哈希内,而
我是一名决定学习 Ruby 和 Ruby on Rails 的 ASP.NET MVC 开发人员。我已经有所了解并在 RoR 上创建了一个网站。在 ASP.NET MVC 上开发,我一直使用三层架构:
最近我看到 Gary Bernhardt 展示了他用来在 vim 中执行 Ruby 代码的 vim 快捷方式。捷径是 :map ,t :w\|:!ruby %. 似乎这个方法总是执行系统 Rub
在为 this question about Blue Ruby 选择的答案中,查克说: All of the current Ruby implementations are compiled to
我有一个 Ruby 数组 > list = Request.find_all_by_artist("Metallica").map(&:song) => ["Nothing else Matters"
我在四舍五入时遇到问题。我有一个 float ,我想将其四舍五入到小数点后的百分之一。但是,我只能使用 .round ,它基本上将它变成一个 int,意思是 2.34.round # => 2. 有没
我使用 ruby on rails 编写了一个小型 Web 应用程序,它的主要目的是上传、存储和显示来自 xml(文件最多几 MB)文件的结果。运行大约 2 个月后,我注意到 mongrel 进程
我们如何用 Ruby 转换像这样的字符串: 𝑙𝑎𝑡𝑜𝑟𝑟𝑒 收件人: Latorre 最佳答案 s = "𝑙𝑎𝑡𝑜𝑟𝑟𝑒" => "𝑙𝑎𝑡𝑜𝑟𝑟𝑒" s.u
通过 ruby monk 时,他们偶尔会从左侧字段中抛出一段语法不熟悉的代码: def compute(xyz) return nil unless xyz xyz.map {|a,
不确定我做错了什么,但我似乎弄错了。 问题是,给你一串空格分隔的数字,你必须返回最大和最小的数字。 注意:所有数字都是有效的 Int32,不需要验证它们。输入字符串中始终至少有一个数字。输出字符串必须
我是一名优秀的程序员,十分优秀!