Exemple #1
0
        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();
     }
 }
Exemple #4
0
        /// <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;
            }
        }
Exemple #7
0
        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);
        }