Ejemplo n.º 1
0
        private void handle_message(PreRunMessage message)
        {
            this.Log().Debug(ChocolateyLoggers.Verbose, "[Pending] Removing all pending packages that should not be considered installed...");

            var pendingFiles = _fileSystem.get_files(ApplicationParameters.PackagesLocation, ApplicationParameters.PackagePendingFileName, SearchOption.AllDirectories).ToList();

            foreach (var pendingFile in pendingFiles.or_empty_list_if_null())
            {
                var packageFolder     = _fileSystem.get_directory_name(pendingFile);
                var packageFolderName = _fileSystem.get_directory_info_for(packageFolder).Name;

                var pendingSkipFiles = _fileSystem.get_files(packageFolder, PENDING_SKIP_FILE, SearchOption.AllDirectories).ToList();
                if (pendingSkipFiles.Count != 0)
                {
                    this.Log().Warn("Pending file found for {0}, but a {1} file was also found. Skipping removal".format_with(packageFolderName, PENDING_SKIP_FILE));
                    continue;
                }

                // wait for the file to be at least x seconds old
                // this allows commands running from the package for configuring sources, etc
                var fileInfo = _fileSystem.get_file_info_for(pendingFile);
                if (fileInfo.CreationTimeUtc.AddSeconds(PENDING_FILE_AGE_SECONDS) > _dateTimeService.get_current_date_time())
                {
                    this.Log().Debug("Pending file found for {0}, but the file is not {1} seconds old yet.".format_with(packageFolderName, PENDING_FILE_AGE_SECONDS));
                    continue;
                }

                this.Log().Warn("[Pending] Removing incomplete install for '{0}'".format_with(packageFolderName));
                FaultTolerance.retry(2, () => _fileSystem.delete_directory_if_exists(packageFolder, recursive: true, overrideAttributes: true, isSilent: true), 500, isSilent: true);
            }
        }
Ejemplo n.º 2
0
 private void allow_retries(Action action)
 {
     FaultTolerance.retry(
         TIMES_TO_TRY_OPERATION,
         action,
         waitDurationMilliseconds: 200,
         increaseRetryByMilliseconds: 100);
 }
Ejemplo n.º 3
0
 private void allow_retries(Action action, bool isSilent = false)
 {
     FaultTolerance.retry(
         TimesToRetryOperation,
         action,
         waitDurationMilliseconds: OperationRetryTimeMilliseconds,
         increaseRetryByMilliseconds: IncreaseRetryMilliseconds,
         isSilent: isSilent);
 }
Ejemplo n.º 4
0
            public void should_throw_an_error_if_retries_are_reached()
            {
                reset();

                Assert.Throws <Exception>(
                    () => FaultTolerance.retry(2, () => { throw new Exception("YIKES"); }, waitDurationMilliseconds: 0),
                    "YIKES"
                    );
            }
Ejemplo n.º 5
0
            public void should_not_allow_the_number_of_retries_to_be_zero()
            {
                reset();

                FaultTolerance.retry(
                    0,
                    () =>
                {
                });
            }
Ejemplo n.º 6
0
            public void should_return_immediately_when_successful()
            {
                reset();

                var i = 0;

                FaultTolerance.retry(3, () => { i += 1; }, waitDurationMilliseconds: 0);

                i.ShouldEqual(1);

                MockLogger.MessagesFor(LogLevel.Warn).Count.ShouldEqual(0);
            }
Ejemplo n.º 7
0
        private void handle_message(PreRunMessage message)
        {
            this.Log().Debug(ChocolateyLoggers.Verbose, "[Pending] Removing all pending packages that should not be considered installed...");

            var pendingFiles = _fileSystem.get_files(ApplicationParameters.PackagesLocation, ApplicationParameters.PackagePendingFileName, SearchOption.AllDirectories).ToList();

            foreach (var pendingFile in pendingFiles.or_empty_list_if_null())
            {
                var packageFolder = _fileSystem.get_directory_name(pendingFile);
                this.Log().Warn("[Pending] Removing incomplete install for '{0}'".format_with(_fileSystem.get_directory_info_for(packageFolder).Name));

                FaultTolerance.retry(2, () => _fileSystem.delete_directory_if_exists(packageFolder, recursive: true, overrideAttributes: true, isSilent: true), 500, isSilent: true);
            }
        }
Ejemplo n.º 8
0
            public void should_log_warning_each_time()
            {
                reset();

                try
                {
                    FaultTolerance.retry(3, () => { throw new Exception("YIKES"); }, waitDurationMilliseconds: 0);
                }
                catch
                {
                    // don't care
                }

                MockLogger.MessagesFor(LogLevel.Warn).Count.ShouldEqual(2);
            }
            public void should_retry_the_number_of_times_specified()
            {
                reset();

                var i = 0;

                try
                {
                    FaultTolerance.retry(10, () =>
                    {
                        i += 1;
                        throw new Exception("YIKES");
                    },
                                         waitDurationMilliseconds: 0);
                }
                catch
                {
                    // don't care
                }

                i.ShouldEqual(10);
            }
