LCOV - code coverage report
Current view: top level - serverManager/common/source - SessionServerAppManager.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 98.0 % 345 338
Test Date: 2026-09-11 17:36:12 Functions: 100.0 % 43 43

            Line data    Source code
       1              : /*
       2              :  * If not stated otherwise in this file or this component's LICENSE file the
       3              :  * following copyright and licenses apply:
       4              :  *
       5              :  * Copyright 2022 Sky UK
       6              :  *
       7              :  * Licensed under the Apache License, Version 2.0 (the "License");
       8              :  * you may not use this file except in compliance with the License.
       9              :  * You may obtain a copy of the License at
      10              :  *
      11              :  * http://www.apache.org/licenses/LICENSE-2.0
      12              :  *
      13              :  * Unless required by applicable law or agreed to in writing, software
      14              :  * distributed under the License is distributed on an "AS IS" BASIS,
      15              :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      16              :  * See the License for the specific language governing permissions and
      17              :  * limitations under the License.
      18              :  */
      19              : 
      20              : #include "SessionServerAppManager.h"
      21              : #include "RialtoServerManagerLogging.h"
      22              : #include "Utils.h"
      23              : #include <algorithm>
      24              : #include <future>
      25              : #include <utility>
      26              : 
      27              : namespace rialto::servermanager::common
      28              : {
      29           45 : SessionServerAppManager::SessionServerAppManager(
      30              :     std::unique_ptr<ipc::IController> &ipcController, const std::shared_ptr<service::IStateObserver> &stateObserver,
      31              :     std::unique_ptr<ISessionServerAppFactory> &&sessionServerAppFactory,
      32              :     std::unique_ptr<IHealthcheckServiceFactory> &&healthcheckServiceFactory,
      33              :     const std::shared_ptr<firebolt::rialto::common::IEventThreadFactory> &eventThreadFactory,
      34           45 :     const firebolt::rialto::ipc::INamedSocketFactory &namedSocketFactory)
      35           45 :     : m_ipcController{ipcController},
      36           90 :       m_eventThread{eventThreadFactory->createEventThread("rialtoservermanager-appmanager")},
      37           45 :       m_sessionServerAppFactory{std::move(sessionServerAppFactory)}, m_stateObserver{stateObserver},
      38           45 :       m_healthcheckService{healthcheckServiceFactory->createHealthcheckService(*this)},
      39          135 :       m_namedSocketFactory{namedSocketFactory}, m_isShuttingDown{false}
      40              : {
      41           45 : }
      42              : 
      43           90 : SessionServerAppManager::~SessionServerAppManager()
      44              : {
      45           45 :     m_eventThread->add(&SessionServerAppManager::shutdownAllSessionServers, this);
      46           45 :     m_eventThread->flush();
      47           45 :     m_eventThread.reset();
      48           90 : }
      49              : 
      50           48 : void SessionServerAppManager::setShuttingDown()
      51              : {
      52           48 :     m_isShuttingDown = true;
      53              : }
      54              : 
      55            8 : void SessionServerAppManager::preloadSessionServers(unsigned numOfPreloadedServers)
      56              : {
      57            8 :     m_eventThread->add(
      58            8 :         [this, numOfPreloadedServers]()
      59              :         {
      60           16 :             for (unsigned i = 0; i < numOfPreloadedServers; ++i)
      61              :             {
      62            8 :                 connectSessionServer(preloadSessionServer());
      63              :             }
      64            8 :         });
      65              : }
      66              : 
      67           38 : bool SessionServerAppManager::initiateApplication(const std::string &appName,
      68              :                                                   const firebolt::rialto::common::SessionServerState &state,
      69              :                                                   const firebolt::rialto::common::AppConfig &appConfig)
      70              : {
      71           38 :     std::promise<bool> p;
      72           38 :     std::future<bool> f{p.get_future()};
      73           76 :     m_eventThread->add([&]() { return p.set_value(handleInitiateApplication(appName, state, appConfig)); });
      74           76 :     return f.get();
      75           38 : }
      76              : 
      77           38 : bool SessionServerAppManager::handleInitiateApplication(const std::string &appName,
      78              :                                                         const firebolt::rialto::common::SessionServerState &state,
      79              :                                                         const firebolt::rialto::common::AppConfig &appConfig)
      80              : {
      81           38 :     RIALTO_SERVER_MANAGER_LOG_INFO("RialtoServerManager requests to launch %s with initial state: %s", appName.c_str(),
      82              :                                    toString(state));
      83          113 :     if (state != firebolt::rialto::common::SessionServerState::NOT_RUNNING &&
      84           38 :         state != firebolt::rialto::common::SessionServerState::SUSPENDED && !getServerByAppName(appName))
      85              :     {
      86           36 :         auto preloadedServer{getPreloadedServer()};
      87           36 :         if (preloadedServer)
      88              :         {
      89            5 :             return configurePreloadedSessionServer(preloadedServer, appName, state, appConfig,
      90           10 :                                                    m_namedSocketFactory.createNamedSocket());
      91              :         }
      92           31 :         return connectSessionServer(launchSessionServer(appName, state, appConfig));
      93           36 :     }
      94            2 :     else if (state == firebolt::rialto::common::SessionServerState::NOT_RUNNING ||
      95            1 :              state == firebolt::rialto::common::SessionServerState::SUSPENDED)
      96              :     {
      97            1 :         RIALTO_SERVER_MANAGER_LOG_ERROR("Initialization of %s failed - wrong state", appName.c_str());
      98              :     }
      99              :     else
     100              :     {
     101            1 :         RIALTO_SERVER_MANAGER_LOG_ERROR("Initialization of %s failed. App is already launched", appName.c_str());
     102              :     }
     103            2 :     return false;
     104              : }
     105              : 
     106           14 : bool SessionServerAppManager::setSessionServerState(const std::string &appName,
     107              :                                                     const firebolt::rialto::common::SessionServerState &newState)
     108              : {
     109           14 :     std::promise<bool> p;
     110           14 :     std::future<bool> f{p.get_future()};
     111           28 :     m_eventThread->add([&]() { return p.set_value(changeSessionServerState(appName, newState)); });
     112           28 :     return f.get();
     113           14 : }
     114              : 
     115           30 : void SessionServerAppManager::onSessionServerStateChanged(int serverId,
     116              :                                                           const firebolt::rialto::common::SessionServerState &newState)
     117              : {
     118           30 :     RIALTO_SERVER_MANAGER_LOG_DEBUG("Queue state change of serverId: %d to %s", serverId, toString(newState));
     119              :     // Event loop needed here, as function caller may be deleted as a result of this call
     120           30 :     m_eventThread->add(&SessionServerAppManager::handleSessionServerStateChange, this, serverId, newState);
     121              : }
     122              : 
     123            3 : void SessionServerAppManager::sendPingEvents(int pingId)
     124              : {
     125            3 :     RIALTO_SERVER_MANAGER_LOG_DEBUG("Queue ping procedure with id: %d", pingId);
     126            3 :     m_eventThread->add(
     127            3 :         [this, pingId]()
     128              :         {
     129            3 :             if (m_healthcheckService)
     130              :             {
     131            6 :                 for (const auto &sessionServer : m_sessionServerApps)
     132              :                 {
     133            3 :                     const auto kSessionServerState{sessionServer->getExpectedState()};
     134            3 :                     if (firebolt::rialto::common::SessionServerState::SUSPENDED == kSessionServerState ||
     135            2 :                         firebolt::rialto::common::SessionServerState::NOT_RUNNING == kSessionServerState)
     136              :                     {
     137            1 :                         RIALTO_SERVER_MANAGER_LOG_DEBUG("Ping with id: %d skipped for server: %d as it is in state: %s",
     138              :                                                         pingId, sessionServer->getServerId(),
     139              :                                                         toString(kSessionServerState));
     140            2 :                         continue;
     141              :                     }
     142            2 :                     auto serverId{sessionServer->getServerId()};
     143            2 :                     if (!m_ipcController->performPing(serverId, pingId))
     144              :                     {
     145            1 :                         RIALTO_SERVER_MANAGER_LOG_ERROR("Ping with id: %d failed for server: %d", pingId, serverId);
     146            1 :                         m_healthcheckService->onPingFailed(serverId, pingId);
     147            1 :                         continue;
     148              :                     }
     149            1 :                     m_healthcheckService->onPingSent(serverId, pingId);
     150              :                 }
     151              :             }
     152            3 :         });
     153              : }
     154              : 
     155            2 : void SessionServerAppManager::onAck(int serverId, int pingId, bool success)
     156              : {
     157            2 :     RIALTO_SERVER_MANAGER_LOG_DEBUG("Queue ack handling for serverId: %d ping id: %d", serverId, pingId);
     158            2 :     m_eventThread->add(&SessionServerAppManager::handleAck, this, serverId, pingId, success);
     159              : }
     160              : 
     161            7 : std::string SessionServerAppManager::getAppConnectionInfo(const std::string &appName) const
     162              : {
     163            7 :     std::promise<std::string> p;
     164            7 :     std::future<std::string> f{p.get_future()};
     165            7 :     m_eventThread->add(
     166            7 :         [&]()
     167              :         {
     168            7 :             auto sessionServer{getServerByAppName(appName)};
     169            7 :             if (sessionServer)
     170              :             {
     171            1 :                 return p.set_value(sessionServer->getSessionManagementSocketName());
     172              :             }
     173            6 :             RIALTO_SERVER_MANAGER_LOG_ERROR("App: %s could not be found", appName.c_str());
     174           18 :             return p.set_value("");
     175            7 :         });
     176           14 :     return f.get();
     177            7 : }
     178              : 
     179            2 : bool SessionServerAppManager::setLogLevels(const service::LoggingLevels &logLevels) const
     180              : {
     181            2 :     std::promise<bool> p;
     182            2 :     std::future<bool> f{p.get_future()};
     183            2 :     m_eventThread->add(
     184            2 :         [&]()
     185              :         {
     186            2 :             setLocalLogLevels(logLevels);
     187            2 :             if (!m_ipcController->setLogLevels(logLevels))
     188              :             {
     189            1 :                 RIALTO_SERVER_MANAGER_LOG_WARN("Change log levels failed.");
     190            1 :                 return p.set_value(false);
     191              :             }
     192            1 :             RIALTO_SERVER_MANAGER_LOG_INFO("Change log levels succeeded.");
     193            1 :             return p.set_value(true);
     194              :         });
     195            4 :     return f.get();
     196            2 : }
     197              : 
     198            4 : void SessionServerAppManager::restartServer(int serverId)
     199              : {
     200            4 :     RIALTO_SERVER_MANAGER_LOG_DEBUG("Queue restart server handling for serverId: %d", serverId);
     201            4 :     m_eventThread->add(&SessionServerAppManager::handleRestartServer, this, serverId);
     202              : }
     203              : 
     204            4 : void SessionServerAppManager::handleRestartServer(int serverId)
     205              : {
     206            4 :     if (m_isShuttingDown)
     207              :     {
     208            1 :         RIALTO_SERVER_MANAGER_LOG_DEBUG("Not restarting serverId: %d as server manager is shutting down", serverId);
     209            3 :         return;
     210              :     }
     211            3 :     auto sessionServer{getServerById(serverId)};
     212            3 :     if (!sessionServer)
     213              :     {
     214            0 :         RIALTO_SERVER_MANAGER_LOG_WARN("Unable to restart server, serverId: %d", serverId);
     215            0 :         return;
     216              :     }
     217            3 :     if (m_healthcheckService)
     218              :     {
     219            3 :         m_healthcheckService->onServerRemoved(sessionServer->getServerId());
     220              :     }
     221              :     // First, get all needed information from current app
     222            3 :     const std::string kAppName{sessionServer->getAppName()};
     223            3 :     const firebolt::rialto::common::SessionServerState kState{sessionServer->getExpectedState()};
     224            3 :     const firebolt::rialto::common::AppConfig kAppConfig{sessionServer->getSessionManagementSocketName(),
     225            3 :                                                          sessionServer->getClientDisplayName()};
     226            3 :     std::unique_ptr<firebolt::rialto::ipc::INamedSocket> namedSocket{std::move(sessionServer->releaseNamedSocket())};
     227            3 :     if (firebolt::rialto::common::SessionServerState::INACTIVE != kState &&
     228            2 :         firebolt::rialto::common::SessionServerState::ACTIVE != kState)
     229              :     {
     230            2 :         RIALTO_SERVER_MANAGER_LOG_DEBUG("Restart server to %s not needed for serverId: %d", toString(kState), serverId);
     231            2 :         return;
     232              :     }
     233            1 :     RIALTO_SERVER_MANAGER_LOG_DEBUG("Restarting server with id: %d", serverId);
     234              :     // Then kill the app
     235            1 :     sessionServer->kill();
     236            1 :     handleSessionServerStateChange(serverId, firebolt::rialto::common::SessionServerState::NOT_RUNNING);
     237            1 :     sessionServer.reset();
     238              : 
     239              :     // Finally, spawn the new app with old settings and set named socket if present
     240            1 :     auto app = m_sessionServerAppFactory->create(kAppName, kState, kAppConfig, *this, std::move(namedSocket));
     241            1 :     if (app->launch())
     242              :     {
     243            1 :         auto result = m_sessionServerApps.emplace(std::move(app));
     244            1 :         if (result.second)
     245              :         {
     246            1 :             connectSessionServer(*result.first);
     247              :         }
     248              :     }
     249              :     else
     250              :     {
     251            0 :         RIALTO_SERVER_MANAGER_LOG_ERROR("Failed to restart server");
     252              :     }
     253            9 : }
     254              : 
     255            3 : bool SessionServerAppManager::resurrectSuspendedServer(const std::shared_ptr<ISessionServerApp> &kSessionServer,
     256              :                                                        const firebolt::rialto::common::SessionServerState &state)
     257              : {
     258            3 :     const std::string kAppName{kSessionServer->getAppName()};
     259            3 :     const firebolt::rialto::common::AppConfig kAppConfig{kSessionServer->getSessionManagementSocketName(),
     260            3 :                                                          kSessionServer->getClientDisplayName()};
     261            3 :     std::unique_ptr<firebolt::rialto::ipc::INamedSocket> namedSocket{std::move(kSessionServer->releaseNamedSocket())};
     262            3 :     m_sessionServerApps.erase(kSessionServer);
     263              : 
     264            3 :     RIALTO_SERVER_MANAGER_LOG_INFO("Resurrecting server for app: %s", kAppName.c_str());
     265            3 :     auto app{getPreloadedServer()};
     266            3 :     if (app)
     267              :     {
     268            1 :         configurePreloadedSessionServer(app, kAppName, state, kAppConfig, std::move(namedSocket));
     269            1 :         m_sessionServerApps.emplace(std::move(app));
     270            1 :         return true;
     271              :     }
     272            2 :     app = m_sessionServerAppFactory->create(kAppName, state, kAppConfig, *this, std::move(namedSocket));
     273            2 :     if (app->launch())
     274              :     {
     275            1 :         auto result = m_sessionServerApps.emplace(std::move(app));
     276            1 :         if (result.second)
     277              :         {
     278            1 :             return connectSessionServer(*result.first);
     279              :         }
     280              :     }
     281              :     else
     282              :     {
     283            1 :         RIALTO_SERVER_MANAGER_LOG_ERROR("Failed to resurrect suspended server for %s", kAppName.c_str());
     284              :     }
     285            1 :     return false;
     286            3 : }
     287              : 
     288           48 : bool SessionServerAppManager::connectSessionServer(const std::shared_ptr<ISessionServerApp> &kSessionServer)
     289              : {
     290           48 :     if (!kSessionServer)
     291              :     {
     292            7 :         RIALTO_SERVER_MANAGER_LOG_ERROR("Unable to connect Session Server - pointer is null!");
     293            7 :         return false;
     294              :     }
     295           41 :     if (!m_ipcController->createClient(kSessionServer->getServerId(), kSessionServer->getAppManagementSocketName()))
     296              :     {
     297            2 :         RIALTO_SERVER_MANAGER_LOG_ERROR("Failed to establish RialtoServerManager - RialtoSessionServer connection for "
     298              :                                         "session server with id: %d",
     299              :                                         kSessionServer->getServerId());
     300            2 :         kSessionServer->kill();
     301            2 :         if (m_healthcheckService)
     302              :         {
     303            2 :             m_healthcheckService->onServerRemoved(kSessionServer->getServerId());
     304              :         }
     305            2 :         m_sessionServerApps.erase(kSessionServer);
     306            2 :         return false;
     307              :     }
     308           39 :     RIALTO_SERVER_MANAGER_LOG_INFO("RialtoServerManager with id %d successfully connected",
     309              :                                    kSessionServer->getServerId());
     310           39 :     return true;
     311              : }
     312              : 
     313           14 : bool SessionServerAppManager::configureSessionServer(const std::shared_ptr<ISessionServerApp> &kSessionServer)
     314              : {
     315           14 :     if (!kSessionServer)
     316              :     {
     317            0 :         RIALTO_SERVER_MANAGER_LOG_ERROR("Unable to configure Session Server - pointer is null!");
     318            0 :         return false;
     319              :     }
     320           14 :     if (kSessionServer->isNamedSocketInitialized())
     321              :     {
     322            3 :         return configureSessionServerWithSocketFd(kSessionServer);
     323              :     }
     324           11 :     return configureSessionServerWithSocketName(kSessionServer);
     325              : }
     326              : 
     327            6 : bool SessionServerAppManager::configurePreloadedSessionServer(
     328              :     const std::shared_ptr<ISessionServerApp> &kSessionServer, const std::string &appName,
     329              :     const firebolt::rialto::common::SessionServerState &state, const firebolt::rialto::common::AppConfig &appConfig,
     330              :     std::unique_ptr<firebolt::rialto::ipc::INamedSocket> &&namedSocket)
     331              : {
     332            6 :     RIALTO_SERVER_MANAGER_LOG_INFO("Configuration of preloaded session server with id: %d for %s app",
     333              :                                    kSessionServer->getServerId(), appName.c_str());
     334           11 :     if (kSessionServer->configure(appName, state, appConfig, std::move(namedSocket)) &&
     335            5 :         configureSessionServer(kSessionServer))
     336              :     {
     337              :         // Schedule adding new preloaded session server (as we've just used one) and return immediately
     338            8 :         m_eventThread->add([this]() { connectSessionServer(preloadSessionServer()); });
     339            4 :         return true;
     340              :     }
     341              :     // Configuration failed, kill server and return error
     342            2 :     handleSessionServerStateChange(kSessionServer->getServerId(), firebolt::rialto::common::SessionServerState::ERROR);
     343            2 :     kSessionServer->kill();
     344            2 :     handleSessionServerStateChange(kSessionServer->getServerId(),
     345              :                                    firebolt::rialto::common::SessionServerState::NOT_RUNNING);
     346              :     // Schedule adding new preloaded session server
     347            4 :     m_eventThread->add([this]() { connectSessionServer(preloadSessionServer()); });
     348            2 :     return false;
     349              : }
     350              : 
     351           14 : bool SessionServerAppManager::changeSessionServerState(const std::string &appName,
     352              :                                                        const firebolt::rialto::common::SessionServerState &newState)
     353              : {
     354           14 :     RIALTO_SERVER_MANAGER_LOG_MIL("RialtoServerManager requests to change state of %s to %s", appName.c_str(),
     355              :                                   toString(newState));
     356           14 :     auto sessionServer{getServerByAppName(appName)};
     357           14 :     if (!sessionServer)
     358              :     {
     359            2 :         RIALTO_SERVER_MANAGER_LOG_ERROR("Change state of %s to %s failed - session server not found.", appName.c_str(),
     360              :                                         toString(newState));
     361            2 :         return false;
     362              :     }
     363           12 :     const firebolt::rialto::common::SessionServerState kCurrentState{sessionServer->getExpectedState()};
     364           12 :     sessionServer->setExpectedState(newState);
     365           12 :     if (kCurrentState == firebolt::rialto::common::SessionServerState::SUSPENDED &&
     366            4 :         (firebolt::rialto::common::SessionServerState::ACTIVE == newState ||
     367            1 :          firebolt::rialto::common::SessionServerState::INACTIVE == newState))
     368              :     {
     369            3 :         return resurrectSuspendedServer(sessionServer, newState);
     370              :     }
     371            9 :     else if (kCurrentState == firebolt::rialto::common::SessionServerState::SUSPENDED &&
     372            1 :              firebolt::rialto::common::SessionServerState::NOT_RUNNING == newState)
     373              :     {
     374              :         // Send the notification and do the cleanup only
     375            1 :         handleSessionServerStateChange(sessionServer->getServerId(), newState);
     376            1 :         return true;
     377              :     }
     378           15 :     else if (m_healthcheckService && (firebolt::rialto::common::SessionServerState::NOT_RUNNING == newState ||
     379           15 :                                       firebolt::rialto::common::SessionServerState::SUSPENDED == newState))
     380              :     {
     381            6 :         m_healthcheckService->onServerRemoved(sessionServer->getServerId());
     382              :     }
     383            8 :     if (!m_ipcController->performSetState(sessionServer->getServerId(), newState))
     384              :     {
     385            2 :         RIALTO_SERVER_MANAGER_LOG_ERROR("Change state of %s to %s failed.", appName.c_str(), toString(newState));
     386            2 :         handleStateChangeFailure(sessionServer, newState);
     387            2 :         return false;
     388              :     }
     389            6 :     RIALTO_SERVER_MANAGER_LOG_INFO("Change state of %s to %s succeeded.", appName.c_str(), toString(newState));
     390            6 :     return true;
     391           14 : }
     392              : 
     393           44 : void SessionServerAppManager::handleSessionServerStateChange(int serverId,
     394              :                                                              firebolt::rialto::common::SessionServerState newState)
     395              : {
     396           44 :     RIALTO_SERVER_MANAGER_LOG_INFO("SessionServer with id: %d changed state to %s", serverId, toString(newState));
     397           44 :     if (m_isShuttingDown)
     398              :     {
     399            1 :         RIALTO_SERVER_MANAGER_LOG_WARN("Not handling state change of serverId: %d as server manager is shutting down",
     400              :                                        serverId);
     401            1 :         return;
     402              :     }
     403           43 :     auto sessionServer{getServerById(serverId)};
     404           43 :     if (!sessionServer)
     405              :     {
     406            0 :         RIALTO_SERVER_MANAGER_LOG_WARN("SessionServer with id: %d not found", serverId);
     407            0 :         return;
     408              :     }
     409           43 :     std::string appName{sessionServer->getAppName()};
     410           43 :     if (!appName.empty() && m_stateObserver) // empty app name is when SessionServer is preloaded
     411              :     {
     412           33 :         m_stateObserver->stateChanged(appName, newState);
     413              :     }
     414           43 :     if (firebolt::rialto::common::SessionServerState::UNINITIALIZED == newState)
     415              :     {
     416           15 :         sessionServer->cancelStartupTimer();
     417           15 :         if (!sessionServer->isPreloaded() && !configureSessionServer(sessionServer))
     418              :         {
     419            2 :             handleSessionServerStateChange(serverId, firebolt::rialto::common::SessionServerState::ERROR);
     420            2 :             sessionServer->kill();
     421            2 :             handleSessionServerStateChange(serverId, firebolt::rialto::common::SessionServerState::NOT_RUNNING);
     422              :         }
     423              :     }
     424           28 :     else if (newState == firebolt::rialto::common::SessionServerState::ERROR && sessionServer->isPreloaded())
     425              :     {
     426            1 :         m_ipcController->removeClient(serverId);
     427            1 :         sessionServer->kill();
     428            1 :         if (m_healthcheckService)
     429              :         {
     430            1 :             m_healthcheckService->onServerRemoved(sessionServer->getServerId());
     431              :         }
     432            1 :         m_sessionServerApps.erase(sessionServer);
     433            1 :         if (!m_isShuttingDown)
     434              :         {
     435            1 :             connectSessionServer(preloadSessionServer());
     436              :         }
     437              :     }
     438           27 :     else if (newState == firebolt::rialto::common::SessionServerState::NOT_RUNNING)
     439              :     {
     440            9 :         m_ipcController->removeClient(serverId);
     441            9 :         if (m_healthcheckService)
     442              :         {
     443            9 :             m_healthcheckService->onServerRemoved(sessionServer->getServerId());
     444              :         }
     445            9 :         m_sessionServerApps.erase(sessionServer);
     446              :     }
     447           18 :     else if (newState == firebolt::rialto::common::SessionServerState::SUSPENDED)
     448              :     {
     449            5 :         m_ipcController->removeClient(sessionServer->getServerId());
     450            5 :         sessionServer->cleanup();
     451              :     }
     452           43 : }
     453              : 
     454            2 : void SessionServerAppManager::handleAck(int serverId, int pingId, bool success)
     455              : {
     456            2 :     if (success)
     457              :     {
     458            1 :         RIALTO_SERVER_MANAGER_LOG_DEBUG("Ping with id: %d succeeded for server: %d", pingId, serverId);
     459              :     }
     460              :     else
     461              :     {
     462            1 :         RIALTO_SERVER_MANAGER_LOG_ERROR("Ping with id: %d failed for server: %d", pingId, serverId);
     463              :     }
     464            2 :     if (m_healthcheckService)
     465              :     {
     466            2 :         m_healthcheckService->onAckReceived(serverId, pingId, success);
     467              :     }
     468              : }
     469              : 
     470           45 : void SessionServerAppManager::shutdownAllSessionServers()
     471              : {
     472           45 :     setShuttingDown();
     473           45 :     m_healthcheckService.reset();
     474           71 :     for (const auto &kSessionServer : m_sessionServerApps)
     475              :     {
     476           26 :         kSessionServer->kill();
     477              :     }
     478           45 :     m_sessionServerApps.clear();
     479              : }
     480              : 
     481              : std::shared_ptr<ISessionServerApp>
     482           31 : SessionServerAppManager::launchSessionServer(const std::string &appName,
     483              :                                              const firebolt::rialto::common::SessionServerState &kInitialState,
     484              :                                              const firebolt::rialto::common::AppConfig &appConfig)
     485              : {
     486           31 :     RIALTO_SERVER_MANAGER_LOG_INFO("Launching Rialto Session Server for %s", appName.c_str());
     487           31 :     auto app = m_sessionServerAppFactory->create(appName, kInitialState, appConfig, *this,
     488           31 :                                                  m_namedSocketFactory.createNamedSocket());
     489           31 :     if (app->launch())
     490              :     {
     491           30 :         if (m_sessionServerApps.emplace(app).second)
     492              :         {
     493           30 :             return app;
     494              :         }
     495              :     }
     496            1 :     return nullptr;
     497           31 : }
     498              : 
     499           15 : std::shared_ptr<ISessionServerApp> SessionServerAppManager::preloadSessionServer()
     500              : {
     501           15 :     RIALTO_SERVER_MANAGER_LOG_INFO("Preloading new Rialto Session Server");
     502           15 :     auto app = m_sessionServerAppFactory->create(*this);
     503           15 :     if (app->launch())
     504              :     {
     505            9 :         if (m_sessionServerApps.emplace(app).second)
     506              :         {
     507            9 :             return app;
     508              :         }
     509              :     }
     510            6 :     return nullptr;
     511           15 : }
     512              : 
     513           39 : std::shared_ptr<ISessionServerApp> SessionServerAppManager::getPreloadedServer() const
     514              : {
     515           39 :     auto iter = std::find_if(m_sessionServerApps.begin(), m_sessionServerApps.end(),
     516            6 :                              [](const auto &srv) { return srv->isPreloaded() && srv->isConnected(); });
     517           39 :     if (m_sessionServerApps.end() != iter)
     518              :     {
     519            6 :         return *iter;
     520              :     }
     521           33 :     return nullptr;
     522              : }
     523              : 
     524           58 : std::shared_ptr<ISessionServerApp> SessionServerAppManager::getServerByAppName(const std::string &appName) const
     525              : {
     526           58 :     auto iter{std::find_if(m_sessionServerApps.begin(), m_sessionServerApps.end(),
     527           19 :                            [&](const auto &srv) { return srv->getAppName() == appName; })};
     528           58 :     if (m_sessionServerApps.end() != iter)
     529              :     {
     530           14 :         return *iter;
     531              :     }
     532           44 :     return nullptr;
     533              : }
     534              : 
     535           48 : std::shared_ptr<ISessionServerApp> SessionServerAppManager::getServerById(int serverId) const
     536              : {
     537           48 :     auto iter{std::find_if(m_sessionServerApps.begin(), m_sessionServerApps.end(),
     538           47 :                            [&](const auto &srv) { return srv->getServerId() == serverId; })};
     539           48 :     if (m_sessionServerApps.end() != iter)
     540              :     {
     541           47 :         return *iter;
     542              :     }
     543            1 :     return nullptr;
     544              : }
     545              : 
     546            2 : void SessionServerAppManager::handleStateChangeFailure(const std::shared_ptr<ISessionServerApp> &kSessionServer,
     547              :                                                        const firebolt::rialto::common::SessionServerState &state)
     548              : {
     549            2 :     if (state == firebolt::rialto::common::SessionServerState::NOT_RUNNING ||
     550            1 :         state == firebolt::rialto::common::SessionServerState::SUSPENDED)
     551              :     {
     552            1 :         RIALTO_SERVER_MANAGER_LOG_WARN("Force change of %s to NotRunning.", kSessionServer->getAppName().c_str());
     553            1 :         kSessionServer->kill();
     554            1 :         handleSessionServerStateChange(kSessionServer->getServerId(), state);
     555              :     }
     556              :     else
     557              :     {
     558            1 :         handleSessionServerStateChange(kSessionServer->getServerId(),
     559              :                                        firebolt::rialto::common::SessionServerState::ERROR);
     560              :     }
     561            2 : }
     562              : 
     563           11 : bool SessionServerAppManager::configureSessionServerWithSocketName(const std::shared_ptr<ISessionServerApp> &kSessionServer)
     564              : {
     565           11 :     RIALTO_SERVER_MANAGER_LOG_DEBUG("Configuring Session Server using socket name");
     566           11 :     const auto kInitialState{kSessionServer->getInitialState()};
     567           11 :     const auto kSocketName{kSessionServer->getSessionManagementSocketName()};
     568           11 :     const auto kClientDisplayName{kSessionServer->getClientDisplayName()};
     569           11 :     const auto kSocketPermissions{kSessionServer->getSessionManagementSocketPermissions()};
     570           11 :     const auto kSocketOwner{kSessionServer->getSessionManagementSocketOwner()};
     571           11 :     const auto kSocketGroup{kSessionServer->getSessionManagementSocketGroup()};
     572           11 :     const auto &kAppName{kSessionServer->getAppName()};
     573              : 
     574           11 :     const firebolt::rialto::common::MaxResourceCapabilitites kMaxResource{kSessionServer->getMaxPlaybackSessions(),
     575           11 :                                                                           kSessionServer->getMaxWebAudioPlayers()};
     576           11 :     if (!m_ipcController->performSetConfiguration(kSessionServer->getServerId(), kInitialState, kSocketName,
     577              :                                                   kClientDisplayName, kMaxResource, kSocketPermissions, kSocketOwner,
     578              :                                                   kSocketGroup, kAppName))
     579              :     {
     580            2 :         RIALTO_SERVER_MANAGER_LOG_ERROR("Configuration of server with id %d failed - ipc error.",
     581              :                                         kSessionServer->getServerId());
     582            2 :         return false;
     583              :     }
     584            9 :     RIALTO_SERVER_MANAGER_LOG_INFO("Configuration of server with id %d succeeded.", kSessionServer->getServerId());
     585            9 :     return true;
     586           11 : }
     587              : 
     588            3 : bool SessionServerAppManager::configureSessionServerWithSocketFd(const std::shared_ptr<ISessionServerApp> &kSessionServer)
     589              : {
     590            3 :     RIALTO_SERVER_MANAGER_LOG_DEBUG("Configuring Session Server using socket fd");
     591            3 :     const auto kInitialState{kSessionServer->getInitialState()};
     592            3 :     const auto kSocketFd{kSessionServer->getSessionManagementSocketFd()};
     593            3 :     const auto kClientDisplayName{kSessionServer->getClientDisplayName()};
     594            3 :     const auto &kAppName{kSessionServer->getAppName()};
     595              : 
     596            3 :     const firebolt::rialto::common::MaxResourceCapabilitites kMaxResource{kSessionServer->getMaxPlaybackSessions(),
     597            3 :                                                                           kSessionServer->getMaxWebAudioPlayers()};
     598            3 :     if (!m_ipcController->performSetConfiguration(kSessionServer->getServerId(), kInitialState, kSocketFd,
     599              :                                                   kClientDisplayName, kMaxResource, kAppName))
     600              :     {
     601            1 :         RIALTO_SERVER_MANAGER_LOG_ERROR("Configuration of server with id %d failed - ipc error.",
     602              :                                         kSessionServer->getServerId());
     603            1 :         return false;
     604              :     }
     605            2 :     RIALTO_SERVER_MANAGER_LOG_INFO("Configuration of server with id %d succeeded.", kSessionServer->getServerId());
     606            2 :     return true;
     607            3 : }
     608              : 
     609            2 : void SessionServerAppManager::onServerStartupTimeout(int serverId)
     610              : {
     611            2 :     m_eventThread->add(&SessionServerAppManager::handleServerStartupTimeout, this, serverId);
     612              : }
     613              : 
     614            2 : void SessionServerAppManager::handleServerStartupTimeout(int serverId)
     615              : {
     616            2 :     auto sessionServer{getServerById(serverId)};
     617            2 :     if (!sessionServer)
     618              :     {
     619            1 :         RIALTO_SERVER_MANAGER_LOG_WARN("Unable to handle startup timeout for serverId: %d", serverId);
     620            1 :         return;
     621              :     }
     622            1 :     const bool isPreloaded{sessionServer->isPreloaded()};
     623            1 :     RIALTO_SERVER_MANAGER_LOG_WARN("Killing: %d", serverId);
     624            1 :     handleSessionServerStateChange(serverId, firebolt::rialto::common::SessionServerState::ERROR);
     625              : 
     626            1 :     if (!isPreloaded)
     627              :     {
     628            1 :         if (m_healthcheckService)
     629              :         {
     630            1 :             m_healthcheckService->onServerRemoved(sessionServer->getServerId());
     631              :         }
     632            1 :         sessionServer->kill();
     633            1 :         handleSessionServerStateChange(serverId, firebolt::rialto::common::SessionServerState::NOT_RUNNING);
     634              :     }
     635            2 : }
     636              : } // namespace rialto::servermanager::common
        

Generated by: LCOV version 2.0-1