コード例 #1
0
		public virtual void Run()
		{
			running = true;
			HttpClient httpClient;
			if (client == null)
			{
				// This is a race condition that can be reproduced by calling cbpuller.start() and cbpuller.stop()
				// directly afterwards.  What happens is that by the time the Changetracker thread fires up,
				// the cbpuller has already set this.client to null.  See issue #109
				Log.W(Database.Tag, "ChangeTracker run() loop aborting because client == null");
				return;
			}
			if (mode == ChangeTracker.ChangeTrackerMode.Continuous)
			{
				// there is a failing unit test for this, and from looking at the code the Replication
				// object will never use Continuous mode anyway.  Explicitly prevent its use until
				// it is demonstrated to actually work.
				throw new RuntimeException("ChangeTracker does not correctly support continuous mode"
					);
			}
			httpClient = client.GetHttpClient();
			ChangeTrackerBackoff backoff = new ChangeTrackerBackoff();
			while (running)
			{
				Uri url = GetChangesFeedURL();
				request = new HttpGet(url.ToString());
				AddRequestHeaders(request);
				// if the URL contains user info AND if this a DefaultHttpClient
				// then preemptively set the auth credentials
				if (url.GetUserInfo() != null)
				{
					Log.V(Database.Tag, "url.getUserInfo(): " + url.GetUserInfo());
					if (url.GetUserInfo().Contains(":") && !url.GetUserInfo().Trim().Equals(":"))
					{
						string[] userInfoSplit = url.GetUserInfo().Split(":");
						Credentials creds = new UsernamePasswordCredentials(URIUtils.Decode(userInfoSplit
							[0]), URIUtils.Decode(userInfoSplit[1]));
						if (httpClient is DefaultHttpClient)
						{
							DefaultHttpClient dhc = (DefaultHttpClient)httpClient;
							MessageProcessingHandler preemptiveAuth = new _MessageProcessingHandler_212(creds
								);
							dhc.AddRequestInterceptor(preemptiveAuth, 0);
						}
					}
					else
					{
						Log.W(Database.Tag, "ChangeTracker Unable to parse user info, not setting credentials"
							);
					}
				}
				try
				{
					string maskedRemoteWithoutCredentials = GetChangesFeedURL().ToString();
					maskedRemoteWithoutCredentials = maskedRemoteWithoutCredentials.ReplaceAll("://.*:.*@"
						, "://---:---@");
					Log.V(Database.Tag, "Making request to " + maskedRemoteWithoutCredentials);
					HttpResponse response = httpClient.Execute(request);
					StatusLine status = response.GetStatusLine();
					if (status.GetStatusCode() >= 300)
					{
						Log.E(Database.Tag, "Change tracker got error " + Sharpen.Extensions.ToString(status
							.GetStatusCode()));
						string msg = string.Format(status.ToString());
						this.error = new CouchbaseLiteException(msg, new Status(status.GetStatusCode()));
						Stop();
					}
					HttpEntity entity = response.GetEntity();
					InputStream input = null;
					if (entity != null)
					{
						input = entity.GetContent();
						if (mode == ChangeTracker.ChangeTrackerMode.LongPoll)
						{
							IDictionary<string, object> fullBody = Manager.GetObjectMapper().ReadValue<IDictionary
								>(input);
							bool responseOK = ReceivedPollResponse(fullBody);
							if (mode == ChangeTracker.ChangeTrackerMode.LongPoll && responseOK)
							{
								Log.V(Database.Tag, "Starting new longpoll");
								continue;
							}
							else
							{
								Log.W(Database.Tag, "Change tracker calling stop");
								Stop();
							}
						}
						else
						{
							JsonFactory jsonFactory = Manager.GetObjectMapper().GetJsonFactory();
							JsonParser jp = jsonFactory.CreateJsonParser(input);
							while (jp.NextToken() != JsonToken.StartArray)
							{
							}
							// ignore these tokens
							while (jp.NextToken() == JsonToken.StartObject)
							{
								IDictionary<string, object> change = (IDictionary)Manager.GetObjectMapper().ReadValue
									<IDictionary>(jp);
								if (!ReceivedChange(change))
								{
									Log.W(Database.Tag, string.Format("Received unparseable change line from server: %s"
										, change));
								}
							}
							Stop();
							break;
						}
						backoff.ResetBackoff();
					}
				}
				catch (Exception e)
				{
					if (!running && e is IOException)
					{
					}
					else
					{
						// in this case, just silently absorb the exception because it
						// frequently happens when we're shutting down and have to
						// close the socket underneath our read.
						Log.E(Database.Tag, "Exception in change tracker", e);
					}
					backoff.SleepAppropriateAmountOfTime();
				}
			}
			Log.V(Database.Tag, "Change tracker run loop exiting");
		}
