private DatabaseDocument GetTenantDatabaseDocument(string tenantId, bool ignoreDisabledFileSystem = false) { JsonDocument jsonDocument; using (systemDatabase.DisableAllTriggersForCurrentThread()) jsonDocument = systemDatabase.Documents.Get("Raven/FileSystems/" + tenantId, null); if (jsonDocument == null || jsonDocument.Metadata == null || jsonDocument.Metadata.Value <bool>(Constants.RavenDocumentDoesNotExists) || jsonDocument.Metadata.Value <bool>(Constants.RavenDeleteMarker)) { return(null); } var document = jsonDocument.DataAsJson.JsonDeserialization <DatabaseDocument>(); if (document.Settings.Keys.Contains("Raven/FileSystem/DataDir") == false) { throw new InvalidOperationException("Could not find Raven/FileSystem/DataDir"); } if (document.Disabled && !ignoreDisabledFileSystem) { throw new InvalidOperationException("The file system has been disabled."); } return(document); }
public static void SaveTemporalHistoryFor(this DocumentDatabase database, string key, TemporalHistory history, TransactionInformation transactionInformation, Etag etag) { using (database.DisableAllTriggersForCurrentThread()) { var document = RavenJObject.FromObject(history); var metadata = new RavenJObject(); database.Put(TemporalHistory.GetKeyFor(key), etag, document, metadata, transactionInformation); } }
private void ActivatePendingDocuments() { using (_database.DisableAllTriggersForCurrentThread()) { var revisionKeys = PendingRevisionsIndex.GetRevisionsRequiringActivation(_database); foreach (var revisionkey in revisionKeys) { _log.Info("Activating Temporal Document {0}", revisionkey); // Establish a new transaction var transactionInformation = new TransactionInformation { Id = Guid.NewGuid().ToString(), Timeout = TimeSpan.FromMinutes(1) }; // Get the current key from the revision key var currentKey = revisionkey.Substring(0, revisionkey.IndexOf(TemporalConstants.TemporalKeySeparator, StringComparison.Ordinal)); // Mark the document as non-pending _database.SetDocumentMetadata(revisionkey, transactionInformation, TemporalMetadata.RavenDocumentTemporalPending, false); // Mark it in the history also Etag historyEtag; var history = _database.GetTemporalHistoryFor(currentKey, transactionInformation, out historyEtag); history.Revisions.First(x => x.Key == revisionkey).Pending = false; _database.SaveTemporalHistoryFor(currentKey, history, transactionInformation, historyEtag); // Load the new revisions document var newRevisionDoc = _database.Get(revisionkey, transactionInformation); var temporal = newRevisionDoc.Metadata.GetTemporalMetadata(); if (temporal.Deleted) { // When the revision is a deletion, delete the current document _database.Delete(currentKey, null, transactionInformation); } else { // Prepare the current document metadata newRevisionDoc.Metadata.Remove(TemporalMetadata.RavenDocumentTemporalDeleted); newRevisionDoc.Metadata.Remove(TemporalMetadata.RavenDocumentTemporalPending); newRevisionDoc.Metadata.Remove("@id"); temporal.Status = TemporalStatus.Current; temporal.RevisionNumber = int.Parse(newRevisionDoc.Key.Split('/').Last()); // Copy the revision to the current document _database.Put(currentKey, null, newRevisionDoc.DataAsJson, newRevisionDoc.Metadata, transactionInformation); } // Commit the transaction _database.Commit(transactionInformation.Id); } } }
public static TemporalHistory GetTemporalHistoryFor(this DocumentDatabase database, string key, TransactionInformation transactionInformation, out Etag etag) { using (database.DisableAllTriggersForCurrentThread()) { var doc = database.Get(TemporalHistory.GetKeyFor(key), transactionInformation); if (doc == null) { etag = null; return(new TemporalHistory()); } etag = doc.Etag; return(doc.DataAsJson.JsonDeserialization <TemporalHistory>()); } }
public static TemporalVersioningConfiguration GetTemporalVersioningConfiguration(this DocumentDatabase database, string entityName) { using (database.DisableAllTriggersForCurrentThread()) { JsonDocument doc = null; if (entityName != null) { doc = database.Get(string.Format("Raven/{0}/{1}", TemporalConstants.BundleName, entityName), null); } if (doc == null) { doc = database.Get(string.Format("Raven/{0}/DefaultConfiguration", TemporalConstants.BundleName), null); } return(doc == null ? null : doc.DataAsJson.JsonDeserialization <TemporalVersioningConfiguration>()); } }
private void Execute() { var timeToWaitInMinutes = TimeSpan.FromMinutes(5); bool runningBecauseOfDataModifications = false; var context = docDb.WorkContext; while (context.DoWork) { try { using (docDb.DisableAllTriggersForCurrentThread()) { var destinations = GetReplicationDestinations(); if (destinations.Length == 0) { WarnIfNoReplicationTargetsWereFound(); } else { var currentReplicationAttempts = Interlocked.Increment(ref replicationAttempts); var copyOfrunningBecauseOfDataModifications = runningBecauseOfDataModifications; var destinationForReplication = destinations .Where(dest => { if (copyOfrunningBecauseOfDataModifications == false) { return(true); } return(IsNotFailing(dest, currentReplicationAttempts)); }); foreach (var dest in destinationForReplication) { var destination = dest; var holder = activeReplicationTasks.GetOrAdd(destination.Url, new IntHolder()); if (Thread.VolatileRead(ref holder.Value) == 1) { continue; } Thread.VolatileWrite(ref holder.Value, 1); Task.Factory.StartNew(() => ReplicateTo(destination), TaskCreationOptions.LongRunning) .ContinueWith(completedTask => { if (completedTask.Exception != null) { log.ErrorException("Could not replicate to " + destination, completedTask.Exception); return; } if (completedTask.Result) // force re-evaluation of replication again { docDb.WorkContext.NotifyAboutWork(); } }); } } } } catch (Exception e) { log.ErrorException("Failed to perform replication", e); } runningBecauseOfDataModifications = context.WaitForWork(timeToWaitInMinutes, ref workCounter); timeToWaitInMinutes = runningBecauseOfDataModifications ? TimeSpan.FromSeconds(30) : TimeSpan.FromMinutes(5); } }
private void Execute() { using (LogContext.WithDatabase(docDb.Name)) { var name = GetType().Name; var timeToWaitInMinutes = TimeSpan.FromMinutes(5); bool runningBecauseOfDataModifications = false; var context = docDb.WorkContext; NotifySiblings(); while (context.DoWork) { try { using (docDb.DisableAllTriggersForCurrentThread()) { var destinations = GetReplicationDestinations(); if (destinations.Length == 0) { WarnIfNoReplicationTargetsWereFound(); } else { var currentReplicationAttempts = Interlocked.Increment(ref replicationAttempts); var copyOfrunningBecauseOfDataModifications = runningBecauseOfDataModifications; var destinationForReplication = destinations .Where(dest => { if (copyOfrunningBecauseOfDataModifications == false) { return(true); } return(IsNotFailing(dest, currentReplicationAttempts)); }); foreach (var dest in destinationForReplication) { var destination = dest; var holder = activeReplicationTasks.GetOrAdd(destination.ConnectionStringOptions.Url, new IntHolder()); if (Thread.VolatileRead(ref holder.Value) == 1) { continue; } Thread.VolatileWrite(ref holder.Value, 1); var replicationTask = Task.Factory.StartNew(() => { using (LogContext.WithDatabase(docDb.Name)) { try { if (ReplicateTo(destination)) { docDb.WorkContext.NotifyAboutWork(); } } catch (Exception e) { log.ErrorException("Could not replicate to " + destination, e); } } }); activeTasks.Enqueue(replicationTask); replicationTask.ContinueWith(_ => { // here we purge all the completed tasks at the head of the queue Task task; while (activeTasks.TryPeek(out task)) { if (!task.IsCompleted && !task.IsCanceled && !task.IsFaulted) { break; } activeTasks.TryDequeue(out task); // remove it from end } }); } } } } catch (Exception e) { log.ErrorException("Failed to perform replication", e); } runningBecauseOfDataModifications = context.WaitForWork(timeToWaitInMinutes, ref workCounter, name); timeToWaitInMinutes = runningBecauseOfDataModifications ? TimeSpan.FromSeconds(30) : TimeSpan.FromMinutes(5); } } }