public function run()
{
// register a shutdown handler for controlled shutdown
register_shutdown_function(array(&$this, 'shutdown'));
// we need the autloader again
require SERVER_AUTOLOADER;
// create the service emitter
$emitter = new Emitter();
// load the bootstrap configuration
/** @var \AppserverIo\Appserver\Core\Api\Node\BootstrapNodeInterface $bootstrapNode */
$bootstrapNode = $this->doLoadBootstrap($this->getBootstrapConfigurationFilename());
// iterate over the listeners and add them to the emitter
/** @var \AppserverIo\Appserver\Core\Api\Node\ListenerNodeInterface $listener */
foreach ($bootstrapNode->getListeners() as $listener) {
// load the listener class name
$listenerClassName = $listener->getType();
// create a new instance of the listener class
/** @var \League\Event\ListenerInterface $listenerInstance */
$listenerInstance = new $listenerClassName();
// query whether we've to inject the application server instance or not
if ($listenerInstance instanceof ApplicationServerAwareListenerInterface) {
$listenerInstance->injectApplicationServer($this);
}
// add the listeners
$emitter->addListener($listener->getEvent(), $listenerInstance);
}
// synchronize the emitter
$this->emitter = $emitter;
// override the default runlevel with the value found in the bootstrap configuration
$this->runlevel = $this->runlevelFromString($bootstrapNode->getDefaultRunlevel());
// flag to keep the server running or to stop it
$keepRunning = true;
// initialize the actual runlevel with -1
$actualRunlevel = -1;
// start with the default runlevel
$this->init(null, $this->runlevel);
do {
try {
switch ($this->command) {
case InitCommand::COMMAND:
// copy command params -> the requested runlevel in that case
$this->runlevel = $this->params;
if ($this->runlevel == ApplicationServerInterface::REBOOT) {
// backup the runlevel
$backupRunlevel = $actualRunlevel;
// shutdown the application server
for ($i = $actualRunlevel; $i >= ApplicationServerInterface::SHUTDOWN; $i--) {
$this->emitter->emit(sprintf('leave.runlevel.%s', $this->runlevelToString($i)), $i);
// stop the services of the PREVIOUS runlevel
$this->doStopServices($i + 1);
}
// switch back to the runlevel we backed up before
for ($z = ApplicationServerInterface::SHUTDOWN; $z <= $backupRunlevel; $z++) {
$this->emitter->emit(sprintf('enter.runlevel.%s', $this->runlevelToString($z)), $z);
}
// set the runlevel to the one before we restart
$actualRunlevel = $backupRunlevel;
// reset the runlevel and the params
$this->runlevel = $this->params = $actualRunlevel;
} elseif ($actualRunlevel == ApplicationServerInterface::SHUTDOWN) {
// we want to shutdown the application server
$keepRunning = false;
} elseif ($actualRunlevel < $this->runlevel) {
// switch to the requested runlevel
for ($i = $actualRunlevel + 1; $i <= $this->runlevel; $i++) {
$this->emitter->emit(sprintf('enter.runlevel.%s', $this->runlevelToString($i)), $i);
}
// set the new runlevel
$actualRunlevel = $this->runlevel;
} elseif ($actualRunlevel > $this->runlevel) {
// switch down to the requested runlevel
for ($i = $actualRunlevel; $i >= $this->runlevel; $i--) {
$this->emitter->emit(sprintf('leave.runlevel.%s', $this->runlevelToString($i)), $i);
// stop the services of the PREVIOUS runlevel
$this->doStopServices($i + 1);
}
// set the new runlevel
$actualRunlevel = $this->runlevel;
} else {
// signal that we've finished switching the runlevels and wait
$this->locked = false;
$this->command = null;
// print a message and wait
$this->getSystemLogger()->info(sprintf('Switched to runlevel %s!!!', $actualRunlevel));
// wait for a new command
$this->synchronized(function ($self) {
$self->wait();
}, $this);
}
break;
case ModeCommand::COMMAND:
// switch the application server mode
$this->doSwitchSetupMode($this->params, $this->getConfigurationFilename());
// singal that we've finished setting umask and wait
$this->locked = false;
$this->command = null;
// wait for a new command
$this->synchronized(function ($self) {
$self->wait();
}, $this);
break;
case DoctrineCommand::COMMAND:
// execute the Doctrine command
$this->result = $this->doDoctrine($this->params);
// singal that we've finished setting umask and wait
$this->locked = false;
$this->command = null;
// wait for a new command
$this->synchronized(function ($self) {
$self->wait();
}, $this);
break;
default:
// print a message and wait
$this->getSystemLogger()->info('Can\'t find any command!!!');
// singal that we've finished setting umask and wait
$this->locked = false;
// wait for a new command
$this->synchronized(function ($self) {
$self->wait();
}, $this);
break;
}
} catch (\Exception $e) {
$this->getSystemLogger()->error($e->getMessage());
}
} while ($keepRunning);
}