/// <summary>
        /// Enqueue a log asynchronously.
        /// </summary>
        /// <param name="log">log to enqueue.</param>
        /// <returns>The async Task for this operation.</returns>
        public async Task EnqueueAsync(Log log)
        {
            try
            {
                State state;
                bool  discardLogs;
                using (await _mutex.GetLockAsync().ConfigureAwait(false))
                {
                    state       = _mutex.State;
                    discardLogs = _discardLogs;
                }
                if (discardLogs)
                {
                    AppCenterLog.Warn(AppCenterLog.LogTag, "Channel is disabled; logs are discarded");
                    AppCenterLog.Debug(AppCenterLog.LogTag, $"Invoke SendingLog event for channel '{Name}'");
                    SendingLog?.Invoke(this, new SendingLogEventArgs(log));
                    AppCenterLog.Debug(AppCenterLog.LogTag, $"Invoke FailedToSendLog event for channel '{Name}'");
                    FailedToSendLog?.Invoke(this, new FailedToSendLogEventArgs(log, new CancellationException()));
                    return;
                }
                AppCenterLog.Debug(AppCenterLog.LogTag, $"Invoke EnqueuingLog event for channel '{Name}'");
                EnqueuingLog?.Invoke(this, new EnqueuingLogEventArgs(log));
                await PrepareLogAsync(log, state).ConfigureAwait(false);

                AppCenterLog.Debug(AppCenterLog.LogTag, $"Invoke FilteringLog event for channel '{Name}'");
                var filteringLogEventArgs = new FilteringLogEventArgs(log);
                FilteringLog?.Invoke(this, filteringLogEventArgs);
                if (filteringLogEventArgs.FilterRequested)
                {
                    AppCenterLog.Warn(AppCenterLog.LogTag, $"Filtering out a log of type '{log.GetType()}' at the request of an event handler.");
                }
                else
                {
                    await PersistLogAsync(log, state).ConfigureAwait(false);
                }
            }
            catch (StatefulMutexException)
            {
                AppCenterLog.Warn(AppCenterLog.LogTag, "The Enqueue operation has been canceled");
            }
        }
Exemple #2
0
        private async Task SignalDeletingLogs(State stateSnapshot)
        {
            var logs = new List <Log>();

            _mutex.Unlock();
            await _storage.GetLogsAsync(Name, ClearBatchSize, logs).ConfigureAwait(false);

            await _mutex.LockAsync(stateSnapshot).ConfigureAwait(false);

            foreach (var log in logs)
            {
                _mutex.Unlock();
                SendingLog?.Invoke(this, new SendingLogEventArgs(log));
                FailedToSendLog?.Invoke(this, new FailedToSendLogEventArgs(log, new CancellationException()));
                await _mutex.LockAsync(stateSnapshot).ConfigureAwait(false);
            }
            if (logs.Count >= ClearBatchSize)
            {
                await SignalDeletingLogs(stateSnapshot).ConfigureAwait(false);
            }
        }
Exemple #3
0
        private Task SignalDeletingLogs()
        {
            var logs = new List <Log>();

            return(_storage.GetLogsAsync(Name, ClearBatchSize, logs)
                   .ContinueWith(completedTask =>
            {
                if (completedTask.IsFaulted)
                {
                    AppCenterLog.Warn(AppCenterLog.LogTag,
                                      "Failed to invoke events for logs being deleted.");
                    return;
                }
                foreach (var log in logs)
                {
                    SendingLog?.Invoke(this, new SendingLogEventArgs(log));
                    FailedToSendLog?.Invoke(this, new FailedToSendLogEventArgs(log, new CancellationException()));
                }
                if (logs.Count >= ClearBatchSize)
                {
                    SignalDeletingLogs();
                }
            }));
        }
 private void AnyChannelSendingLog(object sender, SendingLogEventArgs e)
 {
     SendingLog?.Invoke(sender, e);
 }
Exemple #5
0
        private void TriggerIngestion(IList <Log> logs, State stateSnapshot, string batchId)
        {
            // Before sending logs, trigger the sending event for this channel
            if (SendingLog != null)
            {
                foreach (var eventArgs in logs.Select(log => new SendingLogEventArgs(log)))
                {
                    _mutex.Unlock();
                    SendingLog?.Invoke(this, eventArgs);
                    _mutex.Lock(stateSnapshot);
                }
            }
            // If the optional Install ID has no value, default to using empty GUID
            var installId   = MobileCenter.InstallId.HasValue ? MobileCenter.InstallId.Value : Guid.Empty;
            var serviceCall = _ingestion.PrepareServiceCall(_appSecret, installId, logs);

            serviceCall.ServiceCallFailedCallback = exception =>
            {
                serviceCall.Dispose();
                HandleSendingFailure(batchId, exception);
            };

            serviceCall.ServiceCallSucceededCallback = async() =>
            {
                serviceCall.Dispose();
                if (!_stateKeeper.IsCurrent(stateSnapshot))
                {
                    return;
                }
                try
                {
                    await _storage.DeleteLogsAsync(Name, batchId).ConfigureAwait(false);
                }
                catch (StorageException e)
                {
                    MobileCenterLog.Warn(MobileCenterLog.LogTag, $"Could not delete logs for batch {batchId}", e);
                }
                try
                {
                    await _mutex.LockAsync(stateSnapshot).ConfigureAwait(false);

                    var removedLogs = _sendingBatches[batchId];
                    _sendingBatches.Remove(batchId);
                    if (SentLog != null)
                    {
                        foreach (var log in removedLogs)
                        {
                            _mutex.Unlock();
                            SentLog?.Invoke(this, new SentLogEventArgs(log));
                            _mutex.Lock(stateSnapshot);
                        }
                    }
                    CheckPendingLogs();
                }
                catch (StatefulMutexException)
                {
                }
                finally
                {
                    _mutex.Unlock();
                }
            };
            serviceCall.Execute();
        }