0

我的工作流程是 email--sendgrid--griddler,rails 应用程序在 heroku 上运行。所有入站电子邮件都有附件,有些相当大。我在 Heroku 上不断收到 H12 超时,因为附件需要 30 多秒才能上传到 Google Cloud Storage。

我已经尽我所能使用延迟工作,但我不认为我可以将附件从烤盘传递到延迟工作,因为附件是短暂的。我有一个朋友建议直接从 gmail 中检索电子邮件,而不是使用 sendgrid 和 griddler,但这比我目前所要做的更像是重写。在理想情况下,我可以将附件传递给延迟的工作,但我不知道这最终是否可能。

    email_processor.rb

        if pdfs = attachments.select { |attachment| attachment.content_type == 'application/pdf' }
          pdfs.each do |att|
            # att is a ActionDispatch::Http::UploadedFile type
            # content_type = MIME::Types.type_for(att.to_path).first.content_type
            content_type = att.content_type
            if content_type == 'application/pdf'
              # later if we use multiple attachments in single fax, change num_pages
              fax = @email_address.phone_number.faxes.create(sending_email: @email_address.address ,twilio_to: result, twilio_from: @email_address.phone_number.number, twilio_num_pages: 1)
              attachment = fax.create_attachment
              # next two rows should be with delay
              attachment.upload_file!(att)
              #moved to attachment model for testing
              #fax.send!
            end
          end


    file upload from another model
    def upload_file!(file)
    # file should be ActionDispatch::Http::UploadedFile type
    filename = file.original_filename.gsub(/\s+/, '_')
    filename = filename[0..15] if filename.size > 16
    path = "fax/#{fax.id}/att-#{id}-#{filename}"
    upload_out!(file.open, path)

    #self.fax.send!
    #make_thumbnail_pdf!(file.open)
  end

  def upload_out!(file, path)
    upload = StorageBucket.files.new key: path, body: file, public: true
    upload.save # upload file
    update_columns url: upload.public_url
    self.fax.update(status: 'outbound-uploaded')
    self.fax.process!
  end
4

2 回答 2

0

如果您无法在 30 秒内接收并上传附件,那么 heroku 将无法接收电子邮件。您是对的 - 运行延迟作业的工作人员 dyno 无法访问网络测功机上的临时存储。

即使 worker dyno 可以从 web dyno 的临时存储中读取数据,如果附件足够大,也不能保证 web dyno 可以在 30 秒内处理来自 sendgrid 的 POST。

一种选择是配置 sendgrid 将电子邮件直接转发到您的谷歌应用引擎 - https://cloud.google.com/appengine/docs/standard/python/mail/receiving-mail-with-mail-api

您的应用程序引擎脚本可以将附件写入谷歌云存储,然后您的应用程序引擎脚本可以使用附件的位置向您的 Heroku 应用程序进行 POST,然后 Web 应用程序可以排队延迟作业以下载和处理附件。

于 2019-06-19T06:30:46.417 回答
0

我最终只是完全重写了我的电子邮件处理。我将 gmail 设置为邮件目标,然后在 Heroku 使用计划任务来处理电子邮件(查找未读邮件),然后将附件上传到 Google Cloud Storage。使用计划任务可以解决 H12 问题。

于 2019-06-19T21:13:49.887 回答