/// <summary>
 /// Builds transmission from the file object. In the case of success adds
 /// new transmission to the processing queue. No exceptions are thrown.
 /// </summary>
 /// <param name="file">Valid FileInfo object</param>
 /// <returns>StorageTransmission object in case of success or null in case of fail</returns>
 private StorageTransmission BuildTransmissionFromFile(FileInfo file)
 {
     try
     {
         string text = BuildNewFullFileNameWithSameDate(file.Name);
         File.Move(file.FullName, text);
         FileInfo            newfile = new FileInfo(text);
         StorageTransmission result  = LoadTransmissionFromFileAsync(newfile).ConfigureAwait(false).GetAwaiter().GetResult();
         if (LocalFileLoggerService.Default.Enabled)
         {
             LocalFileLoggerService.Default.Log(LocalLoggerSeverity.Info, "Telemetry", string.Format(CultureInfo.InvariantCulture, "Transmission ({0}): PersistenceStorageBase.BuildTransmissionFromFile renamed file from {1} to {2}", new object[3]
             {
                 result,
                 file.Name,
                 newfile.Name
             }));
         }
         result.Disposing = delegate
         {
             OnPeekedItemDisposed(newfile.Name);
         };
         peekedTransmissions.Add(newfile.Name, newfile.FullName);
         return(result);
     }
     catch (Exception ex)
     {
         string message = string.Format(CultureInfo.InvariantCulture, "Failed to load an item from the storage. file: {0} Exception: {1}", new object[2]
         {
             file,
             ex
         });
         CoreEventSource.Log.LogVerbose(message);
     }
     return(null);
 }
 private static async Task SaveTransmissionToFileAsync(Transmission transmission, string fileFullName)
 {
     try
     {
         using (Stream stream = File.OpenWrite(fileFullName))
         {
             if (LocalFileLoggerService.Default.Enabled)
             {
                 LocalFileLoggerService.Default.Log(LocalLoggerSeverity.Info, "Telemetry", string.Format(CultureInfo.InvariantCulture, "Transmission ({0}): PersistenceStorageBase.SaveTransmissionToFileAsync to file {1}", new object[2]
                 {
                     transmission,
                     Path.GetFileName(fileFullName)
                 }));
             }
             await StorageTransmission.SaveAsync(transmission, stream).ConfigureAwait(false);
         }
     }
     catch (UnauthorizedAccessException)
     {
         string message = $"Failed to save transmission to file. UnauthorizedAccessException. File full path: {fileFullName}";
         CoreEventSource.Log.LogVerbose(message);
         LocalFileLoggerService.Default.Log(LocalLoggerSeverity.Error, "Telemetry", string.Format(CultureInfo.InvariantCulture, "Transmission ({0}): PersistenceStorageBase.SaveTransmissionToFileAsync UnauthorizedAccessException", new object[1]
         {
             transmission
         }));
         throw;
     }
 }
        /// <summary>
        /// Peek all transmissions at once.
        /// </summary>
        /// <param name="token">Cancellation token</param>
        /// <returns>List of transmissions or empty array</returns>
        internal override IEnumerable <StorageTransmission> PeekAll(CancellationToken token)
        {
            List <StorageTransmission> list = new List <StorageTransmission>();

            lock (peekLockObj)
            {
                foreach (FileInfo filteredFile in GetFilteredFiles())
                {
                    token.ThrowIfCancellationRequested();
                    StorageTransmission storageTransmission = BuildTransmissionFromFile(filteredFile);
                    if (storageTransmission != null)
                    {
                        list.Add(storageTransmission);
                    }
                }
            }
            if (LocalFileLoggerService.Default.Enabled)
            {
                LocalFileLoggerService.Default.Log(LocalLoggerSeverity.Info, "Telemetry", string.Format(CultureInfo.InvariantCulture, "PersistenceStorageBase.PeekAll peeked {0} transmissions", new object[1]
                {
                    list.Count
                }));
            }
            return(list);
        }
Beispiel #4
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)
        {
            Tuple <bool, TimeSpan> result = SendAsync(transmission, default(CancellationToken), nextSendInterval).ConfigureAwait(false).GetAwaiter().GetResult();

            nextSendInterval = result.Item2;
            return(result.Item1);
        }
