Beispiel #1
1
 /// <summary>
 /// Constructor</summary>
 public TransactionPropertyNode(ITransactionContext context)
 {
     if(context != null)
         m_contextRef = new WeakReference(context);
     else
         IsReadOnly = true;
 }
Beispiel #2
0
 public TransactedTask(ITask inner, ITransactionContext transactionContext)
 {
     if (inner == null) throw new ArgumentNullException("inner");
     if (transactionContext == null) throw new ArgumentNullException("transactionContext");
     _inner = inner;
     _transactionContext = transactionContext;
 }
        public DbLogger(ITransactionContext context)
        {
            this.context = context;

            Error = new DbLoggerError(this);
            Info = new DbLoggerInfo(this);
        }
        /// <summary>
        /// Handles the poisonous message by forwarding it to the configured error queue
        /// </summary>
        public async Task HandlePoisonMessage(TransportMessage transportMessage, ITransactionContext transactionContext, string errorDescription)
        {
            var headers = transportMessage.Headers;

            string messageId ;

            if (!headers.TryGetValue(Headers.MessageId, out messageId))
            {
                messageId = "<unknown>";
            }

            headers[Headers.ErrorDetails] = errorDescription;
            headers[Headers.SourceQueue] = _transport.Address;

            var errorQueueAddress = _simpleRetryStrategySettings.ErrorQueueAddress;

            try
            {
                _log.Error("Moving message with ID {0} to error queue '{1}' - reason: {2}", messageId, errorQueueAddress, errorDescription);

                await _transport.Send(errorQueueAddress, transportMessage, transactionContext);
            }
            catch (Exception exception)
            {
                _log.Error(exception, "Could not move message with ID {0} to error queue '{1}' - will pause {2} to avoid thrashing",
                    messageId, errorQueueAddress, MoveToErrorQueueFailedPause);

                // if we can't move to error queue, we need to avoid thrashing over and over
                await Task.Delay(MoveToErrorQueueFailedPause);
            }
        }
 public DeleteOrderCommand(long orderID, IOrderDataProxy orderDataProxy, OrderItemService orderItemService, ITransactionContext transactionContext)
 {
     _orderID = orderID;
     _orderDataProxy = orderDataProxy;
     _orderItemService = orderItemService;
     _transactionContext = transactionContext;
 }
        /// <summary>
        /// Sends a copy of the specified <see cref="TransportMessageToSend"/> using the underlying implementation of <see cref="ISendMessages"/>
        /// with an encrypted message body and additional headers
        /// </summary>
        public void Send(string destinationQueueName, TransportMessageToSend message, ITransactionContext context)
        {
            var clone = new TransportMessageToSend
                            {
                                Headers = message.Headers.Clone(),
                                Label = message.Label,
                                Body = message.Body,
                            };

            if (compressionHelper != null)
            {
                var compresssionResult = compressionHelper.Compress(clone.Body);
                if (compresssionResult.Item1)
                {
                    clone.Headers[Headers.Compression] = Headers.CompressionTypes.GZip;
                }
                clone.Body = compresssionResult.Item2;
            }

            if (encryptionHelper != null)
            {
                var iv = encryptionHelper.GenerateNewIv();
                clone.Body = encryptionHelper.Encrypt(clone.Body, iv);
                clone.Headers[Headers.Encrypted] = null;
                clone.Headers[Headers.EncryptionSalt] = iv;
            }

            innerSendMessages.Send(destinationQueueName, clone, context);
        }
