protected override void OnLockAcquired() { if (ScmHostingConfigurations.FunctionsSyncTriggersDelayBackground) { shutdownDelayed = ShutdownDelaySemaphore.GetInstance().Acquire(_traceFactory.GetTracer()); } else { OperationManager.SafeExecute(() => { // Create Sentinel file for DWAS to check // DWAS will check for presence of this file incase a an app setting based recycle needs to be performed in middle of deployment // If this is present, DWAS will postpone the recycle so that deployment goes through first if (!String.IsNullOrEmpty(siteRoot)) { FileSystemHelpers.CreateDirectory(Path.Combine(siteRoot, @"ShutdownSentinel")); string sentinelPath = Path.Combine(siteRoot, @"ShutdownSentinel\Sentinel.txt"); if (!FileSystemHelpers.FileExists(sentinelPath)) { var file = FileSystemHelpers.CreateFile(sentinelPath); file.Close(); } // DWAS checks if write time of this file is in the future then only postpones the recycle FileInfoBase sentinelFileInfo = FileSystemHelpers.FileInfoFromFileName(sentinelPath); sentinelFileInfo.LastWriteTimeUtc = DateTime.UtcNow.AddMinutes(20); } }); } IRepositoryFactory repositoryFactory = RepositoryFactory; if (repositoryFactory != null) { IRepository repository = repositoryFactory.GetRepository(); if (repository != null) { // Clear any left over repository-related lock since we have the actual lock repository.ClearLock(); } } }
protected override void OnLockRelease() { base.OnLockRelease(); if (ScmHostingConfigurations.FunctionsSyncTriggersDelayBackground && shutdownDelayed) { ShutdownDelaySemaphore.GetInstance().Release(_traceFactory.GetTracer()); } else { OperationManager.SafeExecute(() => { // Delete the Sentinel file to signal DWAS that deployment is complete if (!String.IsNullOrEmpty(siteRoot)) { string sentinelPath = Path.Combine(siteRoot, @"ShutdownSentinel\Sentinel.txt"); if (FileSystemHelpers.FileExists(sentinelPath)) { FileSystemHelpers.DeleteFile(sentinelPath); } } }); } }
public void Release() { // Normally, this should never be null here, but currently some LiveScmEditorController code calls Release() incorrectly if (_lockStream == null) { OnLockRelease(); return; } OperationManager.CriticalExecute("LockFile.Release", () => { var temp = _lockStream; _lockStream = null; temp.Close(); _traceFactory.GetTracer().Trace($"LockFile '{_path}' released"); }); // cleanup inactive lock file. technically, it is not needed // we just want to see the lock folder is clean, if no active lock. DeleteFileSafe(); OnLockRelease(); }
public bool Acquire(ITracer tracer) { lock (_lock) { try { // No timeout makes this call instant. No waiting for acquistion bool acquired = _shutdownSemaphore.Wait(millisecondsTimeout: 0); if (!acquired) { tracer.Trace("Could not acquire shutdown semaphore", new Dictionary <string, string> { { "SemaphoreCount", _shutdownSemaphore.CurrentCount.ToString() } }); return(false); } //tracer.Trace("Acquired shutdown semaphore", new Dictionary<string, string> //{ // { "SemaphoreCount", _shutdownSemaphore.CurrentCount.ToString() } //}); OperationManager.SafeExecute(() => { if (Environment.IsAzureEnvironment() && OSDetector.IsOnWindows()) { string siteRoot = PathUtilityFactory.Instance.ResolveLocalSitePath(); // Create Sentinel file for DWAS to check // DWAS will check for presence of this file incase a an app setting based recycle needs to be performed in middle of deployment // If this is present, DWAS will postpone the recycle so that deployment goes through first if (!string.IsNullOrEmpty(siteRoot)) { FileSystemHelpers.CreateDirectory(Path.Combine(siteRoot, @"ShutdownSentinel")); string sentinelPath = Path.Combine(siteRoot, @"ShutdownSentinel\Sentinel.txt"); if (!FileSystemHelpers.FileExists(sentinelPath)) { //tracer.Trace("Creating shutdown sentinel file", new Dictionary<string, string> //{ // { "SemaphoreCount", _shutdownSemaphore.CurrentCount.ToString() } //}); var file = FileSystemHelpers.CreateFile(sentinelPath); file.Close(); } tracer.Trace("Updating shutdown sentinel last write time", new Dictionary <string, string> { { "SemaphoreCount", _shutdownSemaphore.CurrentCount.ToString() } }); // DWAS checks if write time of this file is in the future then only postpones the recycle FileInfoBase sentinelFileInfo = FileSystemHelpers.FileInfoFromFileName(sentinelPath); sentinelFileInfo.LastWriteTimeUtc = DateTime.UtcNow.AddMinutes(20); } } }); } catch (Exception ex) { tracer.TraceError(ex); return(false); } return(true); } }
public bool Lock(string operationName) { Stream lockStream = null; var ignoreCloseStreamException = false; try { FileSystemHelpers.EnsureDirectory(Path.GetDirectoryName(_path)); lockStream = FileSystemHelpers.OpenFile(_path, FileMode.Create, FileAccess.Write, FileShare.Read); WriteLockInfo(operationName, lockStream); OnLockAcquired(); _lockStream = lockStream; lockStream = null; if (_traceLock) { _traceFactory.GetTracer().Trace($"LockFile '{_path}' acquired"); } return(true); } catch (UnauthorizedAccessException) { if (!_ensureLock) { // if it is ReadOnly file system, we will skip the lock // which will enable all read action // for write action, it will fail with UnauthorizedAccessException when perform actual write operation // There is one drawback, previously for write action, even acquire lock will fail with UnauthorizedAccessException, // there will be retry within given timeout. so if exception is temporary, previous`s implementation will still go thru. // While right now will end up failure. But it is a extreme edge case, should be ok to ignore. ignoreCloseStreamException = FileSystemHelpers.IsFileSystemReadOnly(); return(ignoreCloseStreamException); } } catch (IOException ex) { if (!_ensureLock) { // if not enough disk space, no one has the lock. // let the operation thru and fail where it would try to get the file ignoreCloseStreamException = ex.Message.Contains(NotEnoughSpaceText); return(ignoreCloseStreamException); } } catch (Exception ex) { TraceIfUnknown(ex); } finally { if (lockStream != null) { OperationManager.CriticalExecute("LockFile.Lock.Finally", () => lockStream.Close(), _ => !ignoreCloseStreamException); } } return(false); }