Inheritance: IDisposable
Exemplo n.º 1
0
        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);
            }
            using (var locker = new PosixFileLocker(GetCacheIndexLocation(), true))
            {
                if (TryGetFromCache(uri, out fileName))
                {
                    fetchedFiles.Add(fileName, uri);
                    Monitor.Exit(concurrentLock);
                    return(true);
                }
                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);
                }
            }
        }
Exemplo n.º 2
0
        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;
            }
            using(var locker = new PosixFileLocker(GetCacheIndexLocation(), true))
            {
                if(TryGetFromCache(uri, out fileName))
                {
                    fetchedFiles.Add(fileName, uri);
                    Monitor.Exit(concurrentLock);
                    return true;
                }
                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);
                }
            }
        }