Example #1
0
 private async Task <GetFileResult> ReadFileFromLocalAsync()
 {
     return(await Task.Run(delegate
     {
         GetFileResult getFileResult = new GetFileResult
         {
             Code = HttpStatusCode.Unused
         };
         try
         {
             getFileResult.RespStream = fileReader.ReadFile();
             getFileResult.Code = HttpStatusCode.OK;
             return getFileResult;
         }
         catch (ArgumentException)
         {
             getFileResult.ErrorMessage = "File path contains invalid characters";
             return getFileResult;
         }
         catch (IOException)
         {
             getFileResult.ErrorMessage = "IO exception reading file";
             return getFileResult;
         }
         catch (UnauthorizedAccessException)
         {
             getFileResult.ErrorMessage = "Could not access file for reading";
             return getFileResult;
         }
     }).ConfigureAwait(false));
 }
Example #2
0
 private bool IsStale(GetFileResult fileResult)
 {
     if (fileResult.IsFromCache && fileResult.AgeSeconds.HasValue)
     {
         return(fileResult.AgeSeconds <= PollingIntervalMins * 60);
     }
     return(false);
 }
Example #3
0
        /// <summary>
        /// Get a file and send telemetry events.
        /// </summary>
        /// <param name="fromServer"></param>
        /// <returns></returns>
        private async Task <GetFileResult> GetFileAndInstrumentAsync(bool fromServer = false)
        {
            GetFileResult getFileResult = await(fromServer ? requestor.GetFileFromServerAsync() : requestor.GetFileFromCacheAsync()).ConfigureAwait(false);

            if (fromServer && (!getFileResult.IsFromCache || !getFileResult.IsSuccessStatusCode))
            {
                InstrumentGetFile(getFileResult);
            }
            return(getFileResult);
        }
Example #4
0
 /// <summary>
 /// Gets the elapsed time (in seconds) since the last error in downloading / revalidating the file from the
 /// server.
 /// </summary>
 /// <returns>Time in seconds since last error or Int.MaxValue if no error has ever occured.</returns>
 async Task <int> IRemoteControlHTTPRequestor.LastServerRequestErrorSecondsAgoAsync()
 {
     using (GetFileResult getFileResult = await GetFile(errorMarkerFileUrl, httpRequestTimeoutMillis, CacheOnlyPolicy).ConfigureAwait(false))
     {
         if (getFileResult.IsFromCache)
         {
             return(getFileResult.AgeSeconds.Value);
         }
         return(int.MaxValue);
     }
 }
Example #5
0
        /// <summary>
        /// Reads the file from the server url.
        /// In case of errors reading the file from the server, returned <see cref="T:Coding4Fun.VisualStudio.RemoteControl.GetFileResult" /> object's
        /// IsSuccessStatusCode value will be false.
        /// </summary>
        /// <returns>Information about the file obtained from the server</returns>
        async Task <GetFileResult> IRemoteControlHTTPRequestor.GetFileFromServerAsync()
        {
            GetFileResult result = new GetFileResult
            {
                Code = HttpStatusCode.Unused
            };

            try
            {
                int i = 0;
                while (true)
                {
                    if (i >= 2)
                    {
                        return(result);
                    }
                    if (i > 0)
                    {
                        int num = Math.Min(32, (int)Math.Pow(2.0, i));
                        try
                        {
                            await Task.Delay(num * 1000, cancellationTokenSource.Token).ConfigureAwait(false);
                        }
                        catch (OperationCanceledException)
                        {
                            return(result);
                        }
                        catch (ObjectDisposedException)
                        {
                            return(result);
                        }
                        result.Dispose();
                    }
                    result = await GetFile(url, httpRequestTimeoutMillis, ServerRevalidatePolicy).ConfigureAwait(false);

                    if (result.IsSuccessStatusCode)
                    {
                        break;
                    }
                    i++;
                }
                return(result);
            }
            finally
            {
                if (!result.IsSuccessStatusCode && Platform.IsWindows)
                {
                    WinINetHelper.WriteErrorResponseToCache(errorMarkerFileUrl, result.Code);
                }
            }
        }
Example #6
0
        /// <summary>
        /// Instruments the usage of GetFileFromCache and GetFileFromServer.
        /// </summary>
        /// <param name="fileResult"></param>
        private void InstrumentGetFile(GetFileResult fileResult)
        {
            Dictionary <string, object> dictionary = new Dictionary <string, object>
            {
                {
                    "VS.RemoteControl.DownloadFile.FullUrl",
                    FullUrl
                },
                {
                    "VS.RemoteControl.DownloadFile.IsSuccess",
                    fileResult.IsSuccessStatusCode
                },
                {
                    "VS.RemoteControl.DownloadFile.HttpRequestTimeoutInSecs",
                    httpRequestTimeoutSeconds
                },
                {
                    "VS.RemoteControl.DownloadFile.IsFromCache",
                    fileResult.IsFromCache
                },
                {
                    "VS.RemoteControl.DownloadFile.PollingIntervalInMins",
                    PollingIntervalMins
                }
            };
            Dictionary <string, object> dictionary2 = new Dictionary <string, object>();

            if (fileResult.IsSuccessStatusCode)
            {
                dictionary.Add("VS.RemoteControl.DownloadFile.IsNotFound", fileResult.Code == HttpStatusCode.NotFound);
                if (fileResult.RespStream != null)
                {
                    dictionary.Add("VS.RemoteControl.DownloadFile.StreamSize", fileResult.RespStream.Length);
                }
                if (fileResult.AgeSeconds.HasValue)
                {
                    dictionary.Add("VS.RemoteControl.DownloadFile.AgeInSecs", fileResult.AgeSeconds.Value);
                }
            }
            else
            {
                if (fileResult.Code != HttpStatusCode.Unused)
                {
                    dictionary.Add("VS.RemoteControl.DownloadFile.ErrorCode", Enum.GetName(typeof(HttpStatusCode), fileResult.Code));
                }
                dictionary2.Add("VS.RemoteControl.DownloadFile.ErrorMessage", fileResult.ErrorMessage);
            }
            TelemetryLogger2("VS/RemoteControl/DownloadFile", dictionary, dictionary2);
        }
Example #7
0
        /// <summary>
        /// Determines if a local IE cache copy of the file is up-to-date. If no cached copy is available or the
        /// cached copy is not up-to-date, a request is made to the server to download or revalidate the file. The
        /// result of the server request is cached.
        /// </summary>
        /// <param name="cancellationToken">Cancellation token to cancel waiting of operation</param>
        /// <returns>Returns True if the copy in the IE cache is up-to-date by the end of the method. False in case of
        /// failures that prevent updating file.</returns>
        private async Task <bool> EnsureFileIsUpToDateAsync(CancellationToken cancellationToken)
        {
            if (isDisabled)
            {
                return(false);
            }
            try
            {
                await updateMutex.WaitAsync(cancellationToken).ConfigureAwait(false);

                for (int i = 1; i <= 2; i++)
                {
                    using (GetFileResult getFileResult = await GetFileAndInstrumentAsync().ConfigureAwait(false))
                    {
                        if (IsStale(getFileResult))
                        {
                            return(getFileResult.IsSuccessStatusCode);
                        }
                    }
                    if (await requestor.LastServerRequestErrorSecondsAgoAsync().ConfigureAwait(false) < PollingIntervalMins * 60)
                    {
                        return(false);
                    }
                    if (i < 2)
                    {
                        await Task.Delay(rand.Next(0, maxRandomDownloadDelaySeconds), cancellationToken).ConfigureAwait(false);
                    }
                }
                using (GetFileResult getFileResult2 = await GetFileAndInstrumentAsync(true).ConfigureAwait(false))
                {
                    return(getFileResult2.IsSuccessStatusCode);
                }
            }
            finally
            {
                try
                {
                    updateMutex.Release();
                }
                catch (SemaphoreFullException)
                {
                }
            }
        }
Example #8
0
        /// <summary>
        /// Reads the settings file based on the <paramref name="staleBehavior" /> specified. This is the Async version
        /// of ReadFile method.
        /// </summary>
        /// <param name="staleBehavior">See <see cref="T:Coding4Fun.VisualStudio.RemoteControl.BehaviorOnStale" /> for details about each possible setting.
        /// In most cases use the BehaviorOnStale.ReturnStale setting.</param>
        /// <returns>A Stream that can be used to read the setting file. !Callers must call Dispose on this stream
        /// object returned. Or Null is returned in case of failure to get the file (or if server returned
        /// NotFound).</returns>
        public async Task <Stream> ReadFileAsync(BehaviorOnStale staleBehavior)
        {
            if (isDisabled)
            {
                return(null);
            }
            if (isDisposed)
            {
                throw new ObjectDisposedException("RemoteControlClient");
            }
            if (Uri.IsLocalFile)
            {
                return((await ReadFileFromLocalAsync().ConfigureAwait(false)).RespStream);
            }
            switch (staleBehavior)
            {
            case BehaviorOnStale.ReturnStale:
                return((await GetFileAndInstrumentAsync().ConfigureAwait(false)).RespStream);

            case BehaviorOnStale.ReturnNull:
            {
                GetFileResult getFileResult = await GetFileAndInstrumentAsync().ConfigureAwait(false);

                if (IsStale(getFileResult))
                {
                    return(getFileResult.RespStream);
                }
                getFileResult.Dispose();
                return(null);
            }

            case BehaviorOnStale.ForceDownload:
                return((await GetFileAndInstrumentAsync(true).ConfigureAwait(false)).RespStream);

            default:
                return(null);
            }
        }