public FileLocker(string fileToLock) { #if PLATFORM_WINDOWS innerLocker = new WindowsFileLocker(fileToLock); #else innerLocker = new PosixFileLocker(fileToLock); #endif }
private bool TryFetchFromCacheOrUriInner(Uri uri, out string fileName) { #if PLATFORM_WINDOWS using (var locker = new WindowsFileLocker(GetCacheIndexLockLocation())) #else using (var locker = new PosixFileLocker(GetCacheIndexLockLocation())) #endif { if (TryGetFromCache(uri, out fileName)) { fetchedFiles.Add(fileName, uri); return(true); } if (TryFetchFromUriInner(uri, out fileName)) { UpdateInCache(uri, fileName); return(true); } } fileName = null; return(false); }
public bool TryFetchFromUri(Uri uri, out string fileName) { fileName = null; if (!Monitor.TryEnter(concurrentLock)) { Logger.LogAs(this, LogLevel.Error, "Cannot perform concurrent downloads, aborting..."); return(false); } #if PLATFORM_WINDOWS using (var locker = new WindowsFileLocker(GetCacheIndexLockLocation())) #else using (var locker = new PosixFileLocker(GetCacheIndexLockLocation())) #endif { if (TryGetFromCache(uri, out fileName)) { fetchedFiles.Add(fileName, uri); Monitor.Exit(concurrentLock); return(true); } using (client = new WebClient()) { fileName = TemporaryFilesManager.Instance.GetTemporaryFile(); try { var attempts = 0; var success = false; do { var downloadProgressHandler = EmulationManager.Instance.ProgressMonitor.Start(GenerateProgressMessage(uri), false, true); Logger.LogAs(this, LogLevel.Info, "Downloading {0}.", uri); var now = CustomDateTime.Now; var bytesDownloaded = 0L; client.DownloadProgressChanged += (sender, e) => { var newNow = CustomDateTime.Now; var period = newNow - now; if (period > progressUpdateThreshold) { downloadProgressHandler.UpdateProgress(e.ProgressPercentage, GenerateProgressMessage(uri, e.BytesReceived, e.TotalBytesToReceive, e.ProgressPercentage, 1.0 * (e.BytesReceived - bytesDownloaded) / period.TotalSeconds)); now = newNow; bytesDownloaded = e.BytesReceived; } }; var wasCancelled = false; Exception exception = null; var resetEvent = new ManualResetEvent(false); client.DownloadFileCompleted += delegate(object sender, AsyncCompletedEventArgs e) { exception = e.Error; if (e.Cancelled) { wasCancelled = true; } resetEvent.Set(); downloadProgressHandler.Finish(); }; client.DownloadFileAsync(uri, fileName); resetEvent.WaitOne(); downloadProgressHandler.Finish(); if (wasCancelled) { Logger.LogAs(this, LogLevel.Info, "Download cancelled."); File.Delete(fileName); return(false); } if (exception != null) { var webException = exception as WebException; File.Delete(fileName); Logger.LogAs(this, LogLevel.Error, "Failed to download from {0}, reason: {1}.", uri, webException != null ? ResolveWebException(webException) : exception.Message); return(false); } Logger.LogAs(this, LogLevel.Info, "Download done."); if (uri.ToString().EndsWith(".gz", StringComparison.InvariantCulture)) { var decompressionProgressHandler = EmulationManager.Instance.ProgressMonitor.Start(string.Format("Decompressing {0}", uri), false, false); Logger.LogAs(this, LogLevel.Info, "Decompressing {0}.", uri); var decompressedFile = TemporaryFilesManager.Instance.GetTemporaryFile(); using (var gzipStream = new GZipStream(File.OpenRead(fileName), CompressionMode.Decompress)) using (var outputStream = File.OpenWrite(decompressedFile)) { gzipStream.CopyTo(outputStream); } fileName = decompressedFile; Logger.LogAs(this, LogLevel.Info, "Decompression done"); decompressionProgressHandler.Finish(); } }while (!(success = UpdateInCache(uri, fileName)) && attempts++ < 2); if (!success) { Logger.LogAs(this, LogLevel.Error, "Download failed {0} times, wrong checksum or size, aborting.", attempts); File.Delete(fileName); return(false); } fetchedFiles.Add(fileName, uri); return(true); } finally { Monitor.Exit(concurrentLock); } } } }