Hello there,
I have a mail-fetcher script which checks for mails in a pop3 account
regularly and which works perfectly fine standalone and being called
via a crontab entry regularly. However, I'd like to daemonize it
properly and therefore basically wrote the stuff below.
It loads the rails env, checks for mails and calls the
ImportFromMail.receive method which basically inherits from
ActionMailer::Base.
However, it seems the combination of rails env + simple-daemon whoes
with AR in the background as basically the connection to the database
is lost somewhere inbetween.... resulting in the error above :-/
Has anyone come across this / knows a proper way around to use simple-
daemon in combination with the rails environment loaded (and actually
keeping it)?
-J
---- the mail fetcher ----
#!/usr/bin/env ruby
RAILS_ENV = ARGV[1] || 'development'
require File.dirname(__FILE__) + '/../../config/boot'
require File.dirname(__FILE__) + '/../../config/environment'
require File.dirname(__FILE__) + '/../../lib/net/pop.rb'
require 'simple-daemon'
# configuring working dir for SimpleDaemon
WORKING_DIR = File.join(RAILS_ROOT, 'tmp', 'importers',
'mail_fetcher')
CONFIG = YAML.load(IO.read("#{RAILS_ROOT}/config/importers/
mail_fetcher.yml"))
class MailFetcher < SimpleDaemon::Base
`mkdir -p #{WORKING_DIR}` # just make sure the working dir exists
SimpleDaemon::WORKING_DIRECTORY = WORKING_DIR
def self.start
MailFetcher.log("Starting up")
sleep(5)
# looping and processing received messages
MailFetcher.log("Entering infinite loop state (checking every
#{CONFIG[RAILS_ENV]["sleep_time"]} seconds)")
loop do
MailFetcher.log("Checking for new mail(s)")
begin
# setting timeout to just a little bit under 10 minutes
timeout(CONFIG[RAILS_ENV]['timeout']) do
MailFetcher.log("Configuring pop3 environment")
@pop = Net::POP3.new(CONFIG[RAILS_ENV]['server'])
@pop.enable_ssl if CONFIG[RAILS_ENV]['use_ssl'] == true
MailFetcher.log("Configuring pop3 environment: done")
MailFetcher.log("Connecting to mail server")
@pop.start(CONFIG[RAILS_ENV]['username'],
CONFIG[RAILS_ENV]['password'])
MailFetcher.log("Connecting to mail server: done")
if @pop.mails.empty?
log "No new mails"
else
@pop.mails.each do |email|
begin
log "Receiving and importing mail"
ImportFromMail.logger = nil # suppressing rails
internal logging
ImportFromMail.debug_logger = @logger
ImportFromMail.receive(email.pop)
log "Done, deleting mail"
email.delete
rescue Exception => e
log "Error receiving mail: #{e.message}"
end
end
end
MailFetcher.log("Disconnecting from mail server")
@pop.finish
MailFetcher.log("Disconnecting from mail server: done")
end
rescue => e
MailFetcher.log("Could not fetch mail(s): #{e.inspect}")
end
MailFetcher.log("Checking for new mail(s): done")
# sleeping for another n seconds
sleep(CONFIG[RAILS_ENV]["sleep_time"])
end
end
def self.stop
MailFetcher.log("Shutting down")
@pop.finish unless @pop.nil?
sleep(5)
MailFetcher.log("Shutting down: done")
end
# Logging relevant methods
def self.logger
@logger ||= Logger.new(File.join(RAILS_ROOT, 'log',
'mail_fetcher.log'))
end
def self.log(message)
MailFetcher.logger.info("#{Time.now.utc}: #{message}")
end
def log(message)
MailFetcher.log(message)
end
end
# start the actual bot
MailFetcher.daemonize