PROFILING = ENV["PROFILING"] || false
DISABLE_SELECTOR = true #ENV["DISABLE_SELECTOR"] || false
require "ruby-prof" if PROFILING
require "qbeat_log_formatter"
class QBeat
cattr_accessor :logger
def initialize
@shutdown_now = false
connect_signals
end
def run
QBeat.setup_logging
logger.info("QBeat starting up [#{RAILS_ENV}].")
mpd_mon = MpdMonitor.new
selector = WeightedSelector.new
tracks = []
begin
RubyProf.start if PROFILING
loop do
mpd_mon.loop_pre
while mpd_mon.playlist_too_short?
unless DISABLE_SELECTOR
time = Benchmark.realtime do
selector.check_pblock
tracks = selector.select
end
logger.debug(sprintf("Took %0.4f seconds to select track.", time))
else
logger.debug("skipping track selection due to DISABLE_SELECTOR")
end
tracks.each {|track| mpd_mon.append_track_to_playlist(track)}
if PROFILING
result = RubyProf.stop
printer = RubyProf::GraphHtmlPrinter.new(result)
printer.print(open("/home/ericw/public_html/qbeat_profile.html", "w"),
:min_percent => 0)
raise Interrupt.new("profile done")
end
end
mpd_mon.loop_post
raise Interrupt.new("shutdown requested") if @shutdown_now
sleep 2
end
rescue Interrupt
# keyboard interrupt, no op
rescue Exception => e
logger.error("Unhandled exception: #{e.inspect}\n" +
"#{e.backtrace.join("\n")}")
raise e
ensure
shutdown
end
end
def self.setup_logging
qbeat_log = QbeatLogger.new("#{RAILS_ROOT}/log/qbeat_#{RAILS_ENV}.log",
5, 5.megabytes)
qbeat_log.formatter = QbeatLogFormatter.new
[ProgrammingBlock, QBeat, MpdMonitor, TimeSlot,
Fetcher, Schedule, Selector, WeightedSelector].each do |cls|
cls.logger = qbeat_log
end
end
private
def connect_signals
Signal.trap("HUP") do
logger.info("Received HUP signal.")
end
Signal.trap("SIGUSR1") do
logger.info("Received USR1 signal.")
end
Signal.trap("TERM") do
logger.info("Received TERM signal.")
@shutdown_now = true
end
end
def shutdown
logger.info("QBeat shutting down.")
end
end