public void Dispose() { this.DisposeBase(); // Destination path is an concatenation of storage account name and container name. string destinationPath = string.Concat( this.storageAccountFactory.Connection.UseDevelopmentStorage ? AzureConstants.DevelopmentStorageConnectionString : this.storageAccountFactory.Connection.AccountName, ";", // This separator cannot occur in account name or container name this.containerName); lock (Trimmers) { if (Trimmers.ContainsKey(destinationPath)) { // Decrement reference count on the trimmer object TrimmerInfo trimmerInfo = Trimmers[destinationPath]; trimmerInfo.RefCount--; if (0 == trimmerInfo.RefCount) { // No one else is using the trimmer. Dispose it. trimmerInfo.Trimmer.Dispose(); Trimmers.Remove(destinationPath); } } } GC.SuppressFinalize(this); }
public void Dispose() { this.DisposeBase(); lock (Trimmers) { if (Trimmers.ContainsKey(this.destinationPath)) { // Decrement reference count on the trimmer object TrimmerInfo trimmerInfo = Trimmers[this.destinationPath]; trimmerInfo.RefCount--; if (0 == trimmerInfo.RefCount) { // No one else is using the trimmer. Dispose it. trimmerInfo.Trimmer.Dispose(); Trimmers.Remove(this.destinationPath); } } } GC.SuppressFinalize(this); }
internal AzureFileUploader( FabricEvents.ExtensionsEvents traceSource, string logSourceId, string folderName, string destinationPath, string workFolder, StorageAccountFactory storageAccountFactory, string containerName, TimeSpan uploadIntervalMinutes, TimeSpan fileSyncIntervalInMinutes, TimeSpan blobDeletionAgeMinutes, string fabricNodeInstanceName, string deploymentId) : base( traceSource, logSourceId, folderName, destinationPath, workFolder, uploadIntervalMinutes, fileSyncIntervalInMinutes) { // Initialization this.storageAccountFactory = storageAccountFactory; this.containerName = containerName; this.directoryName = AzureUtility.IsAzureInterfaceAvailable() ? string.Join( "/", string.IsNullOrEmpty(deploymentId) ? AzureUtility.DeploymentId : deploymentId, AzureUtility.RoleName, AzureUtility.RoleInstanceId) : fabricNodeInstanceName; this.fabricNodeInstanceName = fabricNodeInstanceName; this.perfHelper = new AzureBlobPerformance(this.TraceSource, this.LogSourceId); // Blob copy is done one at a time, so the concurrency count is 1. this.perfHelper.ExternalOperationInitialize( ExternalOperationTime.ExternalOperationType.BlobCopy, 1); // Create the container at the destination try { Utility.PerformWithRetries( this.CreateContainer, (object)null, new RetriableOperationExceptionHandler(this.AzureStorageExceptionHandler)); } catch (Exception e) { var message = string.Format( "Error creating container {0}, account {1}.", this.containerName, this.storageAccountFactory.Connection.AccountName); this.TraceSource.WriteExceptionAsError( this.LogSourceId, e, message); throw new InvalidOperationException(message, e); } // Check if a trimmer already exists to delete old files from this destination. lock (Trimmers) { if (Trimmers.ContainsKey(destinationPath)) { // Trimmer already exists. Increment its reference count. TrimmerInfo trimmerInfo = Trimmers[destinationPath]; trimmerInfo.RefCount++; } else { // Trimmer does not exist. Create it. AzureFileTrimmer trimmer = new AzureFileTrimmer( folderName, LocalMapFolderPath, storageAccountFactory, containerName, blobDeletionAgeMinutes, fabricNodeInstanceName, deploymentId, AzureUtility.IsAzureInterfaceAvailable()); TrimmerInfo trimmerInfo = new TrimmerInfo { RefCount = 1, Trimmer = trimmer }; Trimmers[destinationPath] = trimmerInfo; } } }
internal FileShareUploader( FabricEvents.ExtensionsEvents traceSource, string logSourceId, bool runningOnBehalfOfApplication, string folderName, string destinationPath, AccessInformation accessInfo, string workFolder, TimeSpan uploadInterval, TimeSpan fileSyncInterval, TimeSpan fileDeletionAge, bool destinationIsLocalAppFolder, string fabricNodeId) : base( traceSource, logSourceId, folderName, destinationPath, workFolder, uploadInterval, fileSyncInterval) { // Initialization this.destinationPath = destinationPath; this.accessInfo = accessInfo; var impersonationRequiredForAppStoreAccess = Utility.IsImpersonationRequiredForAppDiagnosticStoreAccess(); if (runningOnBehalfOfApplication && (false == destinationIsLocalAppFolder) && impersonationRequiredForAppStoreAccess && (FileShareAccessAccountType.None == this.accessInfo.AccountType)) { const string Message = "Impersonation is required to access the file share, but credentials for impersonation have not been provided."; this.TraceSource.WriteError( this.LogSourceId, Message); throw new InvalidOperationException(Message); } // Create the staging folder where we copy the files temporarily before impersonating // and copying it to the final destination. try { Utility.PerformIOWithRetries( () => { if (IsStagingFolderNeededForCopy(folderName)) { CreateStagingFolderForCopy(workFolder); } }); } catch (Exception e) { throw new IOException(string.Format("Unable to create staging directory for work directory {0}.", workFolder), e); } // Check that the destination folder exists or can be created. try { Utility.PerformIOWithRetries( () => this.PerformDestinationOperation( ctx => { var destPath = (string)ctx; if (FabricDirectory.Exists(destPath)) { return true; } FabricDirectory.CreateDirectory(destPath); return true; }, this.destinationPath)); } catch (Exception e) { throw new IOException(string.Format("Unable to create destination directory {0}.", this.destinationPath), e); } this.perfHelper = new FileSharePerformance(this.TraceSource, this.LogSourceId); // File copy is done one at a time, so the concurrency count is 1. this.perfHelper.ExternalOperationInitialize( ExternalOperationTime.ExternalOperationType.FileShareCopy, 1); // Check if a trimmer already exists to delete old files from this destination lock (Trimmers) { if (Trimmers.ContainsKey(this.destinationPath)) { // Trimmer already exists. Increment its reference count. TrimmerInfo trimmerInfo = Trimmers[this.destinationPath]; trimmerInfo.RefCount++; } else { // Trimmer does not exist. Create it. FileShareTrimmer trimmer = new FileShareTrimmer( folderName, this.destinationPath, this.PerformDestinationOperation, LocalMapFolderPath, fileDeletionAge); TrimmerInfo trimmerInfo = new TrimmerInfo { RefCount = 1, Trimmer = trimmer }; Trimmers[this.destinationPath] = trimmerInfo; } } }