Esempio n. 1
0
 public IEnumerable <QueueDescriptor> GetPrivateQueues(string machine, QueueTransaction xactionality)
 {
     // Get a list of queues with the specified category.
     return(MessageQueue.GetPrivateQueuesByMachine(machine).Where(x => ByTransactionality(xactionality, x.Transactional)).Select(x => new QueueDescriptor {
         Path = x.Path, Transactional = x.Transactional, Limit = x.MaximumQueueSize
     }));
 }
        private async Task WaitForAcknowledgements(List <Tracking> sent)
        {
            if (sent.Count == 0)
            {
                return;
            }

            Console.Error.WriteLine($"DEBUG Waiting for {sent.Count} acknowledgements");

            foreach (var item in sent)
            {
                try
                {
                    await Sender.WaitForDeliveryAsync(item);

                    _batchQueue.Lookup(Properties.LookupId, item.LookupId, timeout: TimeSpan.Zero, transaction: QueueTransaction.Single);
                }
                catch (AcknowledgmentException ex)
                {
                    Console.Error.WriteLine("WARNING " + ex);
                    using (var txn = new QueueTransaction())
                    {
                        _batchQueue.MarkRejected(item.LookupId); // send a acknowledgement that the message has been rejected
                        Queues.MoveMessage(_batchQueue, _posionQueue, item.LookupId, txn);
                        txn.Commit();
                    }
                }
                catch (AggregateException ex)
                {
                    //TODO: handle sent error to multi-element format name
                    Console.Error.WriteLine($"WARNING multi-elements format names are not yet supported");
                    throw;
                }
            }
        }
Esempio n. 3
0
 public Task <Task> StartAsync()
 {
     _input = new QueueReader(_inputFormatName);
     if (Queues.IsTransactional(_input.FormatName) == QueueTransactional.Transactional)
     {
         _transaction = QueueTransaction.Single;
     }
     _running = RunAsync();
     return(Task.FromResult(_running));
 }
        public async Task <Message> PeekAsync(Properties properties, QueueTransaction transaction)
        {
            Contract.Requires(transaction != null);
            var ht = _high.PeekAsync(properties);

            if (ht.IsCompleted || ht.IsFaulted) // always give high priority queue the first chance, it may complete synchronously
            {
                return(await ht);
            }
            var lt = _low.PeekAsync(properties);

            Message[] results = await Task.WhenAll(ht, lt);

            return(results.FirstOrDefault(m => m != null));
        }
 private void RouteBatch(List <Tracking> sent)
 {
     try
     {
         using (var txn = new QueueTransaction())
         {
             RouteBatchCore(sent, txn);
             txn.Commit();
         }
     }
     catch (RouteException ex)
     {
         Console.Error.WriteLine($"WARN {ex.Message} {{Destination={ex.Destination}}}");
         BadMessageHandler(_input, ex.LookupId, QueueTransaction.Single);
         sent.Clear();
     }
 }
Esempio n. 6
0
        private void MoveToUnroutableSubQueue(long lookupId, QueueTransaction transaction)
        {
            try
            {
                if (_posionSubQueue == null)
                {
                    _posionSubQueue = new SubQueue(_input.FormatName + ";" + UnroutableSubQueue);
                }

                Queues.MoveMessage(_input, _posionSubQueue, lookupId, transaction);
                return;
            }
            catch (QueueException e)
            {
                Console.Error.WriteLine($"WARN Failed to move message {{lookupId={lookupId}}} {{subqueue={UnroutableSubQueue}}} {{error={e.Message}}}");
            }
        }
Esempio n. 7
0
 private void MoveToPoisonSubqueue(QueueReader fromQueue, long lookupId, QueueTransaction transaction)
 {
     Contract.Requires(fromQueue != null);
     if (_posionQueue == null)
     {
         _posionQueue = new SubQueue(InputQueueFormatName + ";" + UnroutableSubQueue);
     }
     try
     {
         Queues.MoveMessage(fromQueue, _posionQueue, lookupId, transaction);
         return;
     }
     catch (QueueException e)
     {
         Console.Error.WriteLine($"WARN Failed to move message {{lookupId={lookupId}}} {{subqueue={UnroutableSubQueue}}} {{error={e.Message}}}");
     }
 }
