public HttpResponseMessage Compact() { var db = InnerRequest.RequestUri.ParseQueryString()["database"]; if (string.IsNullOrWhiteSpace(db)) return GetMessageWithString("Compact request requires a valid database parameter", HttpStatusCode.BadRequest); var configuration = DatabasesLandlord.CreateTenantConfiguration(db); if (configuration == null) return GetMessageWithString("No database named: " + db, HttpStatusCode.NotFound); var task = Task.Factory.StartNew(() => { var compactStatus = new CompactStatus { State = CompactStatusState.Running, Messages = new List<string>() }; DatabasesLandlord.SystemDatabase.Documents.Delete(CompactStatus.RavenDatabaseCompactStatusDocumentKey(db), null, null); try { var targetDb = DatabasesLandlord.GetDatabaseInternal(db).ResultUnwrap(); DatabasesLandlord.Lock(db, () => targetDb.TransactionalStorage.Compact(configuration, msg => { bool skipProgressReport = false; bool isProgressReport = false; if(IsUpdateMessage(msg)) { isProgressReport = true; var now = SystemTime.UtcNow; compactStatus.LastProgressMessageTime = compactStatus.LastProgressMessageTime ?? DateTime.MinValue; var timeFromLastUpdate = (now - compactStatus.LastProgressMessageTime.Value); if (timeFromLastUpdate >= ReportProgressInterval) { compactStatus.LastProgressMessageTime = now; compactStatus.LastProgressMessage = msg; } else skipProgressReport = true; } if (!skipProgressReport) { if (!isProgressReport) compactStatus.Messages.Add(msg); DatabasesLandlord.SystemDatabase.Documents.Put(CompactStatus.RavenDatabaseCompactStatusDocumentKey(db), null, RavenJObject.FromObject(compactStatus), new RavenJObject(), null); } })); compactStatus.State = CompactStatusState.Completed; compactStatus.Messages.Add("Database compaction completed."); DatabasesLandlord.SystemDatabase.Documents.Put(CompactStatus.RavenDatabaseCompactStatusDocumentKey(db), null, RavenJObject.FromObject(compactStatus), new RavenJObject(), null); } catch (Exception e) { compactStatus.Messages.Add("Unable to compact database " + e.Message); compactStatus.State = CompactStatusState.Faulted; DatabasesLandlord.SystemDatabase.Documents.Put(CompactStatus.RavenDatabaseCompactStatusDocumentKey(db), null, RavenJObject.FromObject(compactStatus), new RavenJObject(), null); throw; } return GetEmptyMessage(); }); long id; Database.Tasks.AddTask(task, new TaskBasedOperationState(task), new TaskActions.PendingTaskDescription { StartTime = SystemTime.UtcNow, TaskType = TaskActions.PendingTaskType.CompactDatabase, Payload = "Compact database " + db, }, out id); return GetMessageWithObject(new { OperationId = id }); }
public HttpResponseMessage Compact() { var fs = InnerRequest.RequestUri.ParseQueryString()["filesystem"]; if (string.IsNullOrWhiteSpace(fs)) return GetMessageWithString("Compact request requires a valid filesystem parameter", HttpStatusCode.BadRequest); var configuration = FileSystemsLandlord.CreateTenantConfiguration(fs); if (configuration == null) return GetMessageWithString("No filesystem named: " + fs, HttpStatusCode.NotFound); var task = Task.Factory.StartNew(() => { var compactStatus = new CompactStatus { State = CompactStatusState.Running, Messages = new List<string>() }; DatabasesLandlord.SystemDatabase.Documents.Delete(CompactStatus.RavenFilesystemCompactStatusDocumentKey(fs), null, null); try { // as we perform compact async we don't catch exceptions here - they will be propagated to operation var targetFs = AsyncHelpers.RunSync(() => FileSystemsLandlord.GetFileSystemInternalAsync(fs)); FileSystemsLandlord.Lock(fs, () => targetFs.Storage.Compact(configuration, msg => { bool skipProgressReport = false; bool isProgressReport = false; if (IsUpdateMessage(msg)) { isProgressReport = true; var now = SystemTime.UtcNow; compactStatus.LastProgressMessageTime = compactStatus.LastProgressMessageTime ?? DateTime.MinValue; var timeFromLastUpdate = (now - compactStatus.LastProgressMessageTime.Value); if (timeFromLastUpdate >= ReportProgressInterval) { compactStatus.LastProgressMessageTime = now; compactStatus.LastProgressMessage = msg; } else skipProgressReport = true; } if (!skipProgressReport) { if (!isProgressReport) compactStatus.Messages.Add(msg); DatabasesLandlord.SystemDatabase.Documents.Put(CompactStatus.RavenFilesystemCompactStatusDocumentKey(fs), null, RavenJObject.FromObject(compactStatus), new RavenJObject(), null); } })); compactStatus.State = CompactStatusState.Completed; compactStatus.Messages.Add("File system compaction completed."); DatabasesLandlord.SystemDatabase.Documents.Put(CompactStatus.RavenFilesystemCompactStatusDocumentKey(fs), null, RavenJObject.FromObject(compactStatus), new RavenJObject(), null); } catch (Exception e) { compactStatus.Messages.Add("Unable to compact file system " + e.Message); compactStatus.State = CompactStatusState.Faulted; DatabasesLandlord.SystemDatabase.Documents.Put(CompactStatus.RavenFilesystemCompactStatusDocumentKey(fs), null, RavenJObject.FromObject(compactStatus), new RavenJObject(), null); throw; } return GetEmptyMessage(); }); long id; Database.Tasks.AddTask(task, new TaskBasedOperationState(task), new TaskActions.PendingTaskDescription { StartTime = SystemTime.UtcNow, TaskType = TaskActions.PendingTaskType.CompactFilesystem, Payload = "Compact filesystem " + fs, }, out id); return GetMessageWithObject(new { OperationId = id }); }