コード例 #2
0
        public virtual void Run()
        {
            running = true;
            HttpClient httpClient;

            if (client == null)
            {
                // This is a race condition that can be reproduced by calling cbpuller.start() and cbpuller.stop()
                // directly afterwards.  What happens is that by the time the Changetracker thread fires up,
                // the cbpuller has already set this.client to null.  See issue #109
                Log.W(Database.Tag, "ChangeTracker run() loop aborting because client == null");
                return;
            }
            if (mode == ChangeTracker.ChangeTrackerMode.Continuous)
            {
                // there is a failing unit test for this, and from looking at the code the Replication
                // object will never use Continuous mode anyway.  Explicitly prevent its use until
                // it is demonstrated to actually work.
                throw new RuntimeException("ChangeTracker does not correctly support continuous mode"
                                           );
            }
            httpClient = client.GetHttpClient();
            ChangeTrackerBackoff backoff = new ChangeTrackerBackoff();

            while (running)
            {
                Uri url = GetChangesFeedURL();
                request = new HttpGet(url.ToString());
                AddRequestHeaders(request);
                // if the URL contains user info AND if this a DefaultHttpClient
                // then preemptively set the auth credentials
                if (url.GetUserInfo() != null)
                {
                    Log.V(Database.Tag, "url.getUserInfo(): " + url.GetUserInfo());
                    if (url.GetUserInfo().Contains(":") && !url.GetUserInfo().Trim().Equals(":"))
                    {
                        string[]    userInfoSplit = url.GetUserInfo().Split(":");
                        Credentials creds         = new UsernamePasswordCredentials(URIUtils.Decode(userInfoSplit
                                                                                                    [0]), URIUtils.Decode(userInfoSplit[1]));
                        if (httpClient is DefaultHttpClient)
                        {
                            DefaultHttpClient        dhc            = (DefaultHttpClient)httpClient;
                            MessageProcessingHandler preemptiveAuth = new _MessageProcessingHandler_212(creds
                                                                                                        );
                            dhc.AddRequestInterceptor(preemptiveAuth, 0);
                        }
                    }
                    else
                    {
                        Log.W(Database.Tag, "ChangeTracker Unable to parse user info, not setting credentials"
                              );
                    }
                }
                try
                {
                    string maskedRemoteWithoutCredentials = GetChangesFeedURL().ToString();
                    maskedRemoteWithoutCredentials = maskedRemoteWithoutCredentials.ReplaceAll("://.*:.*@"
                                                                                               , "://---:---@");
                    Log.V(Database.Tag, "Making request to " + maskedRemoteWithoutCredentials);
                    HttpResponse response = httpClient.Execute(request);
                    StatusLine   status   = response.GetStatusLine();
                    if (status.GetStatusCode() >= 300)
                    {
                        Log.E(Database.Tag, "Change tracker got error " + Sharpen.Extensions.ToString(status
                                                                                                      .GetStatusCode()));
                        string msg = string.Format(status.ToString());
                        this.error = new CouchbaseLiteException(msg, new Status(status.GetStatusCode()));
                        Stop();
                    }
                    HttpEntity  entity = response.GetEntity();
                    InputStream input  = null;
                    if (entity != null)
                    {
                        input = entity.GetContent();
                        if (mode == ChangeTracker.ChangeTrackerMode.LongPoll)
                        {
                            IDictionary <string, object> fullBody = Manager.GetObjectMapper().ReadValue <IDictionary
                                                                                                         >(input);
                            bool responseOK = ReceivedPollResponse(fullBody);
                            if (mode == ChangeTracker.ChangeTrackerMode.LongPoll && responseOK)
                            {
                                Log.V(Database.Tag, "Starting new longpoll");
                                continue;
                            }
                            else
                            {
                                Log.W(Database.Tag, "Change tracker calling stop");
                                Stop();
                            }
                        }
                        else
                        {
                            JsonFactory jsonFactory = Manager.GetObjectMapper().GetJsonFactory();
                            JsonParser  jp          = jsonFactory.CreateJsonParser(input);
                            while (jp.NextToken() != JsonToken.StartArray)
                            {
                            }
                            // ignore these tokens
                            while (jp.NextToken() == JsonToken.StartObject)
                            {
                                IDictionary <string, object> change = (IDictionary)Manager.GetObjectMapper().ReadValue
                                                                      <IDictionary>(jp);
                                if (!ReceivedChange(change))
                                {
                                    Log.W(Database.Tag, string.Format("Received unparseable change line from server: %s"
                                                                      , change));
                                }
                            }
                            Stop();
                            break;
                        }
                        backoff.ResetBackoff();
                    }
                }
                catch (Exception e)
                {
                    if (!running && e is IOException)
                    {
                    }
                    else
                    {
                        // in this case, just silently absorb the exception because it
                        // frequently happens when we're shutting down and have to
                        // close the socket underneath our read.
                        Log.E(Database.Tag, "Exception in change tracker", e);
                    }
                    backoff.SleepAppropriateAmountOfTime();
                }
            }
            Log.V(Database.Tag, "Change tracker run loop exiting");
        }