Beispiel #7
0
        internal Transaction(ITransactionContext context, Database database, int commitId, IsolationLevel isolation, IEnumerable<TableSource> committedTables, IEnumerable<IIndexSet> indexSets)
        {
            CommitId = commitId;
            Database = database;
            Isolation = isolation;
            Context = context;

            context.RegisterInstance<ITransaction>(this);

            Registry = new TransactionRegistry(this);
            TableManager.AddVisibleTables(committedTables, indexSets);

            AddInternalTables();

            TableState = new OldNewTableState();

            IsClosed = false;

            Database.TransactionFactory.OpenTransactions.AddTransaction(this);

            this.CurrentSchema(database.Context.DefaultSchema());
            this.ReadOnly(database.Context.ReadOnly());
            this.AutoCommit(database.Context.AutoCommit());
            this.IgnoreIdentifiersCase(database.Context.IgnoreIdentifiersCase());
            this.ParameterStyle(QueryParameterStyle.Marker);
        }
        public ReceivedTransportMessage ReceiveMessage(ITransactionContext context)
        {
            var receivedTransportMessage = innerReceiveMessages.ReceiveMessage(context);

            if (receivedTransportMessage == null) return null;

            byte[] body;
            var headers = receivedTransportMessage.Headers.Clone();

            if (headers.ContainsKey(Headers.Encrypted))
            {
                var iv = receivedTransportMessage.GetHeader(Headers.EncryptionSalt);
                body = helper.Decrypt(receivedTransportMessage.Body, iv);

                headers.Remove(Headers.EncryptionSalt);
                headers.Remove(Headers.Encrypted);
            }
            else
            {
                body = receivedTransportMessage.Body;
            }

            return new ReceivedTransportMessage
                       {
                           Id = receivedTransportMessage.Id,
                           Headers = headers,
                           Label = receivedTransportMessage.Label,
                           Body = body,
                       };
        }
        public void HandleMessage(TransportMessage transportMessage, ITransactionContext transactionContext)
        {
            var message = transportMessage.GetMessageLabel();

            var options = new List<KeyOption>();

            if (DefaultOutputQueue != null)
            {
                options.Add(KeyOption.New('d',
                    () => { MoveMessage(transportMessage, transactionContext, DefaultOutputQueue); },
                    "Move to default queue '{0}'", DefaultOutputQueue));
            }

            if (transportMessage.Headers.ContainsKey(Headers.SourceQueue))
            {
                var sourceQueue = transportMessage.Headers[Headers.SourceQueue];

                options.Add(KeyOption.New('s',
                    () => { MoveMessage(transportMessage, transactionContext, sourceQueue); },
                    "Return to source queue '{0}'", sourceQueue));
            }

            options.Add(KeyOption.New('c', () =>
            {
                Console.Write("queue > ");
                var queueName = Console.ReadLine();
                MoveMessage(transportMessage, transactionContext, queueName);
            }, "Enter custom queue name to move message to"));

            Prompt(message, options);

            Text.PrintLine();
        }
        /// <summary>
        /// Sends the given <see cref="TransportMessage"/> to the queue with the specified globally addressable name
        /// </summary>
        public async Task Send(string destinationAddress, TransportMessage message, ITransactionContext context)
        {
            context.OnCommitted(async () =>
            {
                var headers = message.Headers.Clone();
                var queue = GetQueue(destinationAddress);
                var messageId = Guid.NewGuid().ToString();
                var popReceipt = Guid.NewGuid().ToString();
                var timeToBeReceivedOrNull = GetTimeToBeReceivedOrNull(headers);
                var queueVisibilityDelayOrNull = GetQueueVisibilityDelayOrNull(headers);
                var cloudQueueMessage = Serialize(messageId, popReceipt, headers, message.Body);

                try
                {
                    var options = new QueueRequestOptions {RetryPolicy = new ExponentialRetry()};
                    var operationContext = new OperationContext();

                    await queue.AddMessageAsync(cloudQueueMessage, timeToBeReceivedOrNull, queueVisibilityDelayOrNull, options, operationContext);
                }
                catch (Exception exception)
                {
                    throw new RebusApplicationException(exception, $"Could not send message with ID {cloudQueueMessage.Id} to '{destinationAddress}'");
                }
            });
        }
Beispiel #11
0
 /// <summary>
 /// Constructs the step context, initially stashing the given <see cref="TransportMessage"/> and <see cref="ITransactionContext"/> into its bag of objects
 /// </summary>
 public IncomingStepContext(TransportMessage message, ITransactionContext transactionContext)
 {
     Save(message);
     Save(transactionContext);
     
     transactionContext.Items[StepContextKey] = this;
 }
Beispiel #12
0
        public void Send(string destinationQueueName, TransportMessageToSend message, ITransactionContext context)
        {
            var outputQueue = cloudQueueClient.GetQueueReference(destinationQueueName);

            using (var memoryStream = new MemoryStream())
            {
                var formatter = new BinaryFormatter();
                var receivedTransportMessage = new ReceivedTransportMessage
                    {
                        Id = Guid.NewGuid().ToString(),
                        Headers = message.Headers,
                        Body = message.Body,
                        Label = message.Label,
                    };

                formatter.Serialize(memoryStream, receivedTransportMessage);
                memoryStream.Position = 0;

                var cloudQueueMessage = new CloudQueueMessage(memoryStream.ToArray());

                var timeToLive = GetTimeToLive(message);
                if (timeToLive.HasValue)
                {
                    outputQueue.AddMessage(cloudQueueMessage, timeToLive.Value);
                }
                else
                {
                    outputQueue.AddMessage(cloudQueueMessage);
                }
            }
        }
 public TransactedActionFilter(ITransactionContext transactionContext, EventDispatchHandler dispatchHandler, ILocalEventsManager domainEvents)
 {
     if (transactionContext == null) throw new ArgumentNullException("transactionContext");
     _transactionContext = transactionContext;
     _dispatchHandler = dispatchHandler;
     _domainEvents = domainEvents;
 }
