public void AddPathStatus(string path, CacheStatusType type, string message) { using (lockObject.Lock()) { pathsProcessed.AddToDictionaryListCreateIfNotExist(path, new PathCacheStatus(path, type, message)); } }
private void FileSystemWatcher_Created(object sender, FileSystemEventArgs e) { try { var path = e.FullPath.RemoveStart(nodeModulesPath + @"\"); if (NO_CACHING) { return; } if (path != ".staging") { using (lockObject.Lock()) { if (cacheStatusType < CacheStatusType.AddingPathsToList) { cacheStatusType = CacheStatusType.AddingPathsToList; } if (!pathsToProcess.Contains(path) && !pathsToNotProcess.Contains(path)) { this.WriteLineNoLock("Adding '{0}' to paths to process", path); pathsToProcess.Add(path); this.AddPathStatusNoLock(path, CacheStatusType.PathAddedToList); } } } } catch (Exception ex) { DebugUtils.Break(); } }
public string SetInstallStatus(string status) { using (lockObject.Lock()) { this.installStatusType = EnumUtils.GetValue <InstallStatusType>(status); if (this.installStatusType == InstallStatusType.InstallsStarted) { if (this.InstallCount > 0) { currentActionVerb = "Caching"; this.cacheStatusType = CacheStatusType.WatchingForPackages; } } else if (this.installStatusType == InstallStatusType.Finalized) { currentActionVerb = "Last pass syncing"; this.LastPassProcess(); NothingToPoll = true; } return($"Install status set to { this.installStatusType.ToString() }"); } }
public PackageCacheService(string root, string packageCachePath) : base(ThreadPriority.Lowest, TimeSpan.FromMilliseconds(1000), TimeSpan.FromMinutes(10), TimeSpan.FromSeconds(15)) { this.root = root; this.packageCachePath = packageCachePath; this.logWriter = new LogWriter(Path.Combine(this.packageCachePath, "Log.txt")); sweepsPath = Path.Combine(packageCachePath, "sweeps"); nodeModulesPath = Path.Combine(root, "node_modules"); pathsToProcess = new List <string>(); pathsToNotProcess = new List <string>(); pathsProcessed = new Dictionary <string, List <PathCacheStatus> >(); installsFromCacheToProcess = new Dictionary <string, PackageWorkingInstallFromCache>(); statusStack = new Stack <CacheStatusType>(); cacheStatusType = CacheStatusType.Initialized; lockObject = LockManager.CreateObject(); memoryStatus = MemoryStatus.Create(); currentActionVerb = "No current action"; packageModules = new NpmNodeModules(nodeModulesPath); this.NothingToPoll = true; if (!Directory.Exists(nodeModulesPath)) { Directory.CreateDirectory(nodeModulesPath); } fileSystemWatcher = new FileSystemWatcher(nodeModulesPath); fileSystemWatcher.EnableRaisingEvents = true; fileSystemWatcher.Created += FileSystemWatcher_Created; fileSystemWatcher.Changed += FileSystemWatcher_Changed; }
public void PopStatus() { using (lockObject.Lock()) { sweepingLogWriter = null; this.cacheStatusType = statusStack.Pop(); } }
public PathCacheStatus(string path, CacheStatusType type) { this.Path = path; this.PathCacheStatusType = type; this.Timestamp = DateTime.Now; this.LastStatusReported = DateTime.MinValue; this.StatusMessage = string.Empty; this.Exception = null; this.Install = string.Empty; this.IsSubPath = false; }
public void SetInstallCount(int count) { using (lockObject.Lock()) { if (count == 0) { this.cacheStatusType = CacheStatusType.EndOfProcessing; } this.InstallCount = count; } }
public override void Stop() { var count = 1; var modulesDirectory = new DirectoryInfo(nodeModulesPath); var lastCount = 0; this.WriteLine("Request to stop service. Waiting on {0} paths to finish processing", count); while (count > 0) { using (lockObject.Lock()) { count = pathsToProcess.Count; if (cacheStatusType < CacheStatusType.ServiceStopping) { cacheStatusType = CacheStatusType.ServiceStopping; } if (lastCount != count) { this.WriteLineNoLock("Waiting on {0} paths to finish processing", count); } lastCount = count; } Thread.Sleep(1); } using (lockObject.Lock()) { cacheStatusType = CacheStatusType.ServiceStopping; } this.WriteLine("Stopping service"); base.Stop(); using (lockObject.Lock()) { cacheStatusType = CacheStatusType.ServiceStopped; } this.WriteLine("Service stopped"); }
public void AddPathStatus(string path, CacheStatusType type) { using (lockObject.Lock()) { var pathCacheStatus = new PathCacheStatus(path, type); if (type == CacheStatusType.PathProcessed) { if (pathsProcessed.ContainsKey(path)) { if (pathsProcessed[path].Any(p => path != p.Path && path.StartsWith(p.Path))) { pathCacheStatus.IsSubPath = true; } } } pathsProcessed.AddToDictionaryListCreateIfNotExist(path, pathCacheStatus); } }
public void LastPassProcess() { var modulesDirectory = new DirectoryInfo(nodeModulesPath); using (lockObject.Lock()) { var paths = modulesDirectory.GetDirectories().Select(d => d.FullName.RemoveStart(nodeModulesPath + @"\")).Where(p => !pathsToNotProcess.Contains(p)).ToList(); if (paths.Count > 0) { this.WriteLineNoLock("\r\nPerforming last pass process on the following paths:\r\n"); this.WriteLineNoLock(paths.ToMultiLineList()); this.WriteLineNoLock(); cacheStatusType = CacheStatusType.LastPassProcessing; pathsToProcess.AddRange(paths); } } }
public PackageCacheStatusInfo(CacheStatusType cacheStatusType, string currentActionVerb, InstallStatusType installStatusType, int sweepIndex, int sweepCount, DateTime lastSweepStart, DateTime lastCacheStatusRequest, Dictionary <string, List <PathCacheStatus> > pathsProcessed, MemoryStatus memoryStatus) { this.CacheStatus = cacheStatusType.ToString(); this.InstallStatus = installStatusType.ToString(); this.SweepIndex = sweepIndex; this.SweepCount = sweepCount; this.LastSweepStart = lastSweepStart; Debug.Assert(currentActionVerb != null); this.CurrentActionVerb = currentActionVerb; this.pathsProcessed = pathsProcessed.ToDictionary(); this.pathsProcessedDelta = pathsProcessed.Where(p => p.Value.Last().Timestamp >= lastCacheStatusRequest).ToDictionary(); if (memoryStatus != null) { memoryStatus.Update(); this.MemoryStatus = memoryStatus; } }
public IDisposable PushSetStatus(CacheStatusType statusType) { using (lockObject.Lock()) { statusStack.Push(this.cacheStatusType); this.cacheStatusType = statusType; if (statusType == CacheStatusType.SweepingFiles) { if (!Directory.Exists(sweepsPath)) { Directory.CreateDirectory(sweepsPath); } sweepingLogWriter = new LogWriter(Path.Combine(sweepsPath, DateTime.Now.ToSortableDateTimeText() + ".txt")); } } return(statusStack.AsDisposable(() => { PopStatus(); })); }
public void AddPathStatusNoLock(string path, CacheStatusType type) { pathsProcessed.AddToDictionaryListCreateIfNotExist(path, new PathCacheStatus(path, type)); }
private void Process() { List <string> paths = null; Dictionary <string, PackageWorkingInstallFromCache> installs = null; var foldersCopied = 0; var foldersWithErrors = 0; var foldersSkipped = 0; var skipped = false; var stopwatch = new Stopwatch(); using (lockObject.Lock()) { paths = pathsToProcess.ToList(); installs = installsFromCacheToProcess.ToDictionary(); if (cacheStatusType < CacheStatusType.ServiceStarted) { cacheStatusType = CacheStatusType.ServiceStarted; } } if (installs != null) { if (installs.Count > 0) { using (lockObject.Lock()) { if (cacheStatusType < CacheStatusType.Installing) { cacheStatusType = CacheStatusType.Installing; installsFromCacheStatus.StatusSummary = "Installing from cache"; } } foreach (var install in installs.Values) { if (this.InstallFromCache(install)) { using (lockObject.Lock()) { installsFromCacheToProcess.Remove(install.Install); } } Thread.Sleep(1); } } } if (paths != null) { if (paths.Count > 0) { using (lockObject.Lock()) { if (cacheStatusType < CacheStatusType.Processing) { cacheStatusType = CacheStatusType.Processing; } } using (this.PushSetStatus(CacheStatusType.SweepingFiles)) { stopwatch.Start(); using (lockObject.Lock()) { sweepIndex = 0; sweepCount = paths.Count; lastSweepStart = DateTime.Now; if (paths.Count == 1) { this.WriteSweepLine("Sweeping {0} directory {1}", paths.Count, "*".Repeat(100)); } else { this.WriteSweepLine("Sweeping {0} directories {1}", paths.Count, "*".Repeat(100)); } } foreach (var path in paths) { try { var packagePath = Path.Combine(nodeModulesPath, path); var cachePath = Path.Combine(packageCachePath, path); var cacheDirectory = new DirectoryInfo(cachePath); var packageDirectory = new DirectoryInfo(packagePath); this.WriteSweepLine("Processing '{0}'", path); using (lockObject.Lock()) { sweepIndex++; } if (!Directory.Exists(cachePath)) { cacheDirectory.Create(); this.WriteSweepLine("Syncing directories for '{0}'", path); SyncDirectories(path, cacheDirectory, packageDirectory, ref skipped); if (skipped) { foldersSkipped++; } else { foldersCopied++; } } else { TimeSpan timeSpan; if (cacheDirectory.CompareTo(packageDirectory, out timeSpan)) { AddPathStatus(path, CacheStatusType.PathProcessed); using (lockObject.Lock()) { this.WriteSweepLine("Cache directory for '{0}' up to date. Comparison took {1} seconds", path, Math.Round(stopwatch.Elapsed.ToDecimalSeconds())); pathsToProcess.Remove(path); foldersSkipped++; } } else { if (CheckVersions(cachePath, packagePath)) { this.WriteSweepLine("Syncing directories for '{0}'. Comparison took {1} seconds", path, Math.Round(stopwatch.Elapsed.ToDecimalSeconds())); SyncDirectories(path, cacheDirectory, packageDirectory, ref skipped); if (skipped) { foldersSkipped++; } else { foldersCopied++; } } else { foldersSkipped++; } } } } catch (Exception ex) { AddPathStatus(path, ex); this.WriteSweepLine("Error for '{0}'. Exception: \r\n{1}", path, ex.Message); if (PackageCacheStatusInfo.GetPathErrorCount(path, pathsProcessed) > PATH_ERROR_LIMIT) { using (lockObject.Lock()) { this.WriteSweepLine("'{0}' reached error limit of {1}. Removing from list", path, PATH_ERROR_LIMIT); foldersWithErrors++; pathsToProcess.Remove(path); } } else { foldersSkipped++; } } Thread.Sleep(1); } stopwatch.Stop(); this.WriteSweepLine("End of sweep. Copied: {0}, Errored: {1}, Skipped: {2}, Sweep time elapsed: {3} seconds", foldersCopied, foldersWithErrors, foldersSkipped, Math.Round(stopwatch.Elapsed.ToDecimalSeconds())); } using (lockObject.Lock()) { cacheStatusType = CacheStatusType.EndOfProcessing; } } } }
public PathCacheStatus(string path, CacheStatusType type, string message) : this(path, type) { this.StatusMessage = message; }
public PathCacheStatus(string path, string install, CacheStatusType type) : this(path, type) { this.Install = install; this.Timestamp = DateTime.Now; }