Beispiel #5
0
        /// <summary>
        /// Send transmissions in a loop.
        /// </summary>
        protected void SendLoop()
        {
            TimeSpan prevSendInterval = TimeSpan.Zero;
            TimeSpan nextSendInterval = sendingIntervalOnNoData;

            try
            {
                for (; !stopped; LogInterval(prevSendInterval, nextSendInterval), DelayHandler.WaitOne(nextSendInterval), prevSendInterval = nextSendInterval)
                {
                    using (StorageTransmission storageTransmission = storage.Peek())
                    {
                        if (!stopped)
                        {
                            if (storageTransmission != null)
                            {
                                if (LocalFileLoggerService.Default.Enabled)
                                {
                                    LocalFileLoggerService.Default.Log(LocalLoggerSeverity.Info, "Telemetry", string.Format(CultureInfo.InvariantCulture, "Transmission ({0}): PersistenceTransmitter.SendLoop about to send", new object[1]
                                    {
                                        storageTransmission
                                    }));
                                }
                                bool flag = Send(storageTransmission, ref nextSendInterval);
                                if (LocalFileLoggerService.Default.Enabled)
                                {
                                    LocalFileLoggerService.Default.Log(LocalLoggerSeverity.Info, "Telemetry", string.Format(CultureInfo.InvariantCulture, "Transmission ({0}): PersistenceTransmitter.SendLoop shouldRetry == {1}", new object[2]
                                    {
                                        storageTransmission,
                                        flag
                                    }));
                                }
                                if (!flag)
                                {
                                    storage.Delete(storageTransmission);
                                }
                            }
                            else
                            {
                                nextSendInterval = sendingIntervalOnNoData;
                            }
                            continue;
                        }
                    }
                    break;
                }
                stoppedHandler.Set();
            }
            catch (ObjectDisposedException)
            {
            }
        }
 internal override void Delete(StorageTransmission item)
 {
     if (StorageFolder != null)
     {
         filesToDelete[item.FileName] = item.FullFilePath;
         if (LocalFileLoggerService.Default.Enabled)
         {
             LocalFileLoggerService.Default.Log(LocalLoggerSeverity.Info, "Telemetry", string.Format(CultureInfo.InvariantCulture, "Transmission ({0}): PersistenceStorageBase.Delete try to delete transmission", new object[1]
             {
                 item
             }));
         }
         TryRemoveFilesToDelete();
     }
 }
 private static async Task <StorageTransmission> LoadTransmissionFromFileAsync(FileInfo file)
 {
     try
     {
         using (Stream stream = file.OpenRead())
         {
             return(await StorageTransmission.CreateFromStreamAsync(stream, file.FullName).ConfigureAwait(false));
         }
     }
     catch (Exception arg)
     {
         string message = $"Failed to load transmission from file. File full path: {file.FullName}, Exception: {arg}";
         CoreEventSource.Log.LogVerbose(message);
         throw;
     }
 }
 /// <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>
 /// <returns></returns>
 internal override StorageTransmission Peek()
 {
     lock (peekLockObj)
     {
         foreach (FileInfo filteredFile in GetFilteredFiles())
         {
             StorageTransmission storageTransmission = BuildTransmissionFromFile(filteredFile);
             if (storageTransmission != null)
             {
                 if (LocalFileLoggerService.Default.Enabled)
                 {
                     LocalFileLoggerService.Default.Log(LocalLoggerSeverity.Info, "Telemetry", string.Format(CultureInfo.InvariantCulture, "Transmission ({0}): PersistenceStorageBase.Peek peeked transmission", new object[1]
                     {
                         storageTransmission
                     }));
                 }
                 return(storageTransmission);
             }
         }
     }
     return(null);
 }
Beispiel #9
0
 internal abstract void Delete(StorageTransmission transmission);
Beispiel #10
0
        /// <summary>
        /// Sends a transmission asynchronously and handle errors.
        /// </summary>
        /// <param name="transmission">The transmission to send.</param>
        /// <param name="token">Cancellation token</param>
        /// <param name="sendInterval">Previous send interval duration</param>
        /// <returns></returns>
        private async Task <Tuple <bool, TimeSpan> > SendAsync(StorageTransmission transmission, CancellationToken token, TimeSpan sendInterval)
        {
            bool isRetryable = false;

            try
            {
                if (transmission != null)
                {
                    bool flag = true;
                    lock (hashLock)
                    {
                        flag = !setOfTransmissionHash.ContainsKey(transmission.ContentHash);
                        if (flag)
                        {
                            setOfTransmissionHash[transmission.ContentHash] = listOfTransmissionHash.AddLast(Tuple.Create(DateTime.UtcNow, transmission.ContentHash));
                            checkStaleHashCount++;
                            if (checkStaleHashCount >= 50)
                            {
                                CleanupStaleTransmissionHash();
                                checkStaleHashCount = 0;
                            }
                        }
                    }
                    if (flag)
                    {
                        await transmission.SendAsync(token).ConfigureAwait(false);
                    }
                    sendInterval = SendingInterval;
                }
            }
            catch (WebException ex)
            {
                int?statusCode = GetStatusCode(ex);
                sendInterval = CalculateNextInterval(statusCode, sendInterval, maxIntervalBetweenRetries);
                isRetryable  = IsRetryable(statusCode, ex.Status);
                LocalFileLoggerService.Default.Log(LocalLoggerSeverity.Error, "Telemetry", string.Format(CultureInfo.InvariantCulture, "Transmission ({0}): PersistenceTransmitter.SendAsync WebException ({1}), isRetryable == {2}", new object[3]
                {
                    transmission,
                    ex.Message,
                    isRetryable
                }));
            }
            catch (Exception ex2)
            {
                sendInterval = CalculateNextInterval(null, sendInterval, maxIntervalBetweenRetries);
                string message = string.Format(CultureInfo.InvariantCulture, "Unknown exception during sending: {0}", new object[1]
                {
                    ex2
                });
                CoreEventSource.Log.LogVerbose(message);
                LocalFileLoggerService.Default.Log(LocalLoggerSeverity.Error, "Telemetry", string.Format(CultureInfo.InvariantCulture, "Transmission ({0}): PersistenceTransmitter.SendAsync Exception ({1})", new object[2]
                {
                    transmission,
                    ex2.Message
                }));
                if (ex2 is OperationCanceledException)
                {
                    throw;
                }
            }
            if (isRetryable)
            {
                lock (hashLock)
                {
                    LinkedListNode <Tuple <DateTime, string> > value = null;
                    if (setOfTransmissionHash.TryGetValue(transmission.ContentHash, out value) && value != null)
                    {
                        listOfTransmissionHash.Remove(value);
                        setOfTransmissionHash.Remove(transmission.ContentHash);
                    }
                }
            }
            return(Tuple.Create(isRetryable, sendInterval));
        }