好的,这是架构设计和代码问题的混合。我在几个应用程序上遇到了这个问题,我不知道如何处理这个问题。
这个问题非常基础,一个允许用户将文件/图像附加到对象的应用程序。
我们说我有以下Django模型:Document
和Attachment
。
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
copy_object
)magic
库,我只查询前128个字节,但仍然是...到S3的一个往返)我已经将缩略图生成移动到外部服务。但是对于较大的文件(标准相机图片可以很容易地大到6-10Mb),我每个文件的处理延迟几乎可以达到1秒,这意味着如果用户上传的图像超过20张,它就会变得非常接近heroku超时...
我目前正在使用celery和redis将大部分处理移到响应生命周期之外,但它并不是很好......可能会在异步任务完成之前请求文档。在这种情况下,某些信息尚不可用(尺寸/方向)。
我认为这应该是一个相当标准的功能,我有兴趣知道你是如何实现这个功能的?
编辑:
只是添加一些我想到的策略:
对于测试和开发我想在django应用程序中保留尽可能多的逻辑...但是,嘿,也许那是不可能的......