public async Task DeleteFileAsync(string fileId) { AssertIdentityProvided(); // Quota is affected var filePath = GetTargetFilePath(fileId); var fileInfo = await Task.Run(() => new FileInfo(filePath)); var fileSize = fileInfo.Length; await Task.Run(() => File.Delete(filePath)); if (_owner != null) { var lockEntry = ServerContext.ServiceTable[_owner].UserLock; // Decrease user storage usage await lockEntry.ObtainExclusiveWriteAsync(); var userManager = new WebUserManager(ServerContext); var ownerData = await userManager.FindUserByUsernameAsync(_owner); var prevStorageUsage = ownerData.StorageUsage; ownerData.StorageUsage -= fileSize; await userManager.UpdateUserInDatabaseAsync(ownerData); lockEntry.ReleaseExclusiveWrite(); } }
public async Task <FileUploadResult> HandleUploadAsync(string fileName, Stream stream) { AssertIdentityProvided(); // Quota is affected var fileId = Guid.NewGuid().ToString(); var targetFile = GetTargetFilePath(fileId); var uploadStreamFileSize = stream.Length; try { // Write file (Wait for upload throttle) await ServerContext.ServiceTable[_owner] .UploadThrottle.WithResourceAsync(async() => { using (var destinationStream = File.Create(targetFile)) { await stream.CopyToAsync(destinationStream); } }); // Make sure user has enough space remaining if (_owner != null) { var lockEntry = ServerContext.ServiceTable[_owner].UserLock; await lockEntry.ObtainExclusiveWriteAsync(); var userManager = new WebUserManager(ServerContext); var ownerData = await userManager.FindUserByUsernameAsync(_owner); var afterUploadSpace = ownerData.StorageUsage + uploadStreamFileSize; if (afterUploadSpace > ownerData.StorageQuota) { lockEntry.ReleaseExclusiveWrite(); // Throw exception, catch block will remove file and rethrow throw new QuotaExceededException(); } // Increase user storage usage ownerData.StorageUsage += uploadStreamFileSize; await userManager.UpdateUserInDatabaseAsync(ownerData); lockEntry.ReleaseExclusiveWrite(); } } catch (QuotaExceededException) { // Roll back write await Task.Run(() => File.Delete(targetFile)); throw; } return(new FileUploadResult { FileId = fileId, Size = uploadStreamFileSize }); }