Beispiel #14
0
        public async Task Send(string destinationAddress, TransportMessage message, ITransactionContext context)
        {
            await _innerTransport.Send(destinationAddress, message, context);

            _sentMessages.Add(message);

            MessageSent(message);
        }
Beispiel #15
0
 public OrderItemClientService(IOrderItemDataProxy dataProxy,
                               IProductDataProxy productDataProxy,
                               IInventoryItemDataProxy inventoryDataProxy,
                               ITransactionContext transactionContext) : base(dataProxy, productDataProxy, inventoryDataProxy, transactionContext)
 {
     _inventoryDataProxy = inventoryDataProxy;
     _transactionContext = transactionContext;
 }
Beispiel #16
0
        public async Task<TransportMessage> Receive(ITransactionContext context, CancellationToken cancellationToken)
        {
            if (_receiveLatencyMs.HasValue)
            {
                await Task.Delay(_receiveLatencyMs.Value, cancellationToken);
            }

            return await _innerTransport.Receive(context, cancellationToken);
        }
Beispiel #17
0
        public async Task Send(string destinationAddress, TransportMessage message, ITransactionContext context)
        {
            if (_sendLatencyMs.HasValue)
            {
                await Task.Delay(_sendLatencyMs.Value);
            }

            await _innerTransport.Send(destinationAddress, message, context);
        }
 /// <summary>
 /// Constructor</summary>
 /// <param name="editingControlOwner">Interface for property editing control owners</param>
 /// <param name="descriptor">Property descriptor</param>
 /// <param name="transactionContext">Interface for transaction contexts</param>
 /// <param name="contextRegistry">Context registry</param>
 public PropertyEditorControlContext(
     IPropertyEditingControlOwner editingControlOwner,
     PropertyDescriptor descriptor,
     ITransactionContext transactionContext,
     IContextRegistry contextRegistry)
     : this(editingControlOwner, descriptor, transactionContext)
 {
     m_contextRegistry = contextRegistry;
 }
Beispiel #19
0
 /// <summary>
 /// Assigns the specified <see cref="ITransactionContext"/> to the current context
 /// </summary>
 public static void Set(ITransactionContext context)
 {
     if (RebusHttpContext.InContext)
         RebusHttpContext.TransactionContext = context;
     else if (RebusOperationContext.InContext)
         RebusOperationContext.TransactionContext = context;
     else
         CallContext.LogicalSetData(TransactionContextKey, context);
 }
