cc-2419: media monitor import on start

-initial check-in
This commit is contained in:
martin 2011-06-28 18:01:30 -04:00
parent 600f80e03f
commit 89dd251782
5 changed files with 98 additions and 18 deletions

View file

@ -3,6 +3,7 @@ import time
import logging import logging
import logging.config import logging.config
import sys import sys
import os
import signal import signal
from multiprocessing import Process from multiprocessing import Process
@ -10,13 +11,14 @@ from multiprocessing import Process
from airtimefilemonitor.airtimenotifier import AirtimeNotifier from airtimefilemonitor.airtimenotifier import AirtimeNotifier
from airtimefilemonitor.airtimeprocessevent import AirtimeProcessEvent from airtimefilemonitor.airtimeprocessevent import AirtimeProcessEvent
from airtimefilemonitor.mediaconfig import AirtimeMediaConfig from airtimefilemonitor.mediaconfig import AirtimeMediaConfig
from airtimefilemonitor.airtimemediamonitorbootstrap import AirtimeMediaMonitorBootstrap
def handleSigTERM(signum, frame): def handleSigTERM(signum, frame):
logger = logging.getLogger() logger = logging.getLogger()
logger.info("Main Process Shutdown, TERM signal caught. %d") logger.info("Main Process Shutdown, TERM signal caught.")
for p in processes: for p in processes:
p.terminate()
logger.info("Killed process. %d", p.pid) logger.info("Killed process. %d", p.pid)
p.terminate()
sys.exit(0) sys.exit(0)
@ -26,13 +28,17 @@ try:
logging.config.fileConfig("logging.cfg") logging.config.fileConfig("logging.cfg")
except Exception, e: except Exception, e:
print 'Error configuring logging: ', e print 'Error configuring logging: ', e
sys.exit() sys.exit(1)
logger = logging.getLogger() logger = logging.getLogger()
processes = [] processes = []
try: try:
config = AirtimeMediaConfig() config = AirtimeMediaConfig(logger)
bootstrap = AirtimeMediaMonitorBootstrap(logger)
bootstrap.scan()
logger.info("Initializing event processor") logger.info("Initializing event processor")
pe = AirtimeProcessEvent(airtime_config=config) pe = AirtimeProcessEvent(airtime_config=config)
@ -45,8 +51,6 @@ try:
processes.append(p) processes.append(p)
p.start() p.start()
signal.signal(signal.SIGTERM, handleSigTERM)
logger.info("Setting up monitor") logger.info("Setting up monitor")
response = None response = None
while response is None: while response is None:
@ -61,14 +65,16 @@ try:
logger.info("Added watch to %s", storage_directory) logger.info("Added watch to %s", storage_directory)
logger.info("wdd result %s", wdd[storage_directory]) logger.info("wdd result %s", wdd[storage_directory])
#register signal before process forks and exits.
signal.signal(signal.SIGTERM, handleSigTERM)
notifier.loop(callback=pe.notifier_loop_callback) notifier.loop(callback=pe.notifier_loop_callback)
for p in processes:
p.join()
except KeyboardInterrupt: except KeyboardInterrupt:
notifier.stop() notifier.stop()
logger.info("Keyboard Interrupt")
except Exception, e: except Exception, e:
notifier.stop() #notifier.stop()
logger.error('Exception: %s', e) logger.error('Exception: %s', e)

View file

@ -17,13 +17,13 @@ DAEMON=/usr/lib/airtime/media-monitor/airtime-media-monitor
PIDFILE=/var/run/airtime-media-monitor.pid PIDFILE=/var/run/airtime-media-monitor.pid
start () { start () {
monit monitor airtime-media-monitor >/dev/null 2>&1 #monit monitor airtime-media-monitor >/dev/null 2>&1
start-stop-daemon --start --background --quiet --chuid $USERID:$GROUPID --make-pidfile --pidfile $PIDFILE --startas $DAEMON start-stop-daemon --start --background --quiet --chuid $USERID:$GROUPID --make-pidfile --pidfile $PIDFILE --startas $DAEMON
} }
stop () { stop () {
# Send TERM after 5 seconds, wait at most 30 seconds. # Send TERM after 5 seconds, wait at most 30 seconds.
monit unmonitor airtime-media-monitor >/dev/null 2>&1 #monit unmonitor airtime-media-monitor >/dev/null 2>&1
start-stop-daemon --stop --oknodo --retry TERM/5/0/30 --quiet --pidfile $PIDFILE start-stop-daemon --stop --oknodo --retry TERM/5/0/30 --quiet --pidfile $PIDFILE
rm -f $PIDFILE rm -f $PIDFILE
} }

