/// <summary> /// Constructor</summary> public TransactionPropertyNode(ITransactionContext context) { if(context != null) m_contextRef = new WeakReference(context); else IsReadOnly = true; }
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); }
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}'"); } }); }
/// <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; }
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; }
public async Task Send(string destinationAddress, TransportMessage message, ITransactionContext context) { await _innerTransport.Send(destinationAddress, message, context); _sentMessages.Add(message); MessageSent(message); }
public OrderItemClientService(IOrderItemDataProxy dataProxy, IProductDataProxy productDataProxy, IInventoryItemDataProxy inventoryDataProxy, ITransactionContext transactionContext) : base(dataProxy, productDataProxy, inventoryDataProxy, transactionContext) { _inventoryDataProxy = inventoryDataProxy; _transactionContext = transactionContext; }
public async Task<TransportMessage> Receive(ITransactionContext context, CancellationToken cancellationToken) { if (_receiveLatencyMs.HasValue) { await Task.Delay(_receiveLatencyMs.Value, cancellationToken); } return await _innerTransport.Receive(context, cancellationToken); }
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; }
/// <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); }
/// <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); }
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)); }
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; }
/// <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())); }
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); }
/// <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)); }
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); }
/// <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); }
/// <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]); }
public async Task Send(string destinationAddress, TransportMessage message, ITransactionContext context) { await _innerTransport.Send(destinationAddress, message, context); }
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)); }
/// <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); }
/// <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)); }
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)); }
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); }
/// <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())); } } }
/// <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); }
/// <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); }
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)); }
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); }
public BindingController(ITransactionContext context) : base(context) { }