diff --git a/library/Director/Daemon/BackgroundDaemon.php b/library/Director/Daemon/BackgroundDaemon.php index 25d0ebc9..128ab52a 100644 --- a/library/Director/Daemon/BackgroundDaemon.php +++ b/library/Director/Daemon/BackgroundDaemon.php @@ -147,6 +147,14 @@ class BackgroundDaemon // TODO: level is sent but not used $processState->setComponentState('db', $state); }); + $db->on('schemaChange', function ($startupSchema, $dbSchema) { + Logger::info(sprintf( + "DB schema version changed. Started with %d, DB has %d. Restarting.", + $startupSchema, + $dbSchema + )); + $this->reload(); + }); $db->setConfigWatch( $dbResourceName diff --git a/library/Director/Daemon/DaemonDb.php b/library/Director/Daemon/DaemonDb.php index e9005f16..730c0e4e 100644 --- a/library/Director/Daemon/DaemonDb.php +++ b/library/Director/Daemon/DaemonDb.php @@ -47,8 +47,15 @@ class DaemonDb /** @var Deferred|null */ protected $pendingDisconnect; + /** @var \React\EventLoop\TimerInterface */ protected $refreshTimer; + /** @var \React\EventLoop\TimerInterface */ + protected $schemaCheckTimer; + + /** @var int */ + protected $startupSchemaVersion; + public function __construct(DaemonProcessDetails $details, $dbConfig = null) { $this->details = $details; @@ -84,6 +91,9 @@ class DaemonDb $this->refreshTimer = $loop->addPeriodicTimer(3, function () { $this->refreshMyState(); }); + $this->schemaCheckTimer = $loop->addPeriodicTimer(15, function () { + $this->checkDbSchema(); + }); if ($this->configWatch) { $this->configWatch->run($this->loop); } @@ -148,7 +158,8 @@ class DaemonDb if ($this->hasAnyOtherActiveInstance($connection)) { throw new RuntimeException('DB is locked by a running daemon instance'); } - $this->details->set('schema_version', $migrations->getLastMigrationNumber()); + $this->startupSchemaVersion = $migrations->getLastMigrationNumber(); + $this->details->set('schema_version', $this->startupSchemaVersion); $this->connection = $connection; $this->db = $connection->getDbAdapter(); @@ -159,6 +170,42 @@ class DaemonDb return $connection; } + protected function checkDbSchema() + { + if ($this->connection === null) { + return; + } + + if ($this->schemaIsOutdated()) { + $this->emit('schemaChange', [ + $this->getStartupSchemaVersion(), + $this->getDbSchemaVersion() + ]); + } + } + + protected function schemaIsOutdated() + { + return $this->getStartupSchemaVersion() < $this->getDbSchemaVersion(); + } + + protected function getStartupSchemaVersion() + { + return $this->startupSchemaVersion; + } + + protected function getDbSchemaVersion() + { + if ($this->connection === null) { + throw new RuntimeException( + 'Cannot determine DB schema version without an established DB connection' + ); + } + $migrations = new Migrations($this->connection); + + return $migrations->getLastMigrationNumber(); + } + protected function onConnected() { $this->emitStatus('connected');