Esempio n. 8
0
        /// <summary>
        /// Posts a <paramref name="message"/> to the <paramref name="queue"/> with acknowledgement requested to be sent to <see cref="AdminQueueFormatName"/>.
        /// </summary>
        public Tracking RequestDelivery(Message message, QueueWriter queue, QueueTransaction transaction = null)
        {
            Contract.Requires(message != null);
            Contract.Requires(queue != null);
            Contract.Assert(_run != null);
            Contract.Assert(_adminQueue != null);

            message.AcknowledgmentTypes |= AcknowledgmentTypes.FullReachQueue;
            message.TimeToReachQueue     = ReachQueueTimeout;
            message.AdministrationQueue  = _adminQueue.FormatName;
            queue.Write(message, transaction);

            // acknowledgements for multicast messages get an empty DestinationQueue, so we need to remove it here
            var formatName = queue.FormatName.StartsWith("multicast=", StringComparison.OrdinalIgnoreCase)? "" : queue.FormatName;

            return(new Tracking(formatName, message.Id, message.LookupId));
        }
        protected void RouteBatchCore(List <Tracking> sent, QueueTransaction txn)
        {
            long         lookupId = 0;
            LookupAction action   = LookupAction.PeekFirst;

            for (int i = 0; i < MaxBatchSize; i++)
            {
                // peek for the next message
                var msg = _input.Lookup(Properties.All, lookupId, action, TimeSpan.Zero);
                if (msg == null)
                {
                    break;
                }
                action   = LookupAction.PeekNext;
                lookupId = msg.LookupId;

                // move to the batch subqueue so we know what we sent
                Queues.MoveMessage(_input, _batchQueue, msg.LookupId, txn);

                // route to message to the destination
                var dest = GetRoute(msg);
                sent.Add(Sender.RequestDelivery(msg, dest, txn));
            }
        }
Esempio n. 10
0
 private static bool ByTransactionality(QueueTransaction xactionality, bool queueTransactional)
 {
     return xactionality == QueueTransaction.Transactional ? queueTransactional : (xactionality == QueueTransaction.NonTransactional ? !queueTransactional : true);
 }
Esempio n. 11
0
 public IEnumerable<QueueDescriptor> GetPublicQueuesByMachine(string machine, QueueTransaction xactionality)
 {
     return MessageQueue.GetPublicQueuesByMachine(machine).Where(x=> ByTransactionality(xactionality, x.Transactional) ).Select(x => new QueueDescriptor { Path = x.Path, Transactional = x.Transactional, Limit = x.MaximumQueueSize });
 }
Esempio n. 12
0
 public IEnumerable<QueueDescriptor> GetPrivateQueues(string machine, QueueTransaction xactionality)
 {
     // Get a list of queues with the specified category.
     return MessageQueue.GetPrivateQueuesByMachine(machine).Where(x => ByTransactionality(xactionality, x.Transactional)).Select(x => new QueueDescriptor { Path = x.Path, Transactional = x.Transactional, Limit = x.MaximumQueueSize });
 }
Esempio n. 13
0
        /// <summary>
        /// Sends a <paramref name="message"/> to the <paramref name="queue"/> and waits for it to be delivered.
        /// Waits for responses from all queues when the <paramref name="queue"/> is a multi-element format name.
        /// Note that the transaction MUST commit before the acknowledgements are received.
        /// </summary>
        /// <returns>Task that completes when the message has been delivered</returns>
        /// <exception cref="TimeoutException">Thrown if the message does not reach the queue before the <see cref="ReachQueueTimeout"/> has been reached</exception>
        /// <exception cref="AcknowledgmentException">Thrown if something bad happens, e.g. message could not be sent, access denied, the queue was purged, etc</exception>
        public static Task DeliverAsync(this QueueWriter queue, Message message, Postman postman, QueueTransaction transaction = null)
        {
            Contract.Requires(queue != null);
            Contract.Requires(message != null);
            Contract.Requires(postman != null);
            Contract.Requires(transaction == null || transaction == QueueTransaction.None || transaction == QueueTransaction.Single);

            var t = postman.RequestDelivery(message, queue, transaction);

            return(postman.WaitForDeliveryAsync(t));
        }
