/// <summary> /// Log next interval. Only log the interval when it changes by more then a minute. So if interval grow by 1 minute or /// decreased by 1 minute it will be logged. /// Logging every interval will just make the log noisy. /// </summary> private static void LogInterval(TimeSpan prevSendInterval, TimeSpan nextSendInterval) { if (Math.Abs(nextSendInterval.TotalSeconds - prevSendInterval.TotalSeconds) > 60) { PersistenceChannelDebugLog.WriteLine("next sending interval: " + nextSendInterval); } }
internal override async Task EnqueueAsync(Transmission transmission) { try { if (transmission == null || StorageFolder == null) { return; } // Initial storage size calculation. CalculateSize(); if ((ulong)_storageSize >= CapacityInBytes || _storageCountFiles >= MaxFiles) { // if max storage capacity has reached, drop the transmission (but log every 100 lost transmissions). if (_transmissionsDropped++ % 100 == 0) { PersistenceChannelDebugLog.WriteLine("Total transmissions dropped: " + _transmissionsDropped); } return; } // Writes content to a temporary file and only then rename to avoid the Peek from reading the file before it is being written. // Creates the temp file name string tempFileName = Guid.NewGuid().ToString("N"); // Now that the file got created we can increase the files count Interlocked.Increment(ref _storageCountFiles); // Saves transmission to the temp file await SaveTransmissionToFileAsync(transmission, tempFileName).ConfigureAwait(false); // Now that the file is written increase storage size. long temporaryFileSize = GetSize(tempFileName); Interlocked.Add(ref _storageSize, temporaryFileSize); // Creates a new file name string now = DateTime.UtcNow.ToString("yyyyMMddHHmmss"); string newFileName = string.Format(CultureInfo.InvariantCulture, "{0}_{1}.trn", now, tempFileName); // Renames the file File.Move(Path.Combine(StorageFolder, tempFileName), Path.Combine(StorageFolder, newFileName)); } catch (Exception e) { PersistenceChannelDebugLog.WriteException(e, "EnqueueAsync"); } }
private async Task SaveTransmissionToFileAsync(Transmission transmission, string file) { try { using (Stream stream = File.OpenWrite(Path.Combine(StorageFolder, file))) { 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}", StorageFolder, file); PersistenceChannelDebugLog.WriteLine(message); throw; } }
private async Task <StorageTransmission> LoadTransmissionFromFileAsync(string file) { try { using (Stream stream = File.OpenRead(Path.Combine(StorageFolder, file))) { StorageTransmission storageTransmissionItem = await StorageTransmission.CreateFromStreamAsync(stream, file).ConfigureAwait(false); return(storageTransmissionItem); } } catch (Exception e) { string message = string.Format( "Failed to load transmission from file. File path: {0}, FileName: {1}, Exception: {2}", "storageFolderName", file, e); PersistenceChannelDebugLog.WriteLine(message); throw; } }
/// <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>True, if there was sent error and we need to retry sending, otherwise false.</returns> protected virtual bool Send(StorageTransmission transmission, ref TimeSpan nextSendInterval) { try { if (transmission != null) { bool isConnected = NetworkInterface.GetIsNetworkAvailable(); // there is no internet connection available, return than. if (!isConnected) { PersistenceChannelDebugLog.WriteLine( "Cannot send data to the server. Internet connection is not available"); return(true); } transmission.SendAsync().ConfigureAwait(false).GetAwaiter().GetResult(); // After a successful sending, try immediately to send another transmission. nextSendInterval = SendingInterval; } } catch (WebException e) { int?statusCode = GetStatusCode(e); nextSendInterval = CalculateNextInterval(statusCode, nextSendInterval, _maxIntervalBetweenRetries); return(IsRetryable(statusCode, e.Status)); } catch (Exception e) { nextSendInterval = CalculateNextInterval(null, nextSendInterval, _maxIntervalBetweenRetries); PersistenceChannelDebugLog.WriteException(e, "Unknown exception during sending"); } return(false); }