Beispiel #1
0
        public void IndicateFileToDelete(string fileName, Etag etag)
        {
            var deletingFileName = RavenFileNameHelper.DeletingFileName(fileName);
            var fileExists = true;

            Storage.Batch(accessor =>
            {
                AssertDeleteOperationNotVetoed(fileName);

                var existingFile = accessor.ReadFile(fileName);

                if (existingFile == null)
                {
                    // do nothing if file does not exist
                    fileExists = false;
                    return;
                }

                if (existingFile.Metadata[SynchronizationConstants.RavenDeleteMarker] != null)
                {
                    // if it is a tombstone drop it
                    accessor.Delete(fileName);
                    fileExists = false;
                    return;
                }

                if (etag != null && existingFile.Etag != etag)
                    throw new ConcurrencyException("Operation attempted on file '" + fileName + "' using a non current etag")
                    {
                        ActualETag = existingFile.Etag,
                        ExpectedETag = etag
                    };

                var metadata = new RavenJObject(existingFile.Metadata).WithDeleteMarker();

                var renameSucceeded = false;

                int deleteAttempts = 0;
                do
                {
                    try
                    {
                        accessor.RenameFile(fileName, deletingFileName);
                        renameSucceeded = true;
                    }
                    catch (FileExistsException) // it means that .deleting file was already existed
                    {
                        var deletingFileHeader = accessor.ReadFile(deletingFileName);

                        if (deletingFileHeader != null && deletingFileHeader.Equals(existingFile))
                        {
                            fileExists = false; // the same file already marked as deleted no need to do it again
                            return;
                        }

                        if (deleteAttempts++ > 128)
                        {
                            Log.Warn("Could not rename a file '{0}' when a delete operation was performed", fileName);
                            throw;
                        }

                        // we need to use different name to do a file rename
                        deletingFileName = RavenFileNameHelper.DeletingFileName(fileName, RandomProvider.GetThreadRandom().Next());
                    }
                } while (renameSucceeded == false);

                accessor.UpdateFileMetadata(deletingFileName, metadata, null);
                accessor.DecrementFileCount(deletingFileName);

                Log.Debug("File '{0}' was renamed to '{1}' and marked as deleted", fileName, deletingFileName);

                var configName = RavenFileNameHelper.DeleteOperationConfigNameForFile(deletingFileName);
                var operation = new DeleteFileOperation { OriginalFileName = fileName, CurrentFileName = deletingFileName };
                accessor.SetConfig(configName, JsonExtensions.ToJObject(operation));

                FileSystem.DeleteTriggers.Apply(trigger => trigger.AfterDelete(fileName));

                Publisher.Publish(new ConfigurationChangeNotification { Name = configName, Action = ConfigurationChangeAction.Set });
                Publisher.Publish(new FileChangeNotification { File = fileName, Action = FileChangeAction.Delete });

                Log.Debug("File '{0}' was deleted", fileName);
            });

            if (fileExists)
            {
                Search.Delete(fileName);
                Search.Delete(deletingFileName);
            }
        }
		public void IndicateFileToDelete(string fileName)
		{
			var deletingFileName = RavenFileNameHelper.DeletingFileName(fileName);
			var fileExists = true;

			storage.Batch(accessor =>
			{
				var existingFileHeader = accessor.ReadFile(fileName);

				if (existingFileHeader == null)
				{
					// do nothing if file does not exist
					fileExists = false;
					return;
				}

				if (existingFileHeader.Metadata[SynchronizationConstants.RavenDeleteMarker] != null)
				{
					// if it is a tombstone drop it
					accessor.Delete(fileName);
					fileExists = false;
					return;
				}

                var metadata = new RavenJObject(existingFileHeader.Metadata).WithDeleteMarker();
                
				var renameSucceeded = false;

				int deleteVersion = 0;

				do
				{
					try
					{
						accessor.RenameFile(fileName, deletingFileName);
						renameSucceeded = true;
					}
					catch (FileExistsException) // it means that .deleting file was already existed
					{
						var deletingFileHeader = accessor.ReadFile(deletingFileName);

						if (deletingFileHeader != null && deletingFileHeader.Equals(existingFileHeader))
						{
							fileExists = false; // the same file already marked as deleted no need to do it again
							return;
						}

						// we need to use different name to do a file rename
						deleteVersion++;
						deletingFileName = RavenFileNameHelper.DeletingFileName(fileName, deleteVersion);
					}
				} while (!renameSucceeded && deleteVersion < 128);

                if (renameSucceeded)
                {
                    accessor.UpdateFileMetadata(deletingFileName, metadata);
                    accessor.DecrementFileCount(deletingFileName);

                    Log.Debug(string.Format("File '{0}' was renamed to '{1}' and marked as deleted", fileName, deletingFileName));

                    var configName = RavenFileNameHelper.DeleteOperationConfigNameForFile(deletingFileName);
                    var operation = new DeleteFileOperation { OriginalFileName = fileName, CurrentFileName = deletingFileName };
                    accessor.SetConfig(configName, JsonExtensions.ToJObject(operation));

                    notificationPublisher.Publish(new ConfigurationChangeNotification { Name = configName, Action = ConfigurationChangeAction.Set });
                }
                else
                {
                    Log.Warn("Could not rename a file '{0}' when a delete operation was performed", fileName);
                }
			});

			if (fileExists)
			{
				search.Delete(fileName);
				search.Delete(deletingFileName);
			}
		}