private bool IsSessionRunning(Guid sessionId) { // Hmmm, is it really done, or still running after calling EndSession()? using (InterprocessLock sessionLock = InterprocessLockManager.Lock(this, m_SessionLockFolder, sessionId.ToString(), 0, true)) { if (sessionLock == null) { // It's holding the lock, so it must still be active! return(true); } // Otherwise, it has released the lock, so it really is closed as it said. We're good. return(false); } }
private void Initialize() { if (m_Initialized) { return; } //we need to grab a lock on this session to prevent it from being transported to the same endpoint at the same time. string sessionWorkingFileNamePath = GenerateTemporarySessionFileNamePath(); //we aren't going to do Using - we keep the lock! if (m_SessionTransportLock == null) //if we are retrying to initialize after a failure we may already have it. { m_SessionTransportLock = InterprocessLockManager.Lock(this, GenerateTemporarySessionPath(), GenerateTemporarySessionFileName(), 0, true); } //we aren't waiting to see if we can get the lock - if anyone else has it they must be transferring the session. if (m_SessionTransportLock != null) { //Lets figure out if we're restarting a previous send or starting a new one. m_TempSessionProgressFileNamePath = sessionWorkingFileNamePath + ".txt"; m_BytesWritten = 0; if (File.Exists(m_TempSessionProgressFileNamePath)) { //load up the existing transfer state. try { m_BytesWritten = LoadProgressTrackingFile(); } catch { //oh well, assume no progress. m_PerformCleanup = true; SafeDeleteFile(m_TempSessionProgressFileNamePath); } } else { //make sure we didn't get started, but not finish, writing our temp file. SafeDeleteFile(m_TempSessionProgressFileNamePath); } m_Initialized = true; } }
/// <summary> /// Get the unique lock for the active session, to be held until the session exits. /// </summary> private void GetSessionFileLock() { if (m_SessionFileLock != null) { return; } var sessionId = Log.SessionSummary.Id; var sessionLockName = sessionId.ToString(); try { m_SessionFileLock = InterprocessLockManager.Lock(this, m_SessionLockFolder, sessionLockName, 0, true); if (m_SessionFileLock == null) { Log.Write(LogMessageSeverity.Information, LogCategory, "Loupe Agent unable to get the unique lock for a new session", "The Loupe Agent's FileMessenger was not able to lock this active session as Running. " + "This could interfere with efficiently distinguishing whether this session has crashed or is still running."); #if DEBUG if (Debugger.IsAttached) { Debugger.Break(); } #endif } } catch (Exception ex) //we don't want failure to get the session file lock to be fatal... { if (!Log.SilentMode) { Log.Write(LogMessageSeverity.Information, LogWriteMode.Queued, ex, true, LogCategory, "Loupe Agent unable to get the unique lock for a new session due to " + ex.GetBaseException().GetType(), "The Loupe Agent's FileMessenger was not able to lock this active session as Running. " + "This could interfere with efficiently distinguishing whether this session has crashed or is still running."); } } }
/// <summary> /// Get a multiprocess lock for the subscription engine. /// </summary> /// <param name="timeout"></param> /// <returns></returns> private InterprocessLock GetLock(int timeout) { return(InterprocessLockManager.Lock(this, m_RepositoryFolder, m_MultiprocessLockName, timeout)); }
private void Initialize() { if (m_Initialized) { return; } //we need to grab a lock on this session to prevent it from being transported to the same endpoint at the same time. var sessionWorkingFileNamePath = GenerateTemporarySessionFileNamePath(); //we aren't going to do Using - we keep the lock! if (m_SessionTransportLock == null) //if we are retrying to initialize after a failure we may already have it. { m_SessionTransportLock = InterprocessLockManager.Lock(this, GenerateTemporarySessionPath(), GenerateTemporarySessionFileName(), 0, true); } //we aren't waiting to see if we can get the lock - if anyone else has it they must be transferring the session. if (m_SessionTransportLock != null) { //grab a lock on the actual data file - if it's not there, no point in continuing. m_SessionFileStream = Repository.LoadSessionFileStream(SessionId, FileId.Value); //calculate our SHA1 Hash... try { using (var csp = SHA1.Create()) { m_SessionFileHash = BitConverter.ToString(csp.ComputeHash(m_SessionFileStream)); } //now back up the stream to the beginning so we can send the actual data. m_SessionFileStream.Position = 0; } catch (Exception ex) { if (!Log.SilentMode) { Log.Write(LogMessageSeverity.Error, LogWriteMode.Queued, ex, RepositoryPublishClient.LogCategory, "Unable to calculate hash for session file due to " + ex.GetType() + " exception.", "The upload will proceed but without the hash to check the accuracy of the upload.\r\nException: {0}\r\n{1}\r\n", ex.GetType(), ex.Message); } } //Lets figure out if we're restarting a previous send or starting a new one. m_TempSessionProgressFileNamePath = sessionWorkingFileNamePath; m_BytesWritten = 0; if (File.Exists(m_TempSessionProgressFileNamePath)) { //load up the existing transfer state. try { m_BytesWritten = LoadProgressTrackingFile(); } catch { //oh well, assume no progress. m_PerformCleanup = true; SafeDeleteFile(m_TempSessionProgressFileNamePath); } } else { //make sure we didn't get started, but not finish, writing our temp file. SafeDeleteFile(m_TempSessionProgressFileNamePath); } m_Initialized = true; } }
/// <summary> /// Execute repository maintenance on a background thread. /// </summary> private void AsyncPerformMaintenance(object state) { try { //make sure if we log something it never blocks, since that could ultimately result in a deadlock. Publisher.ThreadMustNotBlock(); bool collectionChanged = false; //since external objects can freely modify our configuration, save a copy so we run with a consistent perspective. int maxSizeMegabytes = MaxSizeMegabytes; int maxAgeDays = MaxAgeDays; if (m_LoggingEnabled) { Log.Write(LogMessageSeverity.Information, LogCategory, "Starting Repository Maintenance", "Starting repository maintenance on repository stored at {0}, removing fragments older than {1} days and keeping the repository under {2:N0} megabytes.", RepositoryPath, maxAgeDays, maxSizeMegabytes); } //before we do anything more, we have to get the maintenance lock. using (InterprocessLock maintenanceLock = InterprocessLockManager.Lock(this, m_RepositoryPath, MutiprocessLockName, 0, true)) { if (maintenanceLock == null) { //we couldn't get the lock, so no maintenance today. if (m_LoggingEnabled) { Log.Write(LogMessageSeverity.Warning, LogCategory, "Unable to Perform Maintenance - Repository Locked", "Unable to get the maintenance file lock on the repository stored at {0}, not performing maintenance.", RepositoryPath); } return; } //We may not be able to do pruning - we used to be used just for index DB update (not valid any more) if ((string.IsNullOrEmpty(ApplicationName) == false) && (Log.IsSessionEnding == false)) { //find out if there is any maintenance to do - we start by age and it'll let us know if we have anything else to do. bool capacityPruningRequired; bool sessionsRemoved = ProcessPruneForAge(maxAgeDays, maxSizeMegabytes, out capacityPruningRequired); collectionChanged = (collectionChanged || sessionsRemoved); //make sure capacity pruning is enabled. if (maxSizeMegabytes <= 0) { capacityPruningRequired = false; } //anything more to do? if ((capacityPruningRequired) && (Log.IsSessionEnding == false)) { sessionsRemoved = ProcessPruneForSize(MaxSizeMegabytes); collectionChanged = (collectionChanged || sessionsRemoved); } ////and do crashed session conversion. //bool crashedSessionsChanged = ProcessCrashedSessionConversion(); //collectionChanged = (collectionChanged || crashedSessionsChanged); } } if (collectionChanged) { OnCollectionChanged(new CollectionChangeEventArgs(CollectionChangeAction.Refresh, null)); } if (m_LoggingEnabled) { Log.Write(LogMessageSeverity.Information, LogCategory, "Repository Maintenance Complete", "Repository maintenance completed on repository stored at {0}", RepositoryPath); } } catch (Exception ex) { GC.KeepAlive(ex); if (m_LoggingEnabled) { Log.Write(LogMessageSeverity.Warning, LogCategory, "Unable to Perform Repository Maintenance", "Unable to complete repository maintenance successfully due to an exception: {0}", ex); } } finally { //now we need to mark that we're done, and this is done with a lock for multithread purity. lock (m_Lock) { m_PerformingMaintenance = false; System.Threading.Monitor.PulseAll(m_Lock); } } }