Пример #1
0
        /// <summary>
        /// Reads an item from the storage. Order is Last-In-First-Out.
        /// When the Transmission is no longer needed (it was either sent or failed with a non-retriable error) it should be disposed.
        /// </summary>
        internal override StorageTransmission Peek()
        {
            IEnumerable <FileInfo> files = this.GetFiles("*.trn");

            lock (this.peekLockObj)
            {
                foreach (FileInfo file in files)
                {
                    try
                    {
                        // if a file was peeked before, skip it (wait until it is disposed).
                        if (this.peekedTransmissions.ContainsKey(file.Name) == false && this.deletedFilesQueue.Contains(file.Name) == false)
                        {
                            // Load the transmission from disk.
                            StorageTransmission storageTransmissionItem = LoadTransmissionFromFileAsync(file).ConfigureAwait(false).GetAwaiter().GetResult();

                            // when item is disposed it should be removed from the peeked list.
                            storageTransmissionItem.Disposing = item => this.OnPeekedItemDisposed(file.Name);

                            // add the transmission to the list.
                            this.peekedTransmissions.Add(file.Name, file.FullName);
                            return(storageTransmissionItem);
                        }
                    }
                    catch (Exception e)
                    {
                        string msg = string.Format(CultureInfo.InvariantCulture, "Failed to load an item from the storage. file: {0} Exception: {1}", file, e);
                        CoreEventSource.Log.LogVerbose(msg);
                    }
                }
            }

            return(null);
        }
Пример #2
0
        internal override void Delete(StorageTransmission item)
        {
            try
            {
                if (this.StorageFolder == null)
                {
                    return;
                }

                // Initial storage size calculation.
                this.EnsureSizeIsCalculatedAsync().ConfigureAwait(false).GetAwaiter().GetResult();

                IStorageFile file     = this.StorageFolder.GetFileAsync(item.FileName).AsTask().ConfigureAwait(false).GetAwaiter().GetResult();
                long         fileSize = this.GetSizeAsync(file).ConfigureAwait(false).GetAwaiter().GetResult();
                file.DeleteAsync(StorageDeleteOption.PermanentDelete).AsTask().ConfigureAwait(false).GetAwaiter().GetResult();
                this.deletedFilesQueue.Enqueue(item.FileName);

                // calculate size
                Interlocked.Add(ref this.storageSize, -fileSize);
                Interlocked.Decrement(ref this.storageCountFiles);
            }
            catch (IOException e)
            {
                string msg = string.Format(CultureInfo.InvariantCulture, "Failed to delete a file. file: {0} Exception: {1}", item == null ? "null" : item.FullFilePath, e);
                CoreEventSource.Log.LogVerbose(msg);
            }
        }
 private static async Task SaveTransmissionToFileAsync(Transmission transmission, IStorageFile file)
 {
     try
     {
         using (Stream stream = await file.OpenStreamForWriteAsync().ConfigureAwait(false))
         {
             await StorageTransmission.SaveAsync(transmission, stream).ConfigureAwait(false);
         }
     }
     catch (UnauthorizedAccessException)
     {
         string message = string.Format("Failed to save transmission to file. UnauthorizedAccessException. File path: {0}, FileName: {1}", file.Path, file.Name);
         CoreEventSource.Log.LogVerbose(message);
         throw;
     }
 }
        /// <summary>
        /// Send transmissions in a loop.
        /// </summary>
        protected void SendLoop()
        {
            TimeSpan prevSendingInterval = TimeSpan.Zero;
            TimeSpan sendingInterval     = this.sendingIntervalOnNoData;

            try
            {
                while (!this.stopped)
                {
                    using (StorageTransmission transmission = this.storage.Peek())
                    {
                        if (this.stopped)
                        {
                            // This second verfiication is required for cases where 'stopped' was set while peek was happening.
                            // Once the actual sending starts the design is to wait until it finishes and deletes the transmission.
                            // So no extra validation is required.
                            break;
                        }

                        // If there is a transmission to send - send it.
                        if (transmission != null)
                        {
                            bool shouldRetry = this.Send(transmission, ref sendingInterval);
                            if (!shouldRetry)
                            {
                                // If retry is not required - delete the transmission.
                                this.storage.Delete(transmission);
                            }
                        }
                        else
                        {
                            sendingInterval = this.sendingIntervalOnNoData;
                        }
                    }

                    LogInterval(prevSendingInterval, sendingInterval);
                    this.DelayHandler.WaitOne(sendingInterval);
                    prevSendingInterval = sendingInterval;
                }

                this.stoppedHandler.Set();
            }
            catch (ObjectDisposedException)
            {
            }
        }
        private static async Task <StorageTransmission> LoadTransmissionFromFileAsync(IStorageFile file)
        {
            try
            {
                using (Stream stream = await file.OpenStreamForReadAsync().ConfigureAwait(false))
                {
                    StorageTransmission storageTransmissionItem = await StorageTransmission.CreateFromStreamAsync(stream, file.Path).ConfigureAwait(false);

                    return(storageTransmissionItem);
                }
            }
            catch (Exception e)
            {
                string message = string.Format("Failed to load transmission from file. File path: {0}, FileName: {1}, Exception: {2}", file.Path, file.Name, e);
                CoreEventSource.Log.LogVerbose(message);
                throw;
            }
        }
Пример #6
0
        internal override void Delete(StorageTransmission item)
        {
            if (this.StorageFolder == null)
            {
                return;
            }

            try
            {
                File.Delete(item.FullFilePath);
                this.deletedFilesQueue.Enqueue(item.FileName);
            }
            catch (IOException e)
            {
                string msg = string.Format(CultureInfo.InvariantCulture, "Failed to delete a file. file: {0} Exception: {1}", item == null ? "null" : item.FullFilePath, e);
                CoreEventSource.Log.LogVerbose(msg);
            }
            catch (UnauthorizedAccessException e)
            {
                string msg = string.Format(CultureInfo.InvariantCulture, "Failed to delete a file. file: {0} Exception: {1}", item == null ? "null" : item.FullFilePath, e);
                CoreEventSource.Log.LogVerbose(msg);
            }
        }
