cmd = cmd_str.split()
        environ = dict(os.environ.items() + [("MYSQL_USER", "user%d" % port)])
        process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env = environ)
        stdoutLogger = log.FileLoggerThread(self.logger, "php5-cgi stdout", logging.INFO, process.stdout)
        stderrLogger = log.FileLoggerThread(self.logger, "php5-cgi stderr", logging.ERROR, process.stderr)
        stdoutLogger.start()
        stderrLogger.start()
        return process

    def kill_worker(self, addr, port, popen_obj):
        '''Must attempt to kill the specified worker. Does not return anything'''
        self.logger.debug("killing %d", port)
        try:
            popen_obj.kill()
        except OSError, e:
            self.logger.error("Error while trying to kill '%s:%d': %s" % (addr, port, e))

        cmd_str = "php %s" % KILL_SQL_PHP
        self.logger.debug("cmd_str='%s'" % cmd_str)
        cmd = cmd_str.split()
        environ = dict(os.environ.items() + [("MYSQL_USER", "user%d" % port)])
        process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env = environ)
        stdoutLogger = log.FileLoggerThread(self.logger, "kill_sql.php stdout", logging.INFO, process.stdout)
        stderrLogger = log.FileLoggerThread(self.logger, "kill_sql.php stderr", logging.ERROR, process.stderr)
        stdoutLogger.start()
        stderrLogger.start()
        process.wait()

bouncer_process_manager.main(BouncerForPhp)

REDMINE_CMD_TEMPLATE_STR = 'ruby %s/script/server mongrel -e production -p $port' \
    % INSTALL_REDMINE_PATH

class BouncerForRedmine(BouncerProcessManager):

    def start_worker(self, addr, port):
        '''Must attempt to launch the specified worker. Should return the popen object for the new worker
           or None, if the worker couldn't be be launched for some reason.'''
        cmd_str = Template(REDMINE_CMD_TEMPLATE_STR).substitute( \
                addr = addr, \
                port = str(port) \
            )
        self.logger.debug("cmd_str='%s'" % cmd_str)
        cmd = cmd_str.split()
        process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        stdoutLogger = log.FileLoggerThread(self.logger, "redmine stdout", logging.INFO, process.stdout)
        stderrLogger = log.FileLoggerThread(self.logger, "redmine stderr", logging.ERROR, process.stderr)
        stdoutLogger.start()
        stderrLogger.start()
        return process

    def kill_worker(self, addr, port, popen_obj):
        '''Must attempt to kill the specified worker. Does not return anything'''
        try:
            popen_obj.kill()
        except OSError, e:
            self.logger.error("Error while trying to kill '%s:%d': %s" % (addr, port, e))

bouncer_process_manager.main(BouncerForRedmine)

OSQA_CMD_TEMPLATE_STR = 'python %s/manage.py run_gunicorn 0.0.0.0:$port' % INSTALL_OSQA_PATH

class BouncerForOsqa(BouncerProcessManager):

    def start_worker(self, addr, port):
        '''Must attempt to launch the specified worker. Should return the popen object for the new worker
           or None, if the worker couldn't be be launched for some reason.'''
        cmd_str = Template(OSQA_CMD_TEMPLATE_STR).substitute( \
                addr = addr, \
                port = str(port) \
            )
        self.logger.debug("cmd_str='%s'" % cmd_str)
        cmd = cmd_str.split()
        process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        stdoutLogger = log.FileLoggerThread(self.logger, "osqa stdout", logging.INFO, process.stdout)
        stderrLogger = log.FileLoggerThread(self.logger, "osqa stderr", logging.ERROR, process.stderr)
        stdoutLogger.start()
        stderrLogger.start()
        return process

    def kill_worker(self, addr, port, popen_obj):
        '''Must attempt to kill the specified worker. Does not return anything'''
        try:
            popen_obj.kill()
        except OSError, e:
            self.logger.error("Error while trying to kill '%s:%d': %s" % (addr, port, e))

bouncer_process_manager.main(BouncerForOsqa)

import time

dirname = os.path.dirname(os.path.realpath(__file__))

sys.path.append(os.path.join(dirname, '..', '..', 'bouncer'))

import bouncer_process_manager
from bouncer_process_manager import BouncerProcessManager

DUMMY_FASTCGI_APP_PATH = os.path.join(dirname, 'fcgi_worker_process.py')

class BouncerForDummyFcgi(BouncerProcessManager):

    def start_worker(self, addr, port):
        '''Must attempt to launch the specified worker. Should return the popen object for the new worker
           or None, if the worker couldn't be be launched for some reason.'''
        return subprocess.Popen([DUMMY_FASTCGI_APP_PATH, str(port)])

    def kill_worker(self, addr, port, popen_obj):
        '''Must attempt to kill the specified worker. Does not return anything'''
        # TODO: try terminate then graduate to kill if necessary
        # TODO: make sure to kill all children
        try:
            popen_obj.terminate()
        except OSError, e:
            print "Error while trying to kill '%s:%d': %s" % (addr, port, e)


bouncer_process_manager.main(BouncerForDummyFcgi)