Esempio n. 14
0
 public static Tracking RequestDelivery(this QueueWriter queue, Message message, Postman postman, QueueTransaction txn = null) => postman.RequestDelivery(message, queue, txn);
Esempio n. 15
0
 /// <summary>Tries to receive a message from the queue</summary>
 /// <remarks>Within a transaction you cannot receive a message that you moved to a subqueue</remarks>
 /// <param name="properties">The properties to read</param>
 /// <param name="timeout">The time allowed, defaults to infinite.  Use <see cref="F:System.TimeSpan.Zero" /> to return without waiting</param>
 /// <param name="transaction">can be NULL for no transaction, a <see cref="T:BusterWood.Msmq.QueueTransaction" />, <see cref="F:BusterWood.Msmq.QueueTransaction.Single" />, or <see cref="F:BusterWood.Msmq.QueueTransaction.Dtc" />.</param>
 /// <returns>The message, or NULL if the receive times out</returns>
 public Message Read(Properties properties = Properties.All, TimeSpan?timeout = default(TimeSpan?), QueueTransaction transaction = null)
 {
     for (;;)
     {
         var msg          = _queueReader.Read(properties | Properties.Label, timeout);
         var hash         = ComputeHash(msg);
         var existingHash = _hashByLabel[msg.Label];
         if (hash == existingHash)
         {
             Console.Error.WriteLine($"Dropping duplicate message for label '{msg.Label}'");
             continue;
         }
         _hashByLabel[msg.Label] = hash;
         return(msg);
     }
 }
Esempio n. 16
0
 /// <summary>Tries to read the current message from the queue without removing the message from the queue.</summary>
 /// <remarks>Within a transaction you cannot peek a message that you moved to a subqueue</remarks>
 /// <param name="properties">The properties to read</param>
 /// <param name="timeout">The time allowed, defaults to infinite.  Use <see cref="F:System.TimeSpan.Zero" /> to return without waiting</param>
 /// <param name="transaction">can be NULL for no transaction, a <see cref="T:BusterWood.Msmq.QueueTransaction" />, <see cref="F:BusterWood.Msmq.QueueTransaction.Single" />, or <see cref="F:BusterWood.Msmq.QueueTransaction.Dtc" />.</param>
 /// <returns>The message, or NULL if the receive times out</returns>
 public Message Peek(Properties properties = Properties.All, TimeSpan?timeout = default(TimeSpan?), QueueTransaction transaction = null)
 {
     return(_queueReader.Peek(properties, timeout, transaction));
 }
Esempio n. 17
0
 private static bool ByTransactionality(QueueTransaction xactionality, bool queueTransactional)
 {
     return(xactionality == QueueTransaction.Transactional ? queueTransactional : (xactionality == QueueTransaction.NonTransactional ? !queueTransactional : true));
 }
Esempio n. 18
0
 public IEnumerable <QueueDescriptor> GetPublicQueuesByMachine(string machine, QueueTransaction xactionality)
 {
     return(MessageQueue.GetPublicQueuesByMachine(machine).Where(x => ByTransactionality(xactionality, x.Transactional)).Select(x => new QueueDescriptor {
         Path = x.Path, Transactional = x.Transactional, Limit = x.MaximumQueueSize
     }));
 }
 public Message Lookup(Properties properties, long lookupId, QueueTransaction transaction, LookupAction action = LookupAction.ReceiveCurrent, TimeSpan?timeout = null)
 {
     Contract.Requires(transaction != null);
     return(_high.Lookup(properties, lookupId, action, timeout, transaction) ?? _low.Lookup(properties, lookupId, action, timeout, transaction));
 }
 /// <summary>Read without waiting, returns null if no message is available in high or low priority subqueues</summary>
 public Message Read(Properties properties, QueueTransaction transaction)
 {
     Contract.Requires(transaction != null);
     return(_high.Read(properties, TimeSpan.Zero, transaction) ?? _low.Read(properties, TimeSpan.Zero, transaction));
 }