示例#1
0
 public FileLocker(string fileToLock)
 {
 #if PLATFORM_WINDOWS
     innerLocker = new WindowsFileLocker(fileToLock);
 #else
     innerLocker = new PosixFileLocker(fileToLock);
 #endif
 }
示例#2
0
        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);
                    }
                }
            }
        }