Scalr\Observer\MessagingEventObserver::OnHostDown PHP Method

OnHostDown() public method

See also: Scalr\Observer\AbstractEventObserver::OnHostDown()
public OnHostDown ( HostDownEvent $event )
$event HostDownEvent
    public function OnHostDown(HostDownEvent $event)
    {
        if ($event->DBServer->IsRebooting() == 1) {
            $event->exit = 'reboot';
            return;
        }
        if (!$this->FarmID) {
            $event->exit = 'no-farm';
            return;
        }
        $dbFarm = DBFarm::LoadByID($this->FarmID);
        // There is no sense in sending mesages to the Servers in terminated Farm
        if ($dbFarm->Status == FARM_STATUS::TERMINATED) {
            $event->exit = 'farm-terminated';
            return;
        }
        $servers = $dbFarm->GetServersByFilter(['status' => [SERVER_STATUS::RUNNING]]);
        try {
            $DBFarmRole = $event->DBServer->GetFarmRoleObject();
            $DBRole = $event->DBServer->GetFarmRoleObject()->GetRoleObject();
        } catch (Exception $e) {
        }
        //FIXME Igor: HUGE BUG HERE!
        $first_in_role_handled = false;
        $first_in_role_server = null;
        $event->msgExpected = count($servers);
        foreach ($servers as $dbServer) {
            if (!$dbServer instanceof DBServer) {
                continue;
            }
            if (!$dbServer->isScalarized) {
                $event->msgExpected--;
                continue;
            }
            $isfirstinrole = '0';
            $eventServerIsMaster = $event->DBServer->GetProperty(SERVER_PROPERTIES::DB_MYSQL_MASTER) || $event->DBServer->GetProperty(Scalr_Db_Msr::REPLICATION_MASTER);
            if ($eventServerIsMaster && !$first_in_role_handled) {
                if ($dbServer->farmRoleId == $event->DBServer->farmRoleId) {
                    if ($dbServer->GetFarmRoleObject()->GetRoleObject()->hasBehavior(ROLE_BEHAVIORS::MYSQL) || $dbServer->GetFarmRoleObject()->GetRoleObject()->getDbMsrBehavior()) {
                        $first_in_role_handled = true;
                        $first_in_role_server = $dbServer;
                        $isfirstinrole = '1';
                    }
                }
            }
            $msg = new Scalr_Messaging_Msg_HostDown();
            $msg->behaviour = $DBRole ? $DBRole->getBehaviors() : '*Unknown*';
            $msg->roleName = $DBRole ? $DBRole->name : '*Unknown*';
            $msg->localIp = $event->DBServer->localIp;
            $msg->remoteIp = $event->DBServer->remoteIp;
            $msg->isFirstInRole = $isfirstinrole;
            $msg->serverIndex = $event->DBServer->index;
            $msg->farmRoleId = $event->DBServer->farmRoleId;
            $msg->serverId = $event->DBServer->serverId;
            $msg->cloudLocation = $event->DBServer->GetCloudLocation();
            // If FarmRole was removed from farm, no configuration left
            if ($DBFarmRole) {
                $msg = Scalr_Scripting_Manager::extendMessage($msg, $event, $event->DBServer, $dbServer);
                if ($event->DBServer->farmRoleId != 0) {
                    foreach (Scalr_Role_Behavior::getListForRole($event->DBServer->GetFarmRoleObject()->GetRoleObject()) as $behavior) {
                        $msg = $behavior->extendMessage($msg, $event->DBServer);
                    }
                }
            }
            $msg = $dbServer->SendMessage($msg, false, true);
            if ($msg) {
                $event->msgCreated++;
            }
            $loopServerIsMaster = $dbServer->GetProperty(SERVER_PROPERTIES::DB_MYSQL_MASTER) || $dbServer->GetProperty(Scalr_Db_Msr::REPLICATION_MASTER);
            if ($loopServerIsMaster && $dbServer->status == SERVER_STATUS::RUNNING) {
                $doNotPromoteSlave2Master = true;
            }
        }
        if (!$DBFarmRole) {
            return;
        }
        if ($DBFarmRole->GetRoleObject()->getDbMsrBehavior() && !$doNotPromoteSlave2Master && !$DBFarmRole->GetSetting(Scalr_Db_Msr::SLAVE_TO_MASTER)) {
            $this->sendPromoteToMasterMessage($event);
        }
        //LEGACY MYSQL CODE:
        if ($DBFarmRole->GetRoleObject()->hasBehavior(ROLE_BEHAVIORS::MYSQL)) {
            // If EC2 master down
            if ($event->DBServer->GetProperty(SERVER_PROPERTIES::DB_MYSQL_MASTER) && $DBFarmRole) {
                $master = $dbFarm->GetMySQLInstances(true);
                if ($master[0]) {
                    return;
                }
                $msg = new Scalr_Messaging_Msg_Mysql_PromoteToMaster($DBFarmRole->GetSetting(Entity\FarmRoleSetting::MYSQL_ROOT_PASSWORD), $DBFarmRole->GetSetting(Entity\FarmRoleSetting::MYSQL_REPL_PASSWORD), $DBFarmRole->GetSetting(Entity\FarmRoleSetting::MYSQL_STAT_PASSWORD));
                if ($event->DBServer->IsSupported("0.7")) {
                    if (in_array($event->DBServer->platform, [SERVER_PLATFORMS::EC2, SERVER_PLATFORMS::CLOUDSTACK, SERVER_PLATFORMS::IDCF])) {
                        try {
                            $volume = Scalr_Storage_Volume::init()->loadById($DBFarmRole->GetSetting(Entity\FarmRoleSetting::MYSQL_SCALR_VOLUME_ID));
                            $msg->volumeConfig = $volume->getConfig();
                        } catch (Exception $e) {
                            $this->Logger->error(new FarmLogMessage($event->DBServer, "Cannot create volumeConfig for PromoteToMaster message: {$e->getMessage()}"));
                        }
                    }
                } elseif ($event->DBServer->platform == SERVER_PLATFORMS::EC2) {
                    $msg->volumeId = $DBFarmRole->GetSetting(Entity\FarmRoleSetting::MYSQL_MASTER_EBS_VOLUME_ID);
                }
                // Send Mysql_PromoteToMaster to the first server in the same avail zone as old master (if exists)
                // Otherwise send to first in role
                $platform = $event->DBServer->platform;
                if ($platform == SERVER_PLATFORMS::EC2) {
                    $availZone = $event->DBServer->GetProperty(EC2_SERVER_PROPERTIES::AVAIL_ZONE);
                }
                foreach ($servers as $DBServer) {
                    if ($DBServer->serverId == $event->DBServer->serverId) {
                        continue;
                    }
                    if ($platform == SERVER_PLATFORMS::EC2 && $DBServer->GetProperty(EC2_SERVER_PROPERTIES::AVAIL_ZONE) == $availZone || $platform != SERVER_PLATFORMS::EC2) {
                        if ($DBServer->GetFarmRoleObject()->GetRoleObject()->hasBehavior(ROLE_BEHAVIORS::MYSQL)) {
                            $DBFarmRole->SetSetting(Entity\FarmRoleSetting::MYSQL_SLAVE_TO_MASTER, 1);
                            $DBServer->SetProperty(SERVER_PROPERTIES::DB_MYSQL_MASTER, 1);
                            $DBServer->SendMessage($msg, false, true);
                            return;
                        }
                    }
                }
                if ($first_in_role_server) {
                    $DBFarmRole->SetSetting(Entity\FarmRoleSetting::MYSQL_SLAVE_TO_MASTER, 1);
                    $first_in_role_server->SetProperty(SERVER_PROPERTIES::DB_MYSQL_MASTER, 1);
                    $first_in_role_server->SendMessage($msg, false, true);
                }
            }
        }
    }