// Copyright Epic Games, Inc. All Rights Reserved. #include "sessions.h" #include #include #include namespace zen { using namespace std::literals; class SessionLog : public TRefCounted { public: SessionLog(std::filesystem::path LogFilePath) { m_LogFile.Open(LogFilePath, BasicFile::Mode::kWrite); } private: BasicFile m_LogFile; }; class SessionLogStore { public: SessionLogStore(std::filesystem::path StoragePath) : m_StoragePath(std::move(StoragePath)) {} ~SessionLogStore() = default; Ref GetLogForSession(const Oid& SessionId) { // For now, just return a new log for each session. We can implement actual log storage and retrieval later. return Ref(new SessionLog(m_StoragePath / (SessionId.ToString() + ".log"))); } Ref CreateLogForSession(const Oid& SessionId) { // For now, just return a new log for each session. We can implement actual log storage and retrieval later. return Ref(new SessionLog(m_StoragePath / (SessionId.ToString() + ".log"))); } private: std::filesystem::path m_StoragePath; }; SessionsService::Session::Session(const SessionInfo& Info) : m_Info(Info) { } SessionsService::Session::~Session() = default; void SessionsService::Session::AppendLog(LogEntry Entry) { RwLock::ExclusiveLockScope Lock(m_LogLock); m_LogEntries.push_back(std::move(Entry)); while (m_LogEntries.size() > MaxLogEntries) { m_LogEntries.pop_front(); } } std::vector SessionsService::Session::GetLogEntries(uint32_t Limit, uint32_t Offset) const { RwLock::SharedLockScope Lock(m_LogLock); const uint32_t Total = uint32_t(m_LogEntries.size()); if (Offset >= Total) { return {}; } const uint32_t Available = Total - Offset; const uint32_t Count = (Limit > 0) ? std::min(Limit, Available) : Available; std::vector Result; Result.reserve(Count); for (uint32_t i = Offset; i < Offset + Count; i++) { Result.push_back(m_LogEntries[i]); } return Result; } uint64_t SessionsService::Session::GetLogCount() const { RwLock::SharedLockScope Lock(m_LogLock); return m_LogEntries.size(); } ////////////////////////////////////////////////////////////////////////// SessionsService::SessionsService() : m_Log(logging::Get("sessions")) { } SessionsService::~SessionsService() = default; bool SessionsService::RegisterSession(const Oid& SessionId, std::string AppName, std::string Mode, const Oid& JobId, CbObjectView Metadata) { RwLock::ExclusiveLockScope Lock(m_Lock); if (m_Sessions.contains(SessionId)) { return false; } ZEN_INFO("Session {} registered (AppName: {}, Mode: {}, JobId: {})", SessionId, AppName, Mode, JobId); const DateTime Now = DateTime::Now(); m_Sessions.emplace(SessionId, Ref(new Session(SessionInfo{.Id = SessionId, .AppName = std::move(AppName), .Mode = std::move(Mode), .JobId = JobId, .Metadata = CbObject::Clone(Metadata), .CreatedAt = Now, .UpdatedAt = Now}))); return true; } bool SessionsService::UpdateSession(const Oid& SessionId, CbObjectView Metadata) { RwLock::ExclusiveLockScope Lock(m_Lock); auto It = m_Sessions.find(SessionId); if (It == m_Sessions.end()) { return false; } It.value()->UpdateMetadata(Metadata); const SessionInfo& Info = It.value()->Info(); ZEN_DEBUG("Session {} updated (AppName: {}, JobId: {})", SessionId, Info.AppName, Info.JobId); return true; } Ref SessionsService::GetSession(const Oid& SessionId) const { RwLock::SharedLockScope Lock(m_Lock); auto It = m_Sessions.find(SessionId); if (It == m_Sessions.end()) { return {}; } return It->second; } std::vector> SessionsService::GetSessions() const { RwLock::SharedLockScope Lock(m_Lock); std::vector> Result; Result.reserve(m_Sessions.size()); for (const auto& [Id, SessionRef] : m_Sessions) { Result.push_back(SessionRef); } return Result; } bool SessionsService::RemoveSession(const Oid& SessionId) { RwLock::ExclusiveLockScope Lock(m_Lock); auto It = m_Sessions.find(SessionId); if (It == m_Sessions.end()) { return false; } ZEN_INFO("Session {} removed (AppName: {}, JobId: {})", SessionId, It.value()->Info().AppName, It.value()->Info().JobId); Ref Ended = It.value(); Ended->SetEndedAt(DateTime::Now()); m_EndedSessions.push_back(std::move(Ended)); m_Sessions.erase(It); return true; } std::vector> SessionsService::GetEndedSessions() const { RwLock::SharedLockScope Lock(m_Lock); return m_EndedSessions; } uint64_t SessionsService::GetSessionCount() const { RwLock::SharedLockScope Lock(m_Lock); return m_Sessions.size(); } } // namespace zen