private async Task EstablishConnection()
        {
            if (disposed)
            {
                return;
            }

#if !NETFX_CORE
            if (clientSideHeartbeatTimer != null)
            {
                clientSideHeartbeatTimer.Dispose();
                clientSideHeartbeatTimer = null;
            }
#endif

            var requestParams = new CreateHttpJsonRequestParams(null, url + "/changes/events?id=" + id, "GET", credentials,
                                                                conventions)
            {
                AvoidCachingRequest       = true,
                DisableRequestCompression = true
            };

            logger.Info("Trying to connect to {0} with id {1}", requestParams.Url, id);
            bool retry = false;
            IObservable <string> serverEvents = null;
            try
            {
                serverEvents = await jsonRequestFactory.CreateHttpJsonRequest(requestParams).ServerPullAsync().ConfigureAwait(false);
            }
            catch (Exception e)
            {
                logger.WarnException("Could not connect to server: " + url + " and id " + id, e);
                Connected = false;
                ConnectionStatusChanged(this, EventArgs.Empty);

                if (disposed)
                {
                    throw;
                }

                bool timeout;
                if (replicationInformer.IsServerDown(e, out timeout) == false)
                {
                    throw;
                }

                if (replicationInformer.IsHttpStatus(e, HttpStatusCode.NotFound, HttpStatusCode.Forbidden, HttpStatusCode.ServiceUnavailable))
                {
                    throw;
                }

                logger.Warn("Failed to connect to {0} with id {1}, will try again in 15 seconds", url, id);
                retry = true;
            }

            if (retry)
            {
                await Time.Delay(TimeSpan.FromSeconds(15)).ConfigureAwait(false);
                await EstablishConnection().ConfigureAwait(false);

                return;
            }
            if (disposed)
            {
                Connected = false;
                ConnectionStatusChanged(this, EventArgs.Empty);
                throw new ObjectDisposedException("RemoteDatabaseChanges");
            }

            Connected = true;
            ConnectionStatusChanged(this, EventArgs.Empty);
            connection = (IDisposable)serverEvents;
            serverEvents.Subscribe(this);

#if !NETFX_CORE
            clientSideHeartbeatTimer = new Timer(ClientSideHeartbeat, null, TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(10));
#endif

            if (watchAllDocs)
            {
                await Send("watch-docs", null).ConfigureAwait(false);
            }

            if (watchAllIndexes)
            {
                await Send("watch-indexes", null).ConfigureAwait(false);
            }

            foreach (var watchedDoc in watchedDocs)
            {
                await Send("watch-doc", watchedDoc).ConfigureAwait(false);
            }

            foreach (var watchedPrefix in watchedPrefixes)
            {
                await Send("watch-prefix", watchedPrefix).ConfigureAwait(false);
            }

            foreach (var watchedCollection in watchedCollections)
            {
                await Send("watch-collection", watchedCollection);
            }

            foreach (var watchedType in watchedTypes)
            {
                await Send("watch-type", watchedType);
            }

            foreach (var watchedIndex in watchedIndexes)
            {
                await Send("watch-indexes", watchedIndex).ConfigureAwait(false);
            }

            foreach (var watchedBulkInsert in watchedBulkInserts)
            {
                await Send("watch-bulk-operation", watchedBulkInsert).ConfigureAwait(false);
            }
        }
Esempio n. 2
0
        private Task EstablishConnection()
        {
            if (disposed)
            {
                return(new CompletedTask());
            }

            var requestParams = new CreateHttpJsonRequestParams(null, url + "/changes/events?id=" + id, "GET", credentials, conventions)
            {
                AvoidCachingRequest = true
            };

            return(jsonRequestFactory.CreateHttpJsonRequest(requestParams)
                   .ServerPullAsync()
                   .ContinueWith(task =>
            {
                if (disposed)
                {
                    throw new ObjectDisposedException("RemoteDatabaseChanges");
                }
                if (task.IsFaulted)
                {
                    logger.WarnException("Could not connect to server, will retry", task.Exception);
                    Connected = false;
                    ConnectionStatusChanged(this, EventArgs.Empty);

                    if (disposed)
                    {
                        return task;
                    }


                    if (replicationInformer.IsServerDown(task.Exception) == false)
                    {
                        return task;
                    }

                    if (replicationInformer.IsHttpStatus(task.Exception,
                                                         HttpStatusCode.NotFound,
                                                         HttpStatusCode.Forbidden))
                    {
                        return task;
                    }

                    return Time.Delay(TimeSpan.FromSeconds(15))
                    .ContinueWith(_ => EstablishConnection())
                    .Unwrap();
                }

                Connected = true;
                ConnectionStatusChanged(this, EventArgs.Empty);
                connection = (IDisposable)task.Result;
                task.Result.Subscribe(this);

                Task prev = watchAllDocs ? Send("watch-docs", null) : new CompletedTask();

                if (watchAllIndexes)
                {
                    prev = prev.ContinueWith(_ => Send("watch-indexes", null));
                }

                prev = watchedDocs.Aggregate(prev, (cur, docId) => cur.ContinueWith(task1 => Send("watch-doc", docId)));

                prev = watchedPrefixes.Aggregate(prev, (cur, prefix) => cur.ContinueWith(task1 => Send("watch-prefix", prefix)));

                prev = watchedIndexes.Aggregate(prev, (cur, index) => cur.ContinueWith(task1 => Send("watch-indexes", index)));

                return prev;
            })
                   .Unwrap());
        }