View file

@ -0,0 +1,74 @@
import os
from subprocess import Popen, PIPE
class AirtimeMediaMonitorBootstrap():
def __init__(self, logger):
self.logger = logger
"""
on bootup we want to scan all directories and look for files that
weren't there or files that changed before media-monitor process
went offline. We can do this by doing a hash of the directory metadata.
"""
def scan(self):
directories = ['/srv/airtime/stor']
for dir in directories:
self.check_for_diff(dir)
def check_for_diff(self, dir):
airtime_tmp = '/var/tmp/airtime'
if os.path.exists(airtime_tmp + '/.airtime_media_index'):
#a previous index exists, we can do a diff between this
#file and the current state to see whether anything has
#changed.
self.logger.info("Previous index file found.")
#find files that have been modified since the last time
#media-monitor process was running.
command = "find %s -type f -iname '*.ogg' -o -iname '*.mp3' -readable -mmin -30" % dir
stdout = self.execCommandAndReturnStdOut(command)
self.logger.info("Files modified since last checkin: \n%s\n", stdout)
#find deleted files
command = "find %s -type f -iname '*.ogg' -o -iname '*.mp3' -readable > %s/.airtime_media_index.tmp" % (dir, airtime_tmp)
self.execCommand(command)
command = "diff %s/.airtime_media_index.tmp %s/.airtime_media_index" % (airtime_tmp, airtime_tmp)
stdout = self.execCommandAndReturnStdOut(command)
self.logger.info("Deleted files since last checkin:\n%s\n", stdout)
else:
#a previous index does not exist. Most likely means that
#media monitor has never seen this directory before. Let's
#notify airtime server about each of these files
self.logger.info("Previous index file does not exist. Creating a new one")
#create a new index file.
command = "find %s -type f -iname '*.ogg' -o -iname '*.mp3' -readable > %s/.airtime_media_index" % (dir, airtime_tmp)
self.execCommand(command)
def execCommand(self, command):
p = Popen(command, shell=True)
sts = os.waitpid(p.pid, 0)[1]
if sts != 0:
self.logger.warn("command \n%s\n return with a non-zero return value", command)
def execCommandAndReturnStdOut(self, command):
p = Popen(command, shell=True, stdout=PIPE)
stdout = p.communicate()[0]
if p.returncode != 0:
self.logger.warn("command \n%s\n return with a non-zero return value", command)
return stdout
if __name__ == '__main__':
mmb = AirtimeMediaMonitorBootstrap()
mmb.scan()

View file

@ -9,14 +9,14 @@ class AirtimeMediaConfig:
MODE_MOVED = "moved" MODE_MOVED = "moved"
MODE_DELETE = "delete" MODE_DELETE = "delete"
def __init__(self): def __init__(self, logger):
# loading config file # loading config file
try: try:
config = ConfigObj('/etc/airtime/media-monitor.cfg') config = ConfigObj('/etc/airtime/media-monitor.cfg')
self.cfg = config self.cfg = config
except Exception, e: except Exception, e:
print 'Error loading config: ', e logger.info('Error loading config: ', e)
sys.exit() sys.exit()
self.storage_directory = None self.storage_directory = None

View file

@ -13,10 +13,10 @@
with pidfile "/var/run/airtime-liquidsoap.pid" with pidfile "/var/run/airtime-liquidsoap.pid"
start program = "/etc/init.d/airtime-playout start" with timeout 10 seconds start program = "/etc/init.d/airtime-playout start" with timeout 10 seconds
stop program = "/etc/init.d/airtime-playout stop" stop program = "/etc/init.d/airtime-playout stop"
check process airtime-media-monitor # check process airtime-media-monitor
with pidfile "/var/run/airtime-media-monitor.pid" # with pidfile "/var/run/airtime-media-monitor.pid"
start program = "/etc/init.d/airtime-media-monitor start" with timeout 10 seconds # start program = "/etc/init.d/airtime-media-monitor start" with timeout 10 seconds
stop program = "/etc/init.d/airtime-media-monitor stop" # stop program = "/etc/init.d/airtime-media-monitor stop"
check process airtime-show-recorder check process airtime-show-recorder
with pidfile "/var/run/airtime-show-recorder.pid" with pidfile "/var/run/airtime-show-recorder.pid"
start program = "/etc/init.d/airtime-show-recorder start" with timeout 10 seconds start program = "/etc/init.d/airtime-show-recorder start" with timeout 10 seconds