Пример #1
0
 /// <summary>
 /// Initializes a new instance of the <see cref="CommunicationEventArgs"/> class.
 /// </summary>
 /// <param name="config">The configuration.</param>
 /// <param name="payload">The payload.</param>
 /// <param name="response">The response.</param>
 public CommunicationEventArgs(RollbarConfig config, Payload payload, RollbarResponse response)
     : base(config, payload)
 {
     this.Response = response;
 }
Пример #2
0
        /// <summary>
        /// Processes the queues.
        /// </summary>
        /// <param name="tokenMetadata">The token metadata.</param>
        private void ProcessQueues(AccessTokenQueuesMetadata tokenMetadata)
        {
            // let's see if we can unregister any recently released queues:
            var releasedQueuesToRemove = tokenMetadata.PayloadQueues.Where(q => q.IsReleased && (q.GetPayloadCount() == 0)).ToArray();

            if (releasedQueuesToRemove != null && releasedQueuesToRemove.LongLength > 0)
            {
                foreach (var queue in releasedQueuesToRemove)
                {
                    this.Unregister(queue);
                }
            }

            // process the access token's queues:
            foreach (var queue in tokenMetadata.PayloadQueues)
            {
                if (DateTimeOffset.Now < queue.NextDequeueTime)
                {
                    // this means the queue overrides its reporting rate limit via its configuration settings
                    // let's observe its settings and skip processing:
                    continue;
                }

                if (tokenMetadata.IsTransmissionSuspended && DateTimeOffset.Now < tokenMetadata.NextTimeTokenUsage)
                {
                    // the token is suspended and the next usage time is not reached,
                    // let's flush the token queues (we are not allowed to transmit anyway)
                    // and quit processing this token's queues this time (until next processing iteration):
                    foreach (var tokenQueue in tokenMetadata.PayloadQueues)
                    {
                        foreach (var flushedBundle in tokenQueue.Flush())
                        {
                            this.OnRollbarEvent(
                                new PayloadDropEventArgs(
                                    queue.Logger,
                                    flushedBundle.GetPayload(),
                                    PayloadDropEventArgs.DropReason.TokenSuspension
                                    )
                                );
                        }
                    }
                    return;
                }

                PayloadBundle   payloadBundle = null;
                RollbarResponse response      = null;
                try
                {
                    payloadBundle = Process(queue, out response);
                }
                catch (AggregateException aggregateException)
                {
                    if (aggregateException.InnerExceptions.Any(e => e is HttpRequestException))
                    {
                        this.Persist(queue);
                        continue;
                    }
                    else
                    {
                        var bundle = queue.Dequeue();
                        this.OnRollbarEvent(
                            new PayloadDropEventArgs(queue.Logger, bundle.GetPayload(), PayloadDropEventArgs.DropReason.InvalidPayload)
                            );
                        queue.Dequeue();
                        throw;
                    }
                }
                catch (System.Exception ex)
                {
                    Debug.WriteLine($"EXCEPTION: {ex}");
                    this.Persist(queue);
                    continue;
                }

                if (payloadBundle != null && response == null)
                {
                    var bundle = queue.Dequeue();
                    this.OnRollbarEvent(
                        new PayloadDropEventArgs(queue.Logger, bundle.GetPayload(), PayloadDropEventArgs.DropReason.AllTransmissionRetriesFailed)
                        );
                }

                if (payloadBundle == null || response == null)
                {
                    continue;
                }

                tokenMetadata.UpdateNextTimeTokenUsage(response.RollbarRateLimit);

                switch (response.Error)
                {
                case (int)RollbarApiErrorEventArgs.RollbarError.None:
                    payloadBundle.Signal?.Release();
                    queue.Dequeue();
                    break;

                case (int)RollbarApiErrorEventArgs.RollbarError.TooManyRequests:
                    ObeyPayloadTimeout(payloadBundle, queue);
                    this.OnRollbarEvent(
                        new RollbarApiErrorEventArgs(queue.Logger, payloadBundle.GetPayload(), response)
                        );
                    return;

                default:
                    ObeyPayloadTimeout(payloadBundle, queue);
                    this.OnRollbarEvent(
                        new RollbarApiErrorEventArgs(queue.Logger, payloadBundle.GetPayload(), response)
                        );
                    break;
                }
            }
        }
Пример #3
0
 /// <summary>
 /// Initializes a new instance of the <see cref="CommunicationEventArgs"/> class.
 /// </summary>
 /// <param name="logger">The logger.</param>
 /// <param name="payload">The payload.</param>
 /// <param name="response">The response.</param>
 internal CommunicationEventArgs(RollbarLogger logger, Payload payload, RollbarResponse response)
     : base(logger, payload)
 {
     this.Response = response;
 }
        private PayloadBundle Process(PayloadQueue queue, out RollbarResponse response)
        {
            response = null;

            PayloadBundle payloadBundle = queue.Peek();

            while (payloadBundle != null && (payloadBundle.Ignorable || payloadBundle.GetPayload() == null))
            {
                queue.Dequeue();              //throw away the useless one...
                payloadBundle = queue.Peek(); //try next...
            }
            if (payloadBundle == null)
            {
                return(null); //no bundles to process...
            }

            Payload payload = payloadBundle.GetPayload();

            if (payload == null)
            {
                return(null);
            }

            int retries = this._totalRetries;

            while (retries > 0)
            {
                try
                {
                    response = queue.Client.PostAsJson(payloadBundle);
                }
                catch (WebException ex)
                {
                    retries--;
                    this.OnRollbarEvent(
                        new CommunicationErrorEventArgs(queue.Logger, payload, ex, retries)
                        );
                    continue;
                }
                catch (ArgumentNullException ex)
                {
                    retries = 0;
                    this.OnRollbarEvent(
                        new CommunicationErrorEventArgs(queue.Logger, payload, ex, retries)
                        );
                    continue;
                }
                catch (System.Exception ex)
                {
                    retries = 0;
                    this.OnRollbarEvent(
                        new CommunicationErrorEventArgs(queue.Logger, payload, ex, retries)
                        );
                    continue;
                }
                retries = 0;
            }

            if (response != null)
            {
                this.OnRollbarEvent(
                    new CommunicationEventArgs(queue.Logger, payload, response)
                    );
            }

            return(payloadBundle);
        }
Пример #5
0
        /// <summary>
        /// Processes the specified queue.
        /// </summary>
        /// <param name="queue">The queue.</param>
        /// <param name="response">The response.</param>
        /// <returns>PayloadBundle.</returns>
        private PayloadBundle Process(PayloadQueue queue, out RollbarResponse response)
        {
            response = null;

            PayloadBundle payloadBundle;
            Payload       payload = null;

            bool ignorableBundle = false;

            do
            {
                payloadBundle = queue.Peek();
                if (payloadBundle == null)
                {
                    return(null); // the queue is already empty, nothing to process...
                }

                try
                {
                    ignorableBundle = (payloadBundle.Ignorable || payloadBundle.GetPayload() == null);
                }
                catch (System.Exception ex)
                {
                    RollbarErrorUtility.Report(
                        null,
                        payloadBundle,
                        InternalRollbarError.DequeuingError,
                        "While attempting to dequeue a payload bundle...",
                        ex,
                        payloadBundle
                        );
                    ignorableBundle = true; // since something is not kosher about this bundle/payload, it is wise to ignore one...
                }

                if (ignorableBundle)
                {
                    queue.Dequeue(); //throw away the ignorable...
                    this.OnRollbarEvent(
                        new PayloadDropEventArgs(queue.Logger, null, PayloadDropEventArgs.DropReason.IgnorablePayload)
                        );
                }
                else
                {
                    payload = payloadBundle.GetPayload();
                }
            }while (ignorableBundle);

            if (payloadBundle == null || payload == null) // one more sanity check before proceeding further...
            {
                return(null);
            }

            if (queue.Logger?.Config != null && !queue.Logger.Config.Transmit)
            {
                response = new RollbarResponse();
                this.OnRollbarEvent(
                    new TransmissionOmittedEventArgs(queue.Logger, payload)
                    );
                return(payloadBundle);
            }

            int retries = this._totalRetries;

            while (retries > 0)
            {
                try
                {
                    response = queue.Client.PostAsJson(payloadBundle);
                }
                catch (WebException ex)
                {
                    retries--;
                    this.OnRollbarEvent(
                        new CommunicationErrorEventArgs(queue.Logger, payload, ex, retries)
                        );
                    payloadBundle.Register(ex);
                    Thread.Sleep(this._sleepInterval); // wait a bit before we retry it...
                    continue;
                }
                catch (ArgumentNullException ex)
                {
                    retries = 0;
                    this.OnRollbarEvent(
                        new CommunicationErrorEventArgs(queue.Logger, payload, ex, retries)
                        );
                    payloadBundle.Register(ex);
                    continue;
                }
                catch (System.Exception ex)
                {
                    retries = 0;
                    this.OnRollbarEvent(
                        new CommunicationErrorEventArgs(queue.Logger, payload, ex, retries)
                        );
                    payloadBundle.Register(ex);
                    continue;
                }
                retries = 0;
            }

            if (response != null)
            {
                this.OnRollbarEvent(
                    new CommunicationEventArgs(queue.Logger, payload, response)
                    );
            }
            else
            {
                queue.Dequeue(); //we tried our best...
                payloadBundle.Register(new RollbarException(InternalRollbarError.DequeuingError, "Payload dropped!"));
            }

            return(payloadBundle);
        }