0

私のスクリプトは、ユーザーのリストの電子メールを送信します。1 つのアドレスでエラーが発生するとすべてのアプリがクラッシュするため、マルチスレッドが必要です。これは私の実装です:

  require 'thread'
  <...>
  lock = Mutex.new
  lock.synchronize {
    @model.certs.each{ |user|
      @threads << Thread.new(user) { |data|
      to = "#{data['name']} #{data['surname']} <#{data['email']}>"
      subject = '<Subject>'
      body = "<Body>"
      view = View.new()
      view.to = to
      view.body = body
      view.subject = subject
      view.attachment = ''
      view.sendMessage()
      @model.sended(data['email'])
      }
    }
  }

  @threads.each { |t|
    begin
      t.join
    rescue => err
      $log.fatal(err)
    end
  }

view.sendMessage構成:

require 'mail'
require 'net/smtp'
<...>
smtp = Net::SMTP.start(@mailserver)
mail = Mail.new()
mail.from = @from
mail.to = @to
mail.subject = @subject
mail.body = @body
if !@attachment.empty?
  mail.add_file @attachment
end
mail.delivery_method :smtp_connection, {
  :connection => smtp
}
mail.deliver

また、次のような間違いが発生することもあります。

uninitialized constant Mail::Field::FromField (NameError)
/var/lib/gems/1.8/gems/mail-2.4.4/lib/mail/field.rb:189:in `new_field'

また

uninitialized constant Mail::CommonAddress::AddressList (NameError)
/var/lib/gems/1.8/gems/mail-2.4.4/lib/mail/fields/common/common_address.rb:9:in `parse'

どうすれば修正できるのかわかりません。Mutex を追加しても結果はありません。

4

2 に答える 2

2

ruby では Require はスレッドセーフではありません。スレッドを開始する前に、必要なものがすべて既に必要であることを確認する必要があります。

さらに、ミューテックスは現在何もしていません。マルチスレッドは、おそらくネットワーク遅延によって支配される電子メールの送信などのアクティビティに適していますが、エラー処理がマルチスレッドを使用する理由であるとは言えません (どちらかと言えば、マルチスレッドが難しくなります)。

于 2013-05-06T15:56:17.653 に答える
0

@FrederickCheungは、スレッドでのrequireについて正しいです。さらに、本当にスレッドが必要ですか? 何が問題なのですか:

emails.each do |mail|
  begin
    mail.deliver
  rescue TheCorrectExceptionForInvalidEmails
    puts "invalid e-mail: x"
    method_to_remove_invalid_email_from_database
  end
end

レスキューのために空のブロックを入れても、無効なメールではジャンプして実行を続けます。

于 2013-05-06T15:59:49.030 に答える