我已經把mailman gem集成到了我的rails項目中。它從Gmail成功獲取電子郵件。在我的應用程序中,我的電子郵件有一個模型消息。電子郵件已正確保存爲消息模式。郵差多次保存郵件
問題是,電子郵件有時被保存多次,我無法識別一個模式。有些電子郵件會保存一次,有些會保存三次。
但我無法在我的代碼中找到失敗。
這裏是我的mailman_server腳本:
腳本/ mailman_server
#!/usr/bin/env ruby
# encoding: UTF-8
require "rubygems"
require "bundler/setup"
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'config', 'environment'))
require 'mailman'
Mailman.config.ignore_stdin = true
#Mailman.config.logger = Logger.new File.expand_path("../../log/mailman_#{Rails.env}.log", __FILE__)
if Rails.env == 'test'
Mailman.config.maildir = File.expand_path("../../tmp/test_maildir", __FILE__)
else
Mailman.config.logger = Logger.new File.expand_path("../../log/mailman_#{Rails.env}.log", __FILE__)
Mailman.config.poll_interval = 15
Mailman.config.imap = {
server: 'imap.gmail.com',
port: 993, # usually 995, 993 for gmail
ssl: true,
username: '[email protected]',
password: 'my_password'
}
end
Mailman::Application.run do
default do
begin
Message.receive_message(message)
rescue Exception => e
Mailman.logger.error "Exception occurred while receiving message:\n#{message}"
Mailman.logger.error [e, *e.backtrace].join("\n")
end
end
end
電子郵件是我的消息類的內部處理:
def self.receive_message(message)
if message.from.first == "[email protected]"
Message.save_bcc_mail(message)
else
Message.save_incoming_mail(message)
end
end
def self.save_incoming_mail(message)
part_to_use = message.html_part || message.text_part || message
if Kontakt.where(:email => message.from.first).empty?
encoding = part_to_use.content_type_parameters['charset']
Message.create topic: message.subject, message: part_to_use.body.decoded.force_encoding(encoding).encode('UTF-8'), communication_partner: message.from.first, inbound: true, time: message.date
else
encoding = part_to_use.content_type_parameters['charset']
Message.create topic: message.subject, message: part_to_use.body.decoded.force_encoding(encoding).encode('UTF-8'), communication_partner: message.from.first, inbound: true, time: message.date, messageable_type: 'Company', messageable_id: Kontakt.where(:email => message.from.first).first.year.id
end
end
def self.save_bcc_mail(message)
part_to_use = message.html_part || message.text_part || message
if Kontakt.where(:email => message.to.first).empty?
encoding = part_to_use.content_type_parameters['charset']
Message.create topic: message.subject, message: part_to_use.body.decoded.force_encoding(encoding).encode('UTF-8'), communication_partner: message.to.first, inbound: false, time: message.date
else
encoding = part_to_use.content_type_parameters['charset']
Message.create topic: message.subject, message: part_to_use.body.decoded.force_encoding(encoding).encode('UTF-8'), communication_partner: message.to.first, inbound: false, time: message.date, messageable_type: 'Company', messageable_id: Kontakt.where(:email => message.to.first).first.year.id
end
end
我已經進程化的mailman_server這個腳本:
腳本/ mailman_daemon
#!/usr/bin/env ruby
require 'rubygems'
require "bundler/setup"
require 'daemons'
Daemons.run('script/mailman_server')
我Capistrano的部署。
這是其負責停止,啓動和重新啓動我的mailman_server部分:
腳本/ deploy.rb
set :rails_env, "production" #added for delayed job
after "deploy:stop", "delayed_job:stop"
after "deploy:start", "delayed_job:start"
after "deploy:restart", "delayed_job:restart"
after "deploy:stop", "mailman:stop"
after "deploy:start", "mailman:start"
after "deploy:restart", "mailman:restart"
namespace :deploy do
desc "mailman script ausfuehrbar machen"
task :mailman_executable, :roles => :app do
run "chmod +x #{current_path}/script/mailman_server"
end
desc "mailman daemon ausfuehrbar machen"
task :mailman_daemon_executable, :roles => :app do
run "chmod +x #{current_path}/script/mailman_daemon"
end
end
namespace :mailman do
desc "Mailman::Start"
task :start, :roles => [:app] do
run "cd #{current_path};RAILS_ENV=#{fetch(:rails_env)} bundle exec script/mailman_daemon start"
end
desc "Mailman::Stop"
task :stop, :roles => [:app] do
run "cd #{current_path};RAILS_ENV=#{fetch(:rails_env)} bundle exec script/mailman_daemon stop"
end
desc "Mailman::Restart"
task :restart, :roles => [:app] do
mailman.stop
mailman.start
end
end
難道是在啓動郵遞員服務器的多個實例我幾乎同時進行部署,然後每個實例幾乎同時進行調查?在第一個實例之前,第二個和第三個實例池將電子郵件標記爲已讀並輪詢並處理電子郵件?
更新30.01。
我已經設置輪詢intervall 60秒。但這並沒有改變。
我檢查了mailman pid文件的存儲位置。只有一個郵遞員pid文件。所以肯定只有一個郵遞員服務器在運行。我查了日誌文件,然後可以看到,該消息是取多次:
Mailman v0.7.0 started
IMAP receiver enabled ([email protected]).
Polling enabled. Checking every 60 seconds.
Got new message from '[email protected]' with subject 'Test nr 0'.
Got new message from '[email protected]' with subject 'Test nr 1'.
Got new message from '[email protected]' with subject 'test nr 2'.
Got new message from '[email protected]' with subject 'test nr 2'.
Got new message from '[email protected]' with subject 'test nr 3'.
Got new message from '[email protected]' with subject 'test nr 4'.
Got new message from '[email protected]' with subject 'test nr 4'.
Got new message from '[email protected]' with subject 'test nr 4'.
所以這似乎對我來說,這個問題肯定是我的郵差服務器代碼。
更新31.1。
對我來說,這與我的生產機器有關。當我使用完全相同的配置在開發中測試這個(在今天早上將我的本地數據庫從sqlite改爲mysql來測試它),就像在生產機器上一樣,我不會重複。可能是我的代碼一切正常,但生產機器存在問題。請問我的主機是否可以看到解決方案。爲了解決這個問題,我會和Ariejan的建議一起去解決。
解決方案: 我發現了這個問題。我部署到一臺機器,其中tmp目錄是所有版本之間共享的目錄。我忘了定義保存mailman_daemon的pid文件的路徑。所以它被保存在腳本目錄中而不是/ tmp/pids目錄中。因此,新的部署後無法停止舊的mailman_daemon。這導致了一羣工作mailman_daemons投票我的mailaccount ......殺死所有這些進程後,一切順利!沒有更多的重複!
嗨railsnewbie,似乎是一個棘手的問題。我冒昧地贊助你在這裏的編碼問題 - http://www.codersclan.net/ticket/211 – Dror