首页 > 解决方案 > 在 iOS 中加载多个图像时,使用 send_data 加载的图像会损坏一半

问题描述

由于我不想进入这里的原因,我需要在使用此标签加载它们时动态调整来自用户手机(并且是愚蠢的大)的图像的大小

image_tag thumbnail_document_path(document.id), alt: "#{document.document_title}", class: "document-thumbnail"

这将调用缩略图控制器操作

  def thumbnail
    document = Document.find params[:id]
    image_meta = document.image_details.first
    image = Document.get_image_for_display image_meta
    send_data image, type: "image/jpg", disposition: "inline"
  end

Document.get_image_for_display从数据库中提取 blob,检查我们单独保存的元数据以查看它是需要转换为图像的 PDF 还是需要调整大小的大图像,然后执行所有这些操作并异步发送 blob。这适用于除 iOS 之外的所有设备。在 iOS Safari 和 Chrome 上,如果您同时以这种方式加载多个图像,则会发生这种情况。如果有人对此有解释或解决方案,我很想听听!

编辑:此应用程序与 C++ 桌面应用程序共享服务器和数据库,并且不能(也不能)访问服务器上存储这些文件的位置,并且在数百个客户端服务器上存在数十万个文件,因此存储由于物理存储限制,在完整尺寸旁边的调整大小版本不在讨论范围内。仅在尝试转换和加载超过 3 张大图像时才会出现此问题,然后只有第一个图像保持损坏,其他图像将完全加载,尽管它们需要一段时间才能完成。

标签: iosruby-on-railsruby

解决方案


您的thumbnail操作代码意味着get_image_for_display必须是同步的,因为它的返回值会立即使用。如果您使用的是线程服务器(如 puma),它也应该是可重新输入的 - 这样两个实例就可以在一个进程中同时运行。这要求它不写任何状态(类变量、其他全局变量),或者至少用同步来做。(互斥体等)。

但即使您的服务器是单线程的,在生产中通常也有多个进程。因此,对于函数的每个步骤,请考虑并发运行如何干扰。

例如:我可以猜测该函数运行一些外部应用程序来处理数据。首先要检查是否存在临时文件名冲突——当两个实例将数据写入同一个文件时(即使数据将相同)——显然它会被破坏。


推荐阅读