private async Task DoLongPollingRefresh(string appId, string cluster, string dataCenter, CancellationToken cancellationToken)
        {
            var        random         = new Random();
            ServiceDto lastServiceDto = null;

            while (!cancellationToken.IsCancellationRequested)
            {
                var    sleepTime = 50; //default 50 ms
                string url       = null;
                try
                {
                    if (lastServiceDto == null)
                    {
                        var configServices = await _serviceLocator.GetConfigServices().ConfigureAwait(false);

                        lastServiceDto = configServices[random.Next(configServices.Count)];
                    }

                    url = AssembleLongPollRefreshUrl(lastServiceDto.HomepageUrl, appId, cluster, dataCenter);

                    Logger().Debug($"Long polling from {url}");

                    var response = await _httpUtil.DoGetAsync <IList <ApolloConfigNotification> >(url, 600000).ConfigureAwait(false);

                    Logger().Debug($"Long polling response: {response.StatusCode}, url: {url}");
                    if (response.StatusCode == HttpStatusCode.OK && response.Body != null)
                    {
                        UpdateNotifications(response.Body);
                        UpdateRemoteNotifications(response.Body);
                        Notify(lastServiceDto, response.Body);
                        _longPollSuccessSchedulePolicyInMs.Success();
                    }
                    else
                    {
                        sleepTime = _longPollSuccessSchedulePolicyInMs.Fail();
                    }

                    //try to load balance
                    if (response.StatusCode == HttpStatusCode.NotModified && random.NextDouble() >= 0.5)
                    {
                        lastServiceDto = null;
                    }

                    _longPollFailSchedulePolicyInSecond.Success();
                }
                catch (Exception ex)
                {
                    lastServiceDto = null;

                    var sleepTimeInSecond = _longPollFailSchedulePolicyInSecond.Fail();
                    Logger().Warn($"Long polling failed, will retry in {sleepTimeInSecond} seconds. appId: {appId}, cluster: {cluster}, namespace: {string.Join(ConfigConsts.ClusterNamespaceSeparator, _longPollNamespaces.Keys)}, long polling url: {url}, reason: {ex.GetDetailMessage()}");

                    sleepTime = sleepTimeInSecond * 1000;
                }
                finally
                {
                    await Task.Delay(sleepTime, cancellationToken).ConfigureAwait(false);
                }
            }
        }
        private void DoLongPollingRefresh(string appId, string cluster, string dataCenter)
        {
            Random     random         = new Random();
            ServiceDTO lastServiceDto = null;

            while (!m_longPollingStopped.ReadFullFence())
            {
                int    sleepTime = 50; //default 50 ms
                string url       = null;
                try
                {
                    if (lastServiceDto == null)
                    {
                        IList <ServiceDTO> configServices = ConfigServices;
                        lastServiceDto = configServices[random.Next(configServices.Count)];
                    }

                    url = AssembleLongPollRefreshUrl(lastServiceDto.HomepageUrl, appId, cluster, dataCenter);

                    logger.Debug(
                        string.Format("Long polling from {0}", url));
                    Com.Ctrip.Framework.Apollo.Util.Http.HttpRequest request = new Com.Ctrip.Framework.Apollo.Util.Http.HttpRequest(url);
                    //longer timeout - 10 minutes
                    request.Timeout = 600000;

                    HttpResponse <IList <ApolloConfigNotification> > response = m_httpUtil.DoGet <IList <ApolloConfigNotification> >(request);

                    logger.Debug(
                        string.Format("Long polling response: {0}, url: {1}", response.StatusCode, url));
                    if (response.StatusCode == 200 && response.Body != null)
                    {
                        UpdateNotifications(response.Body);
                        UpdateRemoteNotifications(response.Body);
                        Notify(lastServiceDto, response.Body);
                        m_longPollSuccessSchedulePolicyInMS.Success();
                    }
                    else
                    {
                        sleepTime = m_longPollSuccessSchedulePolicyInMS.Fail();
                    }

                    //try to load balance
                    if (response.StatusCode == 304 && random.NextDouble() >= 0.5)
                    {
                        lastServiceDto = null;
                    }

                    m_longPollFailSchedulePolicyInSecond.Success();
                }
                catch (Exception ex)
                {
                    lastServiceDto = null;

                    int sleepTimeInSecond = m_longPollFailSchedulePolicyInSecond.Fail();
                    logger.Warn(
                        string.Format("Long polling failed, will retry in {0} seconds. appId: {1}, cluster: {2}, namespace: {3}, long polling url: {4}, reason: {5}",
                                      sleepTimeInSecond, appId, cluster, AssembleNamespaces(), url, ExceptionUtil.GetDetailMessage(ex)));

                    sleepTime = sleepTimeInSecond * 1000;
                }
                finally
                {
                    Thread.Sleep(sleepTime);
                }
            }
        }