Ejemplo n.º 10
0
        public XmlType deserialize <XmlType>(string xmlFilePath, int retryCount)
        {
            return(FaultTolerance.retry(retryCount, () => GlobalMutex.enter(
                                            () =>
            {
                this.Log().Trace("Entered mutex to deserialize '{0}'".format_with(xmlFilePath));

                return FaultTolerance.try_catch_with_logging_exception(
                    () =>
                {
                    var xmlSerializer = new XmlSerializer(typeof(XmlType));
                    using (var fileStream = _fileSystem.open_file_readonly(xmlFilePath))
                        using (var fileReader = new StreamReader(fileStream))
                            using (var xmlReader = XmlReader.Create(fileReader))
                            {
                                if (!xmlSerializer.CanDeserialize(xmlReader))
                                {
                                    this.Log().Warn("Cannot deserialize response of type {0}", typeof(XmlType));
                                    return default(XmlType);
                                }

                                try
                                {
                                    return (XmlType)xmlSerializer.Deserialize(xmlReader);
                                }
                                catch (InvalidOperationException ex)
                                {
                                    // Check if its just a malformed document.
                                    if (ex.Message.Contains("There is an error in XML document"))
                                    {
                                        // If so, check for a backup file and try an parse that.
                                        if (_fileSystem.file_exists(xmlFilePath + ".backup"))
                                        {
                                            using (var backupStream = _fileSystem.open_file_readonly(xmlFilePath + ".backup"))
                                                using (var backupReader = new StreamReader(backupStream))
                                                    using (var backupXmlReader = XmlReader.Create(backupReader))
                                                    {
                                                        var validConfig = (XmlType)xmlSerializer.Deserialize(backupXmlReader);

                                                        // If there's no errors and it's valid, go ahead and replace the bad file with the backup.
                                                        if (validConfig != null)
                                                        {
                                                            // Close fileReader so that we can copy the file without it being locked.
                                                            fileReader.Close();
                                                            _fileSystem.copy_file(xmlFilePath + ".backup", xmlFilePath, overwriteExisting: true);
                                                        }

                                                        return validConfig;
                                                    }
                                        }
                                    }

                                    throw;
                                }
                                finally
                                {
                                    foreach (var updateFile in _fileSystem.get_files(_fileSystem.get_directory_name(xmlFilePath), "*.update").or_empty_list_if_null())
                                    {
                                        this.Log().Debug("Removing '{0}'".format_with(updateFile));
                                        FaultTolerance.try_catch_with_logging_exception(
                                            () => _fileSystem.delete_file(updateFile),
                                            errorMessage: "Unable to remove update file",
                                            logDebugInsteadOfError: true,
                                            isSilent: true
                                            );
                                    }
                                }
                            }
                },
                    "Error deserializing response of type {0}".format_with(typeof(XmlType)),
                    throwError: true);
            }, MUTEX_TIMEOUT),
                                        waitDurationMilliseconds: 200,
                                        increaseRetryByMilliseconds: 200));
        }
Ejemplo n.º 11
0
        public void serialize <XmlType>(XmlType xmlType, string xmlFilePath, bool isSilent)
        {
            _fileSystem.create_directory_if_not_exists(_fileSystem.get_directory_name(xmlFilePath));

            FaultTolerance.retry(3, () => GlobalMutex.enter(
                                     () =>
            {
                this.Log().Trace("Entered mutex to serialize '{0}'".format_with(xmlFilePath));
                FaultTolerance.try_catch_with_logging_exception(
                    () =>
                {
                    var xmlSerializer = new XmlSerializer(typeof(XmlType));

                    this.Log().Trace("Opening memory stream for xml file creation.");
                    using (var memoryStream = new MemoryStream())
                        using (var streamWriter = new StreamWriter(memoryStream, encoding: new UTF8Encoding(encoderShouldEmitUTF8Identifier: true))
                        {
                            AutoFlush = true
                        }
                               ){
                            xmlSerializer.Serialize(streamWriter, xmlType);
                            streamWriter.Flush();

                            // Grab the hash of both files and compare them.
                            this.Log().Trace("Hashing original file at '{0}'".format_with(xmlFilePath));
                            var originalFileHash  = _hashProvider.hash_file(xmlFilePath);
                            memoryStream.Position = 0;
                            if (!originalFileHash.is_equal_to(_hashProvider.hash_stream(memoryStream)))
                            {
                                this.Log().Trace("The hashes were different.");
                                // If there wasn't a file there in the first place, just write the new one out directly.
                                if (string.IsNullOrEmpty(originalFileHash))
                                {
                                    this.Log().Debug("There was no original file at '{0}'".format_with(xmlFilePath));
                                    memoryStream.Position = 0;
                                    _fileSystem.write_file(xmlFilePath, () => memoryStream);

                                    this.Log().Trace("Closing xml memory stream.");
                                    memoryStream.Close();
                                    streamWriter.Close();

                                    return;
                                }

                                // Otherwise, create an update file, and resiliently move it into place.
                                var tempUpdateFile = xmlFilePath + "." + Process.GetCurrentProcess().Id + ".update";
                                this.Log().Trace("Creating a temp file at '{0}'".format_with(tempUpdateFile));
                                memoryStream.Position = 0;
                                this.Log().Trace("Writing file '{0}'".format_with(tempUpdateFile));
                                _fileSystem.write_file(tempUpdateFile, () => memoryStream);

                                memoryStream.Close();
                                streamWriter.Close();

                                this.Log().Trace("Replacing file '{0}' with '{1}'.".format_with(xmlFilePath, tempUpdateFile));
                                _fileSystem.replace_file(tempUpdateFile, xmlFilePath, xmlFilePath + ".backup");
                            }
                        }
                },
                    errorMessage: "Error serializing type {0}".format_with(typeof(XmlType)),
                    throwError: true,
                    isSilent: isSilent);
            }, MUTEX_TIMEOUT),
                                 waitDurationMilliseconds: 200,
                                 increaseRetryByMilliseconds: 200);
        }
Ejemplo n.º 12
0
            public void should_not_allow_the_number_of_retries_to_be_zero()
            {
                reset();

                Assert.Throws <ApplicationException>(() => FaultTolerance.retry(0, () => { }));
            }