private void UpdateReplicationInformationFromDocument(JsonDocument document) { var replicationDocument = document.DataAsJson.JsonDeserialization <ReplicationDocument>(); replicationDestinations = replicationDocument.Destinations.Select(x => { if (string.IsNullOrEmpty(x.Url)) { return(null); } if (string.IsNullOrEmpty(x.Database)) { return(x.Url); } return(MultiDatabase.GetRootDatabaseUrl(x.Url) + "/databases/" + x.Database + "/"); }) // filter out replication destination that don't have the url setup, we don't know how to reach them // so we might as well ignore them. Probably private replication destination (using connection string names only) .Where(x => x != null) .ToList(); foreach (var replicationDestination in replicationDestinations) { FailureCounter value; if (failureCounts.TryGetValue(replicationDestination, out value)) { continue; } failureCounts[replicationDestination] = new FailureCounter(); } }
private void RefreshReplicationInformationInternal(string url, Func <ReplicationDocument> getReplicationDestinations) { lock (this) { var serverHash = ServerHash.GetServerHash(url); JsonDocument document; var fromFailoverUrls = false; try { var replicationDestinations = getReplicationDestinations(); document = replicationDestinations == null ? null : RavenJObject.FromObject(replicationDestinations).ToJsonDocument(); failureCounts[url] = new FailureCounter(); // we just hit the master, so we can reset its failure count } catch (Exception e) { log.ErrorException("Could not contact master for new replication information", e); document = ReplicationInformerLocalCache.TryLoadReplicationInformationFromLocalCache(serverHash); if (document == null) { if (FailoverServers != null && FailoverServers.Length > 0) // try to use configured failover servers { var failoverServers = new ReplicationDocument { Destinations = new List <ReplicationDestination>() }; foreach (var failover in FailoverServers) { failoverServers.Destinations.Add(failover); } document = new JsonDocument { DataAsJson = RavenJObject.FromObject(failoverServers) }; fromFailoverUrls = true; } } } if (document == null) { lastReplicationUpdate = SystemTime.UtcNow; // checked and not found return; } if (!fromFailoverUrls) { ReplicationInformerLocalCache.TrySavingReplicationInformationToLocalCache(serverHash, document); } UpdateReplicationInformationFromDocument(document); lastReplicationUpdate = SystemTime.UtcNow; } }
private void UpdateReplicationInformationFromDocument(IEnumerable <string> destinations) { foreach (var destination in destinations) { FailureCounter value; if (failureCounts.TryGetValue(destination, out value)) { continue; } failureCounts[destination] = new FailureCounter(); } }
/// <summary> /// Increments the failure count for the specified operation URL /// </summary> /// <param name="operationUrl">The operation URL.</param> public void IncrementFailureCount(string operationUrl) { FailureCounter value = GetHolder(operationUrl); var current = Interlocked.Increment(ref value.Value); if (current == 1) // first failure { FailoverStatusChanged(this, new FailoverStatusChangedEventArgs { Url = operationUrl, Failing = true }); } }
/// <summary> /// Refreshes the replication information. /// Expert use only. /// </summary> public override void RefreshReplicationInformation(IAsyncFilesCommands commands) { lock (this) { var serverClient = (IAsyncFilesCommandsImpl)commands; string urlForFilename = serverClient.UrlFor(); var serverHash = ServerHash.GetServerHash(urlForFilename); JsonDocument document = null; try { var config = serverClient.Configuration.GetKeyAsync <RavenJObject>(SynchronizationConstants.RavenSynchronizationDestinations).Result; failureCounts[urlForFilename] = new FailureCounter(); // we just hit the master, so we can reset its failure count if (config != null) { var destinationsArray = config.Value <RavenJArray>("Destinations"); if (destinationsArray != null) { document = new JsonDocument(); document.DataAsJson = new RavenJObject() { { "Destinations", destinationsArray } }; } } } catch (Exception e) { log.ErrorException("Could not contact master for new replication information", e); document = ReplicationInformerLocalCache.TryLoadReplicationInformationFromLocalCache(serverHash); } if (document == null) { lastReplicationUpdate = SystemTime.UtcNow; // checked and not found return; } ReplicationInformerLocalCache.TrySavingReplicationInformationToLocalCache(serverHash, document); UpdateReplicationInformationFromDocument(document); lastReplicationUpdate = SystemTime.UtcNow; } }
/// <summary> /// Refreshes the replication information. /// Expert use only. /// </summary> public override void RefreshReplicationInformation(IAsyncFilesCommands commands) { lock (this) { var serverClient = (IAsyncFilesCommandsImpl)commands; var urlForFilename = serverClient.UrlFor(); var serverHash = ServerHash.GetServerHash(urlForFilename); JsonDocument document = null; try { var destinations = serverClient.Synchronization.GetDestinationsAsync().Result; failureCounts[urlForFilename] = new FailureCounter(); // we just hit the master, so we can reset its failure count if (destinations != null) { document = new JsonDocument { DataAsJson = new RavenJObject() { { "Destinations", RavenJToken.FromObject(destinations) } } }; } } catch (Exception e) { log.ErrorException("Could not contact master for new replication information", e); document = ReplicationInformerLocalCache.TryLoadReplicationInformationFromLocalCache(serverHash); } if (document == null) { LastReplicationUpdate = SystemTime.UtcNow; // checked and not found ReplicationDestinations.Clear(); // clear destinations that could be retrieved from local storage return; } ReplicationInformerLocalCache.TrySavingReplicationInformationToLocalCache(serverHash, document); UpdateReplicationInformationFromDocument(document); LastReplicationUpdate = SystemTime.UtcNow; } }
private FailureCounter GetHolder(string operationUrl) { #if !SILVERLIGHT return(failureCounts.GetOrAdd(operationUrl, new FailureCounter())); #else // need to compensate for 3.5 not having concurrent dic. FailureCounter value; if (failureCounts.TryGetValue(operationUrl, out value) == false) { lock (replicationLock) { if (failureCounts.TryGetValue(operationUrl, out value) == false) { failureCounts[operationUrl] = value = new FailureCounter(); } } } return(value); #endif }
/// <summary> /// Determines whether this is the first failure on the specified operation URL. /// </summary> /// <param name="operationUrl">The operation URL.</param> public bool IsFirstFailure(string operationUrl) { FailureCounter value = GetHolder(operationUrl); return(value.Value == 0); }