public Bridge(string leftName, string rightName, bool autoCreateQueues, string autoCreateQueuesIdentity, EndpointInstances endpointInstances, ISubscriptionStorage subscriptionStorage, IDistributionPolicy distributionPolicy, string poisonQueue, Action <TransportExtensions <TLeft> > leftCustomization, Action <TransportExtensions <TRight> > rightCustomization, int?maximumConcurrency) { this.endpointInstances = endpointInstances; this.subscriptionStorage = subscriptionStorage; publishRouter = new PublishRouter(subscriptionStorage, distributionPolicy); sendRouter = new SendRouter(endpointInstances, distributionPolicy); replyRouter = new ReplyRouter(); leftConfig = RawEndpointConfiguration.Create(leftName, (context, _) => Forward(context, rightStartable, rightSubscribeRouter), poisonQueue); var leftTransport = leftConfig.UseTransport <TLeft>(); leftTransport.GetSettings().Set("errorQueue", poisonQueue); leftCustomization?.Invoke(leftTransport); if (autoCreateQueues) { leftConfig.AutoCreateQueue(autoCreateQueuesIdentity); } rightConfig = RawEndpointConfiguration.Create(rightName, (context, _) => Forward(context, leftStartable, leftSubscribeRouter), poisonQueue); var rightTransport = rightConfig.UseTransport <TRight>(); rightTransport.GetSettings().Set("errorQueue", poisonQueue); rightCustomization?.Invoke(rightTransport); if (autoCreateQueues) { rightConfig.AutoCreateQueue(autoCreateQueuesIdentity); } if (maximumConcurrency.HasValue) { leftConfig.LimitMessageProcessingConcurrencyTo(1); rightConfig.LimitMessageProcessingConcurrencyTo(1); } }
Resubscriber(string inputQueueName, TimeSpan delay, Action <TransportExtensions <T> > configureTransport) { this.inputQueueName = inputQueueName; config = RawEndpointConfiguration.Create(inputQueueName + ".Resubscriber", async(context, dispatcher) => { context.Headers.TryGetValue(Headers.SubscriptionMessageType, out var messageTypeString); if (!context.Headers.TryGetValue(Headers.SubscriberTransportAddress, out var subscriberAddress)) { subscriberAddress = context.Headers[Headers.ReplyToAddress]; } var key = Tuple.Create(subscriberAddress, messageTypeString); var resubscriptionId = context.Headers[ResubscriptionIdHeader]; var resubscriptionTimestamp = DateTime.Parse(context.Headers[ResubscriptionTimestampHeader]); if (idMap.ContainsKey(key)) { var valuePair = idMap[key]; if (valuePair.Item1 != resubscriptionId && resubscriptionTimestamp < valuePair.Item2) { //If we already processed a newer subscribe/unsubscribe message for this -> ignore return; } //We've seen that same message before. Let's pause the resubscription for some time await Task.Delay(delay); } //Send it to the bridge to re-subscribe var outgoingMessage = new OutgoingMessage(context.MessageId, context.Headers, context.Body); var operation = new TransportOperation(outgoingMessage, new UnicastAddressTag(inputQueueName)); await dispatcher.Dispatch(new TransportOperations(operation), context.TransportTransaction, context.Extensions).ConfigureAwait(false); logger.Debug("Moved subscription message back to the queue."); idMap[key] = Tuple.Create(resubscriptionId, resubscriptionTimestamp); }, "poison"); config.AutoCreateQueue(); config.LimitMessageProcessingConcurrencyTo(1); var transport = config.UseTransport <T>(); configureTransport(transport); }