Beispiel #20
0
        /// <summary>
        /// Assigns the specified <see cref="ITransactionContext"/> to the current thread
        /// </summary>
        public static void Set(ITransactionContext context)
        {
            if (!context.IsTransactional)
            {
                throw new InvalidOperationException(string.Format(@"Cannot mount {0} as the current ambient Rebus transaction context, but it does not make sense to do so.

            It does not make sense because a non-transactional transaction context does not have a life span that should be allowed to function as a context - by definition, a non-transactional context must be a throw-away context whose lifetime is purely transient.", context));
            }
            current = context;
        }
 /// <summary>
 /// Initializes this dialog with the required and optional contexts</summary>
 /// <param name="selectionContext">Selection context -- required</param>
 /// <param name="namingContext">Naming context -- required</param>
 /// <param name="transactionContext">Transaction context -- optional</param>
 /// <remarks>Combine with the constructor? This separate Set() only makes sense if this dialog box
 /// is floating or dockable.</remarks>
 public void Set(
     ISelectionContext selectionContext,
     INamingContext namingContext,
     ITransactionContext transactionContext)
 {
     m_selectionContext = selectionContext;
     m_namingContext = namingContext;
     m_transactionContext = transactionContext;
     UpdatePreview();
 }
        async Task Send(IEnumerable<string> destinationAddressesList,
            TransportMessage transportMessage,
            ITransactionContext currentTransactionContext)
        {
            var sendTasks = destinationAddressesList
                .Select(address => _transport.Send(address, transportMessage, currentTransactionContext))
                .ToArray();

            await Task.WhenAll(sendTasks);
        }
Beispiel #23
0
        public async Task Send(string destinationAddress, TransportMessage message, ITransactionContext context)
        {
            var outgoingMessages = context.GetOrAdd(OutgoingMessagesItemsKey, () =>
            {
                context.OnCommitted(async () => SendOutgoingMessages(context));

                return new ConcurrentQueue<OutgoingMessage>();
            });

            outgoingMessages.Enqueue(new OutgoingMessage(destinationAddress, message));
        }
Beispiel #24
0
        static IEnumerable<ReceivedTransportMessage> GetAllTheMessages(IReceiveMessages messageQueue, ITransactionContext transactionContext)
        {
            var messages = new List<ReceivedTransportMessage>();
            ReceivedTransportMessage transportMessage;
            while ((transportMessage = messageQueue.ReceiveMessage(transactionContext)) != null)
            {
                messages.Add(transportMessage);
            }

            return messages;
        }
        /// <summary>
        /// Receives a <see cref="ReceivedTransportMessage"/> using the underlying implementation of <see cref="IReceiveMessages"/>
        /// decrypting the message body if necessary, and remove the additional encryption headers
        /// </summary>
        public ReceivedTransportMessage ReceiveMessage(ITransactionContext context)
        {
            var message = innerReceiveMessages.ReceiveMessage(context);

            if (message == null) return null;

            var clone = new ReceivedTransportMessage
                            {
                                Body = message.Body,
                                Headers = message.Headers.Clone(),
                                Label = message.Label,
                                Id = message.Id
                            };

            var headers = clone.Headers;

            if (encryptionHelper != null)
            {
                if (headers.ContainsKey(Headers.Encrypted))
                {
                    var iv = clone.GetStringHeader(Headers.EncryptionSalt);
                    clone.Body = encryptionHelper.Decrypt(clone.Body, iv);

                    headers.Remove(Headers.EncryptionSalt);
                    headers.Remove(Headers.Encrypted);
                }
            }

            if (compressionHelper != null)
            {
                if (headers.ContainsKey(Headers.Compression))
                {
                    var compressionType = (headers[Headers.Compression] ?? "").ToString();

                    switch (compressionType)
                    {
                        case Headers.CompressionTypes.GZip:
                            clone.Body = compressionHelper.Decompress(clone.Body);
                            break;

                        default:
                            throw new ArgumentException(
                                string.Format(
                                    "Received message has the {0} header, but the compression type is set to {1} which cannot be handled",
                                    Headers.Compression, compressionType));
                    }

                    headers.Remove(Headers.Compression);
                }
            }

            return clone;
        }
 public DeleteProductCommand(long productID,
                             IProductDataProxy productDataProxy,
                             IInventoryItemService inventoryService,
                             IOrderService orderService,
                             ITransactionContext transactionContext)
 {
     _productID = productID;
     _productDataProxy = productDataProxy;
     _inventoryService = inventoryService;
     _orderService = orderService;
     _transactionContext = transactionContext;
 }
Beispiel #27
0
        /// <summary>
        /// Delivers the given message to the queue identitied by the given <paramref name="destinationAddress"/>
        /// </summary>
        public async Task Send(string destinationAddress, TransportMessage message, ITransactionContext context)
        {
            if (destinationAddress == null) throw new ArgumentNullException("destinationAddress");
            if (message == null) throw new ArgumentNullException("message");
            if (context == null) throw new ArgumentNullException("context");

            if (!_network.HasQueue(destinationAddress))
            {
                throw new ArgumentException(string.Format("Destination queue address '{0}' does not exist!", destinationAddress));
            }

            context.OnCommitted(async () => _network.Deliver(destinationAddress, message.ToInMemTransportMessage()));
        }
Beispiel #28
0
        public async Task<TransportMessage> Receive(ITransactionContext context)
        {
            var transportMessage = await _innerTransport.Receive(context);

            if (transportMessage != null)
            {
                _receivedMessages.Add(transportMessage);

                MessageReceived(transportMessage);
            }

            return transportMessage;
        }
        public ReceivedTransportMessage ReceiveMessage(ITransactionContext context)
        {
            ReceivedTransportMessage temp;
            if (messageQueue.TryDequeue(out temp))
            {
                context.DoRollback += () =>
                    {
                        Console.WriteLine("Returning {0} to the fake message queue", temp);
                        messageQueue.Enqueue(temp);
                    };

                return temp;
            }
            return null;
        }
        public void Send(string destinationQueueName, TransportMessageToSend message, ITransactionContext context)
        {
            var iv = helper.GenerateNewIv();

            var transportMessageToSend = new TransportMessageToSend
                                             {
                                                 Headers = message.Headers.Clone(),
                                                 Label = message.Label,
                                                 Body = helper.Encrypt(message.Body, iv),
                                             };

            transportMessageToSend.Headers[Headers.Encrypted] = null;
            transportMessageToSend.Headers[Headers.EncryptionSalt] = iv;

            innerSendMessages.Send(destinationQueueName, transportMessageToSend, context);
        }
Beispiel #31
0
        /// <summary>
        /// Sends the given <see cref="TransportMessage"/> to the queue with the specified globally addressable name
        /// </summary>
        public async Task Send(string destinationAddress, TransportMessage transportMessage, ITransactionContext context)
        {
            var outgoingMessages = context.GetOrAdd("outgoing-messages", () =>
            {
                var messagesToSend = new ConcurrentQueue <MessageToSend>();

                context.OnCommitted((_) =>
                {
                    var messagesByQueue = messagesToSend
                                          .GroupBy(m => m.DestinationAddress)
                                          .ToList();

                    return(Task.WhenAll(messagesByQueue.Select(async batch =>
                    {
                        var queueName = batch.Key;
                        var queue = await _queueFactory.GetQueue(queueName);

                        await Task.WhenAll(batch.Select(async message =>
                        {
                            var headers = message.Headers.Clone();
                            var timeToBeReceivedOrNull = GetTimeToBeReceivedOrNull(headers);
                            var queueVisibilityDelayOrNull = GetQueueVisibilityDelayOrNull(headers);
                            var cloudQueueMessage = Serialize(headers, message.Body);

                            try
                            {
                                await queue.AddMessageAsync(
                                    cloudQueueMessage,
                                    timeToBeReceivedOrNull,
                                    queueVisibilityDelayOrNull,
                                    ExponentialRetryRequestOptions,
                                    new OperationContext()
                                    );
                            }
                            catch (Exception exception)
                            {
                                var errorText = $"Could not send message with ID {cloudQueueMessage.Id} to '{message.DestinationAddress}'";

                                throw new RebusApplicationException(exception, errorText);
                            }
                        }));
                    })));
                });

                return(messagesToSend);
            });

            var messageToSend = new MessageToSend(destinationAddress, transportMessage.Headers, transportMessage.Body);

            outgoingMessages.Enqueue(messageToSend);
        }
 public static string CurrentSchema(this ITransactionContext transaction)
 {
     return(transaction.GetStringVariable(TransactionSettingKeys.CurrentSchema));
 }
 public static bool IgnoreIdentifiersCase(this ITransactionContext transaction)
 {
     return(transaction.GetBooleanVariable(TransactionSettingKeys.IgnoreIdentifiersCase));
 }
 public static void IgnoreIdentifiersCase(this ITransactionContext transaction, bool value)
 {
     transaction.SetBooleanVariable(TransactionSettingKeys.IgnoreIdentifiersCase, value);
 }
 public static bool ReadOnly(this ITransactionContext transaction)
 {
     return(transaction.GetBooleanVariable(TransactionSettingKeys.ReadOnly));
 }
Beispiel #36
0
            public async Task Send(string destinationAddress, TransportMessage message, ITransactionContext context)
            {
                for (var counter = 0; counter < 10; counter++)
                {
                    Console.Write(".");
                    await Task.Delay(100);
                }

                Console.WriteLine($"Sending {message.GetMessageLabel()}");

                await _transport.Send(destinationAddress, message, context);
            }
Beispiel #37
0
        /// <summary>
        /// Resolves all handlers for the given <typeparamref name="TMessage"/> message type
        /// </summary>
        public async Task <IEnumerable <IHandleMessages <TMessage> > > GetHandlers <TMessage>(TMessage message, ITransactionContext transactionContext)
        {
            var handlerInstances = _container
                                   .GetAllInstances <IHandleMessages <TMessage> >()
                                   .ToList();

            transactionContext.OnDisposed(() =>
            {
                handlerInstances
                .OfType <IDisposable>()
                .ForEach(disposable =>
                {
                    disposable.Dispose();
                });
            });

            return(handlerInstances);
        }
Beispiel #38
0
        /// <summary>
        /// Resolves all handlers for the given <typeparamref name="TMessage"/> message type
        /// </summary>
        public async Task <IEnumerable <IHandleMessages <TMessage> > > GetHandlers <TMessage>(TMessage message, ITransactionContext transactionContext)
        {
            if (TryGetInstance <IEnumerable <IHandleMessages <TMessage> > >(_container, out var handlerInstances))
            {
                var handlerList = handlerInstances.ToList();

                transactionContext.OnDisposed(() =>
                {
                    handlerList
                    .OfType <IDisposable>()
                    .ForEach(disposable =>
                    {
                        disposable.Dispose();
                    });
                });

                return(handlerList);
            }

            return(new IHandleMessages <TMessage> [0]);
        }
Beispiel #39
0
 public async Task Send(string destinationAddress, TransportMessage message, ITransactionContext context)
 {
     await _innerTransport.Send(destinationAddress, message, context);
 }
Beispiel #40
0
        ConcurrentDictionary <string, ConcurrentQueue <TransportMessage> > GetOutgoingMessages(ITransactionContext context)
        {
            return(context.GetOrAdd(OutgoingMessagesKey, () =>
            {
                var destinations = new ConcurrentDictionary <string, ConcurrentQueue <TransportMessage> >();

                context.OnCommitted(async() =>
                {
                    // send outgoing messages
                    foreach (var destinationAndMessages in destinations)
                    {
                        var destinationAddress = destinationAndMessages.Key;
                        var messages = destinationAndMessages.Value;

                        var sendTasks = messages
                                        .Select(async message =>
                        {
                            await GetRetrier().Execute(async() =>
                            {
                                using (var brokeredMessageToSend = MsgHelpers.CreateBrokeredMessage(message))
                                {
                                    try
                                    {
                                        await Send(destinationAddress, brokeredMessageToSend).ConfigureAwait(false);
                                    }
                                    catch (MessagingEntityNotFoundException exception)
                                    {
                                        // do NOT rethrow as MessagingEntityNotFoundException because it has its own ToString that swallows most of the info!!
                                        throw new MessagingException($"Could not send to '{destinationAddress}'!", false, exception);
                                    }
                                }
                            }).ConfigureAwait(false);
                        })
                                        .ToArray();

                        await Task.WhenAll(sendTasks).ConfigureAwait(false);
                    }
                });

                return destinations;
            }));
        }
 /// <summary>
 /// Default constructor.
 /// </summary>
 /// <param name="mainTransactionContext">The transaction context of the session owning the
 /// <see cref="ConnectionManager"/>.</param>
 public DependentContext(ITransactionContext mainTransactionContext)
 {
     MainTransactionContext = mainTransactionContext ?? throw new ArgumentNullException(nameof(mainTransactionContext));
 }
Beispiel #42
0
        /// <summary>
        /// Sends the given transport message to the specified destination queue address by adding it to the queue's table.
        /// </summary>
        public virtual async Task Send(string destinationAddress, TransportMessage message, ITransactionContext context)
        {
            var connection = await GetConnection(context).ConfigureAwait(false);

            var destinationAddressToUse = GetDestinationAddressToUse(destinationAddress, message);

            try
            {
                await InnerSend(destinationAddressToUse, message, connection).ConfigureAwait(false);
            }
            catch (Exception e)
            {
                throw new RebusApplicationException(e, $"Unable to send to destination {destinationAddress}");
            }
        }
 public static void CurrentSchema(this ITransactionContext transaction, string schemaName)
 {
     transaction.SetStringVariable(TransactionSettingKeys.CurrentSchema, schemaName);
 }
Beispiel #44
0
        /// <inheritdoc />
        public async Task <TransportMessage> Receive(ITransactionContext context, CancellationToken cancellationToken)
        {
            if (Address == null)
            {
                throw new InvalidOperationException("This RabbitMQ transport does not have an input queue - therefore, it is not possible to receive anything");
            }

            try
            {
                if (!_consumers.TryDequeue(out var consumer))
                {
                    consumer = InitializeConsumer();
                }
                else
                {
                    try
                    {
                        // When a consumer is dequeued from the the "consumers" pool, it might be bound to a queue, which does not exist anymore,
                        // eg. expired and deleted by RabittMQ server policy). In this case this calling QueueDeclarePassive will result in
                        // an OperationInterruptedException and "consumer.Model.IsOpen" will be set to false (this is handled later in the code by
                        // disposing this consumer). There is no need to handle this exception. The logic of InitializeConsumer() will make sure
                        // that the queue is recreated later based on assumption about how ReBus is handling null-result of ITransport.Receive().
                        consumer?.Model.QueueDeclarePassive(Address);
                    }
                    catch { }
                }

                if (consumer == null)
                {
                    // initialization must have failed
                    return(null);
                }

                if (!consumer.Model.IsOpen)
                {
                    consumer.Dispose();
                    return(null);
                }

                context.OnDisposed((tc) => _consumers.Enqueue(consumer));


                if (!consumer.Queue.Dequeue(TwoSeconds, out var result))
                {
                    return(null);
                }

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

                // ensure we use the consumer's model throughtout the handling of this message
                context.Items[CurrentModelItemsKey] = consumer.Model;

                var deliveryTag = result.DeliveryTag;

                context.OnCompleted(async(tc) =>
                {
                    var model = GetModel(context);
                    model.BasicAck(deliveryTag, multiple: false);
                });

                context.OnAborted((tc) =>
                {
                    // we might not be able to do this, but it doesn't matter that much if it succeeds
                    try
                    {
                        var model = GetModel(context);
                        model.BasicNack(deliveryTag, multiple: false, requeue: true);
                    }
                    catch { }
                });

                return(CreateTransportMessage(result.BasicProperties, result.Body));
            }
            catch (EndOfStreamException)
            {
                return(null);
            }
            catch (Exception exception)
            {
                Thread.Sleep(1000);

                throw new RebusApplicationException(exception, $"Unexpected exception thrown while trying to dequeue a message from rabbitmq, queue address: {Address}");
            }
        }
 public static void AutoCommit(this ITransactionContext transaction, bool value)
 {
     transaction.SetBooleanVariable(TransactionSettingKeys.AutoCommit, value);
 }
 public static bool AutoCommit(this ITransactionContext transaction)
 {
     return(transaction.GetBooleanVariable(TransactionSettingKeys.AutoCommit));
 }
Beispiel #47
0
 public async Task <TransportMessage> Receive(ITransactionContext context, CancellationToken cancellationToken)
 {
     return(await _transport.Receive(context, cancellationToken));
 }
 public static bool ErrorOnDirtySelect(this ITransactionContext transaction)
 {
     return(transaction.GetBooleanVariable(TransactionSettingKeys.ErrorOnDirtySelect));
 }
Beispiel #49
0
        async Task <TransportMessage> ReceiveTransportMessage(CancellationToken token, ITransactionContext context)
        {
            try
            {
                return(await _transport.Receive(context, token).ConfigureAwait(false));
            }
            catch (TaskCanceledException)
            {
                // it's fine - just a sign that we are shutting down
                throw;
            }
            catch (OperationCanceledException)
            {
                // it's fine - just a sign that we are shutting down
                throw;
            }
            catch (Exception exception)
            {
                _log.Warn("An error occurred when attempting to receive the next message: {exception}", exception);

                _backoffStrategy.WaitError();

                return(null);
            }
        }
 public static void ErrorOnDirtySelect(this ITransactionContext transaction, bool value)
 {
     transaction.SetBooleanVariable(TransactionSettingKeys.ErrorOnDirtySelect, value);
 }
        /// <summary>
        /// Resolves all handlers for the given <typeparamref name="TMessage"/> message type
        /// </summary>
        public async Task <IEnumerable <IHandleMessages <TMessage> > > GetHandlers <TMessage>(TMessage message, ITransactionContext transactionContext)
        {
            var handlerInstances = GetAllHandlerInstances <TMessage>();

            transactionContext.OnDisposed(() =>
            {
                foreach (var disposableInstance in handlerInstances.OfType <IDisposable>())
                {
                    disposableInstance.Dispose();
                }
            });

            return(handlerInstances);
        }
Beispiel #52
0
        /// <summary>
        /// Receives the next message from the input queue. Returns null if no message was available
        /// </summary>
        public async Task <TransportMessage> Receive(ITransactionContext context, CancellationToken cancellationToken)
        {
            if (_inputQueueAddress == null)
            {
                throw new InvalidOperationException("This Azure Service Bus transport does not have an input queue, hence it is not possible to reveive anything");
            }

            using (await _bottleneck.Enter(cancellationToken).ConfigureAwait(false))
            {
                var brokeredMessage = await ReceiveBrokeredMessage().ConfigureAwait(false);

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

                var headers = brokeredMessage.Properties
                              .Where(kvp => kvp.Value is string)
                              .ToDictionary(kvp => kvp.Key, kvp => (string)kvp.Value);

                var messageId           = headers.GetValueOrNull(Headers.MessageId);
                var now                 = DateTime.UtcNow;
                var leaseDuration       = brokeredMessage.LockedUntilUtc - now;
                var lockRenewalInterval = TimeSpan.FromMinutes(0.5 * leaseDuration.TotalMinutes);

                var renewalTask = GetRenewalTaskOrFakeDisposable(messageId, brokeredMessage, lockRenewalInterval);

                context.OnAborted(() =>
                {
                    renewalTask.Dispose();

                    try
                    {
                        brokeredMessage.Abandon();
                    }
                    catch (Exception exception)
                    {
                        // if it fails, it'll be back on the queue anyway....
                        _log.Warn("Could not abandon message: {0}", exception);
                    }
                });

                context.OnCommitted(async() =>
                {
                    renewalTask.Dispose();
                });

                context.OnCompleted(async() =>
                {
                    try
                    {
                        await brokeredMessage.CompleteAsync().ConfigureAwait(false);
                    }
                    catch (MessageLockLostException exception)
                    {
                        var elapsed = DateTime.UtcNow - now;

                        throw new RebusApplicationException(exception, $"The message lock for message with ID {messageId} was lost - tried to complete after {elapsed.TotalSeconds:0.0} s");
                    }
                });

                context.OnDisposed(() =>
                {
                    renewalTask.Dispose();

                    brokeredMessage.Dispose();
                });

                using (var memoryStream = new MemoryStream())
                {
                    await brokeredMessage.GetBody <Stream>().CopyToAsync(memoryStream).ConfigureAwait(false);

                    return(new TransportMessage(headers, memoryStream.ToArray()));
                }
            }
        }
Beispiel #53
0
 /// <summary>
 /// Sends the given message to the queue with the given <paramref name="destinationAddress"/>
 /// </summary>
 public async Task Send(string destinationAddress, TransportMessage message, ITransactionContext context)
 {
     GetOutgoingMessages(context)
     .GetOrAdd(destinationAddress, _ => new ConcurrentQueue <TransportMessage>())
     .Enqueue(message);
 }
 public static void ReadOnly(this ITransactionContext transaction, bool value)
 {
     transaction.SetBooleanVariable(TransactionSettingKeys.ReadOnly, value);
 }
Beispiel #55
0
        /// <summary>
        /// Resolves all handlers for the given <typeparamref name="TMessage"/> message type
        /// </summary>
        public async Task <IEnumerable <IHandleMessages <TMessage> > > GetHandlers <TMessage>(TMessage message, ITransactionContext transactionContext)
        {
            var handlerInstances = GetAllHandlerInstances <TMessage>();

            void DisposeInstances(ITransactionContext _)
            {
                foreach (var instance in handlerInstances)
                {
                    _windsorContainer.Release(instance);
                }
            }

            transactionContext.OnDisposed(DisposeInstances);

            return(handlerInstances);
        }
Beispiel #56
0
        private async Task <bool> ExecutePluginOnPostTransactionStageAsync(IExecutive executive,
                                                                           ITransactionContext txContext,
                                                                           Timestamp currentBlockTime,
                                                                           IChainContext internalChainContext,
                                                                           TieredStateCache internalStateCache,
                                                                           CancellationToken cancellationToken)
        {
            var trace = txContext.Trace;

            if (!trace.IsSuccessful())
            {
                internalStateCache = new TieredStateCache(txContext.StateCache);
                foreach (var preTrace in txContext.Trace.PreTraces)
                {
                    var stateSets = preTrace.GetStateSets();
                    internalStateCache.Update(stateSets);
                }

                internalChainContext.StateCache = internalStateCache;
            }

            foreach (var plugin in _postPlugins)
            {
                var transactions = await plugin.GetPostTransactionsAsync(executive.Descriptors, txContext);

                foreach (var postTx in transactions)
                {
                    var singleTxExecutingDto = new SingleTransactionExecutingDto
                    {
                        Depth            = 0,
                        ChainContext     = internalChainContext,
                        Transaction      = postTx,
                        CurrentBlockTime = currentBlockTime
                    };
                    var postTrace = await ExecuteOneAsync(singleTxExecutingDto, cancellationToken);

                    if (postTrace == null)
                    {
                        return(false);
                    }
                    trace.PostTransactions.Add(postTx);
                    trace.PostTraces.Add(postTrace);

                    if (postTx.MethodName == "ChargeResourceToken")
                    {
                        var consumedResourceTokens = new ConsumedResourceTokens();
                        consumedResourceTokens.MergeFrom(postTrace.ReturnValue);
                        trace.ConsumedResourceTokens = consumedResourceTokens;
                    }

                    if (!postTrace.IsSuccessful())
                    {
                        return(false);
                    }

                    internalStateCache.Update(postTrace.GetStateSets());
                }
            }

            return(true);
        }
 /// <summary>
 /// Create a transaction context for a dependent session.
 /// </summary>
 /// <param name="dependentSession">The dependent session.</param>
 /// <param name="mainContext">The context of the session owning the <see cref="ConnectionManager"/>.</param>
 /// <returns>A dependent context for the session.</returns>
 protected virtual ITransactionContext CreateDependentContext(ISessionImplementor dependentSession, ITransactionContext mainContext)
 {
     return(new DependentContext(mainContext));
 }
Beispiel #58
0
 public Task Send(string destinationAddress, TransportMessage message, ITransactionContext context)
 {
     return(_transport.Send(destinationAddress, message, context));
 }
 private void EnlistDependentSession(ISessionImplementor dependentSession, ITransactionContext mainContext)
 {
     dependentSession.TransactionContext = CreateDependentContext(dependentSession, mainContext);
     dependentSession.AfterTransactionBegin(null);
 }
Beispiel #60
0
 public BindingController(ITransactionContext context)
     : base(context)
 {
 }