在Heroku + Django Rest Framework + s3上上传图像的时间问题

时间:2017-10-23 10:44:54

标签: django heroku amazon-s3

好的,这是架构设计和代码问题的混合。我在几个应用程序上遇到了这个问题,我不知道如何处理这个问题。

这个问题非常基础,一个允许用户将文件/图像附加到对象的应用程序。

我们说我有以下Django模型:DocumentAttachment

class Document(models.Model):

     body = models.TextField(blank=True, help_text='Plain text.')

class Attachment(models.Model):

     document = models.ForeignKey(Document, on_delete=models.CASCADE, related_name='attachments')
     attachment = models.FileField(upload_to=get_attachment_path, max_length=255,  null=False)
     filesize = models.IntegerField(default=0)
     filetype = models.CharField(blank=True, max_length=100)
     orientation = models.IntegerField(default=0)

get_attachment_path callable只是根据文档pk和用户构建路径。

当用户创建文档时,他可以将文件附加到文档。由于它是一个现代世界,您希望能够在创建文档之前上传文件,因此我有一个TempUpload对象以及从Web应用程序到S3的直接连接(使用预先签名的URL)

当用户点击文档表单上的save时,我会得到一个包含我需要附加到新文档的所有TempUpload个对象的数组。

现在问题是......在heroku 30s超时限制内,我需要:

  • 创建文档(非常快)
  • 迭代TempUpload个对象的数组,并创建Attachment
  • 将文件复制到其最终目的地(使用boto3 copy_object
  • 获取文件类型(使用magic库,我只查询前128个字节,但仍然是...到S3的一个往返)
  • 获取文件大小(另一次往返S3)
  • 获取方向(仅当附件是图像时,也基于EXIF数据并使用流式传输)

我已经将缩略图生成移动到外部服务。但是对于较大的文件(标准相机图片可以很容易地大到6-10Mb),我每个文件的处理延迟几乎可以达到1秒,这意味着如果用户上传的图像超过20张,它就会变得非常接近heroku超时...

我目前正在使用celery和redis将大部分处理移到响应生命周期之外,但它并不是很好......可能会在异步任务完成之前请求文档。在这种情况下,某些信息尚不可用(尺寸/方向)。

我认为这应该是一个相当标准的功能,我有兴趣知道你是如何实现这个功能的?

编辑:

只是添加一些我想到的策略:

  • 在初始上传时获取信息,而不是在保存文档时获取。这可行,但问题是我不知道上传何时完成(这直接发生在网络应用程序和S3之间)
  • 使用lambda fonction?
  • 使用S3标签而不是移动文件以轻松区分"已保存的"文件和应删除的文件?

对于测试和开发我想在django应用程序中保留尽可能多的逻辑...但是,嘿,也许那是不可能的......

0 个答案:

没有答案