Пример #7
0
        /// <summary>
        /// Sends a transmission and handle errors.
        /// </summary>
        /// <param name="transmission">The transmission to send.</param>
        /// <param name="nextSendInterval">When this value returns it will hold a recommendation for when to start the next sending iteration.</param>
        /// <returns>A boolean value that indicates if there was a retriable error.</returns>
        protected virtual bool Send(StorageTransmission transmission, ref TimeSpan nextSendInterval)
        {
            try
            {
                if (transmission != null)
                {
                    transmission.SendAsync().ConfigureAwait(false).GetAwaiter().GetResult();

                    // After a successful sending, try immeidiately to send another transmission.
                    nextSendInterval = this.SendingInterval;
                }
            }
            // https://github.com/microsoft/ApplicationInsights-dotnet/blob/70e438848915ec163fd7794221b27be34260d3b4/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs#L158
            // HttpClient.SendAsync throws HttpRequestException only on the following scenarios:
            // "The request failed due to an underlying issue such as network connectivity, DNS failure, server certificate validation or timeout."
            // i.e for Server errors (500 status code), no exception is thrown.
            catch (HttpRequestException)
            {
                nextSendInterval = this.CalculateNextInterval(null, nextSendInterval, this.maxIntervalBetweenRetries);
                return(true);
            }
            catch (WebException e)
            {
                int?statusCode = GetStatusCode(e);
                nextSendInterval = this.CalculateNextInterval(statusCode, nextSendInterval, this.maxIntervalBetweenRetries);
                return(IsRetryable(statusCode, e.Status));
            }
            catch (Exception e)
            {
                nextSendInterval = this.CalculateNextInterval(null, nextSendInterval, this.maxIntervalBetweenRetries);
                string msg = string.Format(CultureInfo.InvariantCulture, "Unknown exception during sending: {0}", e);
                CoreEventSource.Log.LogVerbose(msg);
            }

            return(false);
        }
        internal override void Delete(StorageTransmission item)
        {
            if (this.StorageFolder == null)
            {
                return;
            }

            try
            {
                File.Delete(item.FullFilePath);
                this.deletedFilesQueue.Enqueue(item.FileName);
            }
            catch (IOException e)
            {
                string msg = string.Format(CultureInfo.InvariantCulture, "Failed to delete a file. file: {0} Exception: {1}", item == null ? "null" : item.FullFilePath, e);
                CoreEventSource.Log.LogVerbose(msg);
            }
            catch (UnauthorizedAccessException e)
            {
                string msg = string.Format(CultureInfo.InvariantCulture, "Failed to delete a file. file: {0} Exception: {1}", item == null ? "null" : item.FullFilePath, e);
                CoreEventSource.Log.LogVerbose(msg);
            }
        }
Пример #9
0
 internal abstract void Delete(StorageTransmission transmission);
        /// <summary>
        /// Sends a transmission and handle errors.
        /// </summary>
        /// <param name="transmission">The transmission to send.</param>
        /// <param name="nextSendInterval">When this value returns it will hold a recommendation for when to start the next sending iteration.</param>
        /// <returns>A boolean value that indicates if there was a retriable error.</returns>        
        protected virtual bool Send(StorageTransmission transmission, ref TimeSpan nextSendInterval)
        {   
            try
            {
                if (transmission != null)
                {
                    transmission.SendAsync().ConfigureAwait(false).GetAwaiter().GetResult();
                    
                    // After a successful sending, try immeidiately to send another transmission. 
                    nextSendInterval = this.SendingInterval;
                }
            }
            catch (WebException e)
            {
                int? statusCode = GetStatusCode(e);
                nextSendInterval = this.CalculateNextInterval(statusCode, nextSendInterval, this.maxIntervalBetweenRetries);
                return IsRetryable(statusCode, e.Status);
            }
            catch (Exception e)
            {
                nextSendInterval = this.CalculateNextInterval(null, nextSendInterval, this.maxIntervalBetweenRetries);
                string msg = string.Format(CultureInfo.InvariantCulture, "Unknown exception during sending: {0}", e);
                CoreEventSource.Log.LogVerbose(msg);
            }

            return false;
        }
Пример #11
0
        internal override void Delete(StorageTransmission item)
        {
            try
            {
                if (this.StorageFolder == null)
                {
                    return;
                }

                // Initial storage size calculation. 
                this.EnsureSizeIsCalculatedAsync().ConfigureAwait(false).GetAwaiter().GetResult();

                IStorageFile file = this.StorageFolder.GetFileAsync(item.FileName).AsTask().ConfigureAwait(false).GetAwaiter().GetResult();
                long fileSize = this.GetSizeAsync(file).ConfigureAwait(false).GetAwaiter().GetResult();
                file.DeleteAsync(StorageDeleteOption.PermanentDelete).AsTask().ConfigureAwait(false).GetAwaiter().GetResult();
                this.deletedFilesQueue.Enqueue(item.FileName);

                // calculate size                
                Interlocked.Add(ref this.storageSize, -fileSize);
                Interlocked.Decrement(ref this.storageCountFiles);
            }
            catch (IOException e)
            {
                string msg = string.Format(CultureInfo.InvariantCulture, "Failed to delete a file. file: {0} Exception: {1}", item == null ? "null" : item.FullFilePath, e);
                CoreEventSource.Log.LogVerbose(msg);
            }
        }
 internal abstract void Delete(StorageTransmission transmission);