private void Begin <T>(Action <T> receiveHandler, SubscriptionClient subscriptionClient)
 {
     Debug.WriteLine("Calling BeginReceive");
     subscriptionClient.BeginReceive(
         TimeSpan.FromMinutes(5),
         (cb) => ProcessBrokeredMessage(receiveHandler, subscriptionClient, cb),
         null);
 }
        //private SubscriptionClient _subscriptionClient = null;
        //private string _entityPath = null;
        //public QueueCacheDependency(string key, string guid, TokenProvider tokenProvider, Uri uri, string queueName)
        //{
        //    _key = key;
        //    _guid = guid;
        //    //_tokenProvider = tokenProvider;
        //    //_uri = uri;
        //    //_entityPath = entityPath;
        //    var factory = MessagingFactory.Create(uri, tokenProvider);
        //    _receiver = factory.CreateMessageReceiver(queueName);
        //    WaitCallback callback = new WaitCallback(WaitForMessage);
        //    ThreadPool.QueueUserWorkItem(callback);
        //}
        public QueueCacheDependency(string key, SubscriptionClient subscriptionClient, string crc)
        {
            Trace.TraceInformation("QueueCacheDependency created: {0}", key);
            //_subscriptionClient = subscriptionClient;
            //_guid = guid;
            _key = key;
            _crc = crc;

            subscriptionClient.BeginReceive(
                TimeSpan.MaxValue,
                ReceiveDone,
                subscriptionClient
            );
        }
Esempio n. 3
0
 private void Begin <T>(Action <T> receiveHandler, SubscriptionClient subscriptionClient)
 {
     subscriptionClient.BeginReceive(
         TimeSpan.FromMinutes(5),
         (cb) =>
     {
         var brokeredMessage = subscriptionClient.EndReceive(cb);
         if (brokeredMessage != null)
         {
             var messageData = brokeredMessage.GetBody <T>();
             receiveHandler(messageData);
             Begin <T>(receiveHandler, subscriptionClient);
         }
     },
         null);
 }
        public void StartReceiving(ReceiverCallback callback, SubscriptionClient subscriptionClient, TimeSpan waitTime)
        {
            _subscriptionClient = subscriptionClient;

            //TODO: Find a way to do this now that subscription client is moved to the subscriber
            //if (_subscriptionClient != null) // we already have a subscription
            //    throw new InvalidOperationException("Already Receiving. Stop previous operation first");

            if (_subscriptionClient == null) // we already have a subscription
            {
                throw new InvalidOperationException("Subscription Client was not set.");
            }


            _receiverCallback = callback;


            // make initial async call
            _asyncResult = _subscriptionClient.BeginReceive(waitTime, ReceiveDone, _subscriptionClient);
        }
        public void ReceiveDone(IAsyncResult result)
        {
            if (result != null)
            {
                var tmpClient = result.AsyncState as SubscriptionClient;

                if (tmpClient != null)
                {
                    var brokeredMessage = tmpClient.EndReceive(result);

                    if (brokeredMessage != null)
                    {
                        //TODO: Handle both peeklock and receiveanddelete modes
                        brokeredMessage.Complete();

                        var tmpMessage = brokeredMessage.GetBody <NotificationMessage>();

                        #region translate the property back into a type
                        var tmpType = NotificationMessageType.All;
                        if (brokeredMessage.Properties[MessagePropertyType].ToString().Equals(NotificationMessageType.Important.ToString()))
                        {
                            tmpType = NotificationMessageType.Important;
                        }
                        else if (brokeredMessage.Properties[MessagePropertyType].ToString().Equals(NotificationMessageType.Unimportant.ToString()))
                        {
                            tmpType = NotificationMessageType.Unimportant;
                        }
                        #endregion

                        _receiverCallback(tmpMessage, tmpType);
                    }
                }
            }

            // do receive for next message
            if (_subscriptionClient != null)
            {
                _asyncResult = _subscriptionClient.BeginReceive(ReceiveDone, _subscriptionClient);
            }
        }
Esempio n. 6
0
 public IAsyncResult BeginReceive(TimeSpan serverWaitTime, AsyncCallback callback, object state)
 {
     return(client.BeginReceive(serverWaitTime, callback, state));
 }
Esempio n. 7
0
        private static void RunLoop()
        {
            MessagingFactory   factory = MessagingFactory.Create();
            SubscriptionClient auditSubscriptionClient = factory.CreateSubscriptionClient("IssueTrackingTopic", "AuditSubscription", ReceiveMode.ReceiveAndDelete);


            var retryPolicy = new RetryPolicy <ServiceBusTransientErrorDetectionStrategy>(RetryStrategy.DefaultClientRetryCount);

            var waitTimeout = TimeSpan.FromSeconds(10);

            // Declare an action acting as a callback whenever a message arrives on a queue.
            AsyncCallback completeReceive = null;

            // Declare an action acting as a callback whenever a non-transient exception occurs while receiving or processing messages.
            Action <Exception> recoverReceive = null;

            // Declare a cancellation token that is used to signal an exit from the receive loop.
            var cts = new CancellationTokenSource();

            // Declare an action implementing the main processing logic for received messages.
            Action <BrokeredMessage> processMessage = ((msg) =>
            {
                // Put your custom processing logic here. DO NOT swallow any exceptions.

                Console.WriteLine(msg.Properties["HorseId"]);
            });

            // Declare an action responsible for the core operations in the message receive loop.
            Action receiveMessage = (() =>
            {
                // Use a retry policy to execute the Receive action in an asynchronous and reliable fashion.
                retryPolicy.ExecuteAction
                (
                    (cb) =>
                {
                    // Start receiving a new message asynchronously.
                    auditSubscriptionClient.BeginReceive(waitTimeout, cb, null);
                },
                    (ar) =>
                {
                    // Make sure we are not told to stop receiving while we were waiting for a new message.
                    if (!cts.IsCancellationRequested)
                    {
                        // Complete the asynchronous operation. This may throw an exception that will be handled internally by retry policy.
                        BrokeredMessage msg = auditSubscriptionClient.EndReceive(ar);

                        // Check if we actually received any messages.
                        if (msg != null)
                        {
                            // Make sure we are not told to stop receiving while we were waiting for a new message.
                            if (!cts.IsCancellationRequested)
                            {
                                try
                                {
                                    // Process the received message.
                                    processMessage(msg);

                                    // With PeekLock mode, we should mark the processed message as completed.
                                    if (auditSubscriptionClient.Mode == ReceiveMode.PeekLock)
                                    {
                                        // Mark brokered message as completed at which point it's removed from the queue.
                                        msg.Complete();
                                    }
                                }
                                catch
                                {
                                    // With PeekLock mode, we should mark the failed message as abandoned.
                                    if (auditSubscriptionClient.Mode == ReceiveMode.PeekLock)
                                    {
                                        // Abandons a brokered message. This will cause Service Bus to unlock the message and make it available
                                        // to be received again, either by the same consumer or by another completing consumer.
                                        msg.Abandon();
                                    }

                                    // Re-throw the exception so that we can report it in the fault handler.
                                    throw;
                                }
                                finally
                                {
                                    // Ensure that any resources allocated by a BrokeredMessage instance are released.
                                    msg.Dispose();
                                }
                            }
                            else
                            {
                                // If we were told to stop processing, the current message needs to be unlocked and return back to the queue.
                                if (auditSubscriptionClient.Mode == ReceiveMode.PeekLock)
                                {
                                    msg.Abandon();
                                }
                            }
                        }
                    }

                    // Invoke a custom callback method to indicate that we have completed an iteration in the message receive loop.
                    completeReceive(ar);
                },
                    () =>
                {
                    Console.WriteLine("Success Handler");
                },
                    (ex) =>
                {
                    // Invoke a custom action to indicate that we have encountered an exception and
                    // need further decision as to whether to continue receiving messages.
                    recoverReceive(ex);
                });
            });

            // Initialize a custom action acting as a callback whenever a message arrives on a queue.
            completeReceive = ((ar) =>
            {
                if (!cts.IsCancellationRequested)
                {
                    // Continue receiving and processing new messages until we are told to stop.
                    receiveMessage();
                }
            });

            // Initialize a custom action acting as a callback whenever a non-transient exception occurs while receiving or processing messages.
            recoverReceive = ((ex) =>
            {
                // Just log an exception. Do not allow an unhandled exception to terminate the message receive loop abnormally.
                Console.WriteLine(ex.Message);

                if (!cts.IsCancellationRequested)
                {
                    // Continue receiving and processing new messages until we are told to stop regardless of any exceptions.
                    receiveMessage();
                }
            });

            // Start receiving messages asynchronously.
            receiveMessage();

            // Perform any other work. Message will keep arriving asynchronously while we are busy doing something else.

            // Stop the message receive loop gracefully.
            cts.Cancel();
        }
        /// <summary>
        ///     Receives the messages in an endless asynchronous loop.
        /// </summary>
        private void ReceiveMessages(CancellationToken cancellationToken)
        {
            // Declare an action to receive the next message in the queue or end if cancelled.
            Action receiveNext = null;

            // Declare an action acting as a callback whenever a non-transient exception occurs while receiving or processing messages.
            Action <Exception> recoverReceive = null;

            // Declare an action responsible for the core operations in the message receive loop.
            Action receiveMessage = () => {
                // Use a retry policy to execute the Receive action in an asynchronous and reliable fashion.
                receiveRetryPolicy.ExecuteAction
                (
                    cb => {
                    // Start receiving a new message asynchronously.
                    client.BeginReceive(ReceiveLongPollingTimeout, cb, null);
                },
                    ar => {
                    // Complete the asynchronous operation. This may throw an exception that will be handled internally by retry policy.
                    try {
                        return(client.EndReceive(ar));
                    } catch (TimeoutException) {
                        // TimeoutException is not just transient but completely expected in this case, so not relying on Topaz to retry
                        return(null);
                    }
                },
                    msg => {
                    // Process the message once it was successfully received
                    if (processInParallel)
                    {
                        // Continue receiving and processing new messages asynchronously
                        Task.Factory.StartNew(receiveNext);
                    }

                    // Check if we actually received any messages.
                    if (msg != null)
                    {
                        var roundtripStopwatch             = Stopwatch.StartNew();
                        long schedulingElapsedMilliseconds = 0;
                        long processingElapsedMilliseconds = 0;

                        Task.Factory.StartNew(() => {
                            var releaseAction = MessageReleaseAction.AbandonMessage;

                            try {
                                instrumentation.MessageReceived();

                                schedulingElapsedMilliseconds = roundtripStopwatch.ElapsedMilliseconds;

                                // Make sure the process was told to stop receiving while it was waiting for a new message.
                                if (!cancellationToken.IsCancellationRequested)
                                {
                                    try {
                                        try {
                                            // Process the received message.
                                            releaseAction = InvokeMessageHandler(msg);

                                            processingElapsedMilliseconds = roundtripStopwatch.ElapsedMilliseconds - schedulingElapsedMilliseconds;
                                            instrumentation.MessageProcessed(releaseAction.Kind == MessageReleaseActionKind.Complete, processingElapsedMilliseconds);
                                        } catch {
                                            processingElapsedMilliseconds = roundtripStopwatch.ElapsedMilliseconds - schedulingElapsedMilliseconds;
                                            instrumentation.MessageProcessed(false, processingElapsedMilliseconds);

                                            throw;
                                        }
                                    } finally {
                                        if (roundtripStopwatch.Elapsed > TimeSpan.FromSeconds(45))
                                        {
                                            dynamicThrottling.Penalize();
                                        }
                                    }
                                }
                            } finally {
                                // Ensure that any resources allocated by a BrokeredMessage instance are released.
                                ReleaseMessage(msg, releaseAction, processingElapsedMilliseconds, schedulingElapsedMilliseconds, roundtripStopwatch);
                            }

                            if (!processInParallel)
                            {
                                // Continue receiving and processing new messages until told to stop.
                                receiveNext.Invoke();
                            }
                        });
                    }
                    else
                    {
                        dynamicThrottling.NotifyWorkCompleted();
                        if (!processInParallel)
                        {
                            // Continue receiving and processing new messages until told to stop.
                            receiveNext.Invoke();
                        }
                    }
                },
                    ex => {
                    // Invoke a custom action to indicate that we have encountered an exception and
                    // need further decision as to whether to continue receiving messages.
                    recoverReceive.Invoke(ex);
                });
            };

            // Initialize an action to receive the next message in the queue or end if cancelled.
            receiveNext = () => {
                dynamicThrottling.WaitUntilAllowedParallelism(cancellationToken);
                if (!cancellationToken.IsCancellationRequested)
                {
                    dynamicThrottling.NotifyWorkStarted();
                    // Continue receiving and processing new messages until told to stop.
                    receiveMessage.Invoke();
                }
            };

            // Initialize a custom action acting as a callback whenever a non-transient exception occurs while receiving or processing messages.
            recoverReceive = ex => {
                // Just log an exception. Do not allow an unhandled exception to terminate the message receive loop abnormally.
                Trace.TraceError("An unrecoverable error occurred while trying to receive a new message from subscription {1}:\r\n{0}", ex, subscription);
                dynamicThrottling.NotifyWorkCompletedWithError();

                if (!cancellationToken.IsCancellationRequested)
                {
                    // Continue receiving and processing new messages until told to stop regardless of any exceptions.
                    TaskEx.Delay(10000).ContinueWith(t => receiveMessage.Invoke());
                }
            };

            // Start receiving messages asynchronously.
            receiveNext.Invoke();
        }