public void Runs() { var random = new Random(); var max = (byte)random.Next(byte.MinValue, byte.MaxValue); var min = (byte)random.Next(byte.MinValue, max); var count = Substitute.For<IQueueCount>(); var setup = new QueueSetup<object> { Name = "test", Priority = QueuePriority.Low, Processor = () => { return Substitute.For<IProcessor<object>>(); }, }; var connection = new QueueConnection<object>() { ConnectionString = ConnectionString, Setup = setup, }; var throughput = Substitute.For<IQueueThroughput>(); throughput.Frequency(setup.Priority).Returns(new Range<byte>(min, max)); var s = new BusQueueAutoScaler<object>(count, connection, throughput); var runs = s.Runs(connection); Assert.IsNotNull(runs); Assert.AreEqual(min, runs.MinimumPeriodInSeconds); Assert.AreEqual(max, runs.MaximumPeriodInSeconds); throughput.Received().Frequency(setup.Priority); }
public void Runs() { var random = new Random(); var frequency = new Range<byte>(); frequency.Maximum = (byte)random.Next(byte.MinValue, byte.MaxValue); frequency.Minimum = (byte)random.Next(byte.MinValue, frequency.Maximum); var count = Substitute.For<IQueueCount>(); var setup = new QueueSetup<object>() { Priority = QueuePriority.High, Name = Guid.NewGuid().ToString(), Processor = () => { return Substitute.For<IProcessor<object>>(); }, }; var connection = new QueueConnection<object>() { Setup = setup, ConnectionString = ConnectionString, }; var throughput = Substitute.For<IQueueThroughput>(); throughput.Frequency(setup.Priority).Returns(frequency); var s = new StorageQueueAutoScaler<object>(count, connection, throughput); var runs = s.Runs(connection); Assert.IsNotNull(runs); Assert.AreEqual(frequency.Minimum, runs.MinimumPeriodInSeconds); Assert.AreEqual(frequency.Maximum, runs.MaximumPeriodInSeconds); throughput.Received().Frequency(setup.Priority); }
public void ConnectionString() { var expected = Guid.NewGuid().ToString(); var qc = new QueueConnection<object>() { ConnectionString = expected, }; Assert.AreEqual(expected, qc.ConnectionString); }
public void Setup() { var expected = new QueueSetup<object>(); var qc = new QueueConnection<object>() { Setup = expected, }; Assert.AreEqual(expected, qc.Setup); }
public static void NoVerification(QueueConnection queueConnection, QueueProducerConfiguration queueProducerConfiguration, long messageCount, ICreationScope scope) { }
public static void Verify(QueueConnection queueConnection, QueueProducerConfiguration queueProducerConfiguration, long messageCount, int orderId, ICreationScope scope) { new VerifyQueueData(queueConnection, queueProducerConfiguration.Options()).Verify(messageCount, null, orderId); }
static void Main(string[] args) { //we are using serilog for sample purposes var log = new LoggerConfiguration() .WriteTo.Console() .MinimumLevel.Debug() .CreateLogger(); Log.Logger = log; log.Information("Startup"); log.Information(SharedConfiguration.AllSettings); //verify that the queue exists var fileLocation = Path.Combine(Environment.ExpandEnvironmentVariables("%userprofile%"), "Documents"); var queueName = ConfigurationManager.AppSettings.ReadSetting("QueueName"); var connectionString = $"Filename={fileLocation}{ConfigurationManager.AppSettings.ReadSetting("Database")};Connection=shared;"; var queueConnection = new QueueConnection(queueName, connectionString); using (var createQueueContainer = new QueueCreationContainer <LiteDbMessageQueueInit>(serviceRegister => Injectors.AddInjectors(new SerilogAdapter(log), SharedConfiguration.EnableTrace, SharedConfiguration.EnableMetrics, SharedConfiguration.EnableCompression, SharedConfiguration.EnableEncryption, "LiteDbConsumerLinq", serviceRegister), options => Injectors.SetOptions(options, SharedConfiguration.EnableChaos))) { using (var createQueue = createQueueContainer.GetQueueCreation <LiteDbMessageQueueCreation>(queueConnection)) { if (!createQueue.QueueExists) { //the consumer can't do anything if the queue hasn't been created Log.Error( $"Could not find {connectionString}. Verify that you have run the producer, which will create the queue"); return; } } } using (var schedulerContainer = new SchedulerContainer(serviceRegister => Injectors.AddInjectors(new SerilogAdapter(log), SharedConfiguration.EnableTrace, SharedConfiguration.EnableMetrics, SharedConfiguration.EnableCompression, SharedConfiguration.EnableEncryption, "LiteDbConsumerLinq", serviceRegister), options => Injectors.SetOptions(options, SharedConfiguration.EnableChaos))) { using (var scheduler = schedulerContainer.CreateTaskScheduler()) { var factory = schedulerContainer.CreateTaskFactory(scheduler); factory.Scheduler.Configuration.MaximumThreads = 8; //8 background threads factory.Scheduler.Configuration.MaxQueueSize = 1; //allow work to be de-queued but held in memory until a thread is free //note - the same factory can be passed to multiple queue instances - don't dispose the scheduler container until all queues have finished factory.Scheduler.Start(); //the scheduler must be started before passing it to a queue using (var queueContainer = new QueueContainer <LiteDbMessageQueueInit>(serviceRegister => Injectors.AddInjectors(new SerilogAdapter(log), SharedConfiguration.EnableTrace, SharedConfiguration.EnableMetrics, SharedConfiguration.EnableCompression, SharedConfiguration.EnableEncryption, "LiteDbConsumerLinq", serviceRegister), options => Injectors.SetOptions(options, SharedConfiguration.EnableChaos))) { using (var queue = queueContainer.CreateConsumerMethodQueueScheduler(queueConnection, factory)) { //set some processing options and start looking for work //in the async model, the worker count is how many threads are querying the queue - the scheduler runs the work queue.Configuration.Worker.WorkerCount = 1; //lets just run 1 thread that queries the database queue.Configuration.HeartBeat.UpdateTime = "sec(*%10)"; //set a heartbeat every 10 seconds queue.Configuration.HeartBeat.MonitorTime = TimeSpan.FromSeconds(15); //check for dead records every 15 seconds queue.Configuration.HeartBeat.Time = TimeSpan.FromSeconds( 35); //records with no heartbeat after 35 seconds are considered dead //an invalid data exception will be re-tried 3 times, with delays of 3, 6 and then finally 9 seconds queue.Configuration.TransportConfiguration.RetryDelayBehavior.Add( typeof(InvalidDataException), new List <TimeSpan> { TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(6), TimeSpan.FromSeconds(9) }); queue.Configuration.MessageExpiration.Enabled = true; queue.Configuration.MessageExpiration.MonitorTime = TimeSpan.FromSeconds(20); //check for expired messages every 20 seconds queue.Start(); Console.WriteLine("Processing messages - press any key to stop"); Console.ReadKey((true)); //if jaeger is using udp, sometimes the messages get lost; there doesn't seem to be a flush() call ? if (SharedConfiguration.EnableTrace) { System.Threading.Thread.Sleep(2000); } } } } } }
private void Verify(QueueConnection arg1, QueueProducerConfiguration arg2, long arg3, ICreationScope arg4) { //only verify count in redis }
public void Run <TTransportInit, TTransportCreate>( QueueConnection queueConnection, int messageCount, int runtime, int timeOut, int workerCount, int readerCount, int queueSize, int messageType, LinqMethodTypes linqMethodTypes, bool enableChaos, Action <TTransportCreate> setOptions, Func <QueueProducerConfiguration, AdditionalMessageData> generateData, Action <QueueConnection, QueueProducerConfiguration, long, ICreationScope> verify, Action <QueueConnection, IBaseTransportOptions, ICreationScope, int, bool, bool> verifyQueueCount) where TTransportInit : ITransportInit, new() where TTransportCreate : class, IQueueCreation { if (Factory == null) { Factory = CreateFactory(workerCount, queueSize); } var logProvider = LoggerShared.Create(queueConnection.Queue, GetType().Name); using (var queueCreator = new QueueCreationContainer <TTransportInit>( serviceRegister => serviceRegister.Register(() => logProvider, LifeStyles.Singleton))) { ICreationScope scope = null; var oCreation = queueCreator.GetQueueCreation <TTransportCreate>(queueConnection); try { setOptions(oCreation); var result = oCreation.CreateQueue(); Assert.True(result.Success, result.ErrorMessage); scope = oCreation.Scope; if (messageType == 1) { var id = Guid.NewGuid(); var producer = new ProducerMethodAsyncShared(); producer.RunTestAsync <TTransportInit>(queueConnection, false, messageCount, logProvider, generateData, verify, false, runtime, id, linqMethodTypes, oCreation.Scope, false).Wait(timeOut); var consumer = new ConsumerMethodAsyncShared { Factory = Factory }; consumer.RunConsumer <TTransportInit>(queueConnection, false, logProvider, runtime, messageCount, timeOut, readerCount, TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(35), id, "second(*%10)", enableChaos, scope); } else if (messageType == 2) { var id = Guid.NewGuid(); var producer = new ProducerMethodAsyncShared(); producer.RunTestAsync <TTransportInit>(queueConnection, false, messageCount, logProvider, generateData, verify, false, runtime, id, linqMethodTypes, oCreation.Scope, false).Wait(timeOut); var consumer = new ConsumerMethodAsyncShared { Factory = Factory }; consumer.RunConsumer <TTransportInit>(queueConnection, false, logProvider, runtime, messageCount, timeOut, readerCount, TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(35), id, "second(*%10)", enableChaos, scope); } else if (messageType == 3) { var id = Guid.NewGuid(); var producer = new ProducerMethodAsyncShared(); producer.RunTestAsync <TTransportInit>(queueConnection, false, messageCount, logProvider, generateData, verify, false, runtime, id, linqMethodTypes, oCreation.Scope, false).Wait(timeOut); var consumer = new ConsumerMethodAsyncShared { Factory = Factory }; consumer.RunConsumer <TTransportInit>(queueConnection, false, logProvider, runtime, messageCount, timeOut, readerCount, TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(35), id, "second(*%10)", enableChaos, scope); } verifyQueueCount(queueConnection, oCreation.BaseTransportOptions, scope, 0, false, false); } finally { oCreation.RemoveQueue(); oCreation.Dispose(); scope?.Dispose(); } } }
public VerifyQueueRecordCount(QueueConnection queueConnection, SqlServerMessageQueueTransportOptions options) { _options = options; _connection = new SqlConnectionInformation(queueConnection); _tableNameHelper = new SqlServerTableNameHelper(_connection); }
/// <summary> /// Initializes a new instance of the <see cref="RedisConnectionInfo"/> class. /// </summary> /// <param name="queueConnection">Queue and connection information.</param> public RedisConnectionInfo(QueueConnection queueConnection) : base(queueConnection) { ValidateConnection(queueConnection.Connection); }
public void RunConsumer <TTransportInit>(QueueConnection queueConnection, bool addInterceptors, ILogger logProvider, int messageCount, int workerCount, int timeOut, int queueSize, int readerCount, TimeSpan heartBeatTime, TimeSpan heartBeatMonitorTime, string updateTime, string route, bool enableChaos, ICreationScope scope) where TTransportInit : ITransportInit, new() { if (enableChaos) { timeOut *= 2; } using (var metrics = new Metrics.Metrics(queueConnection.Queue)) { var addInterceptorConsumer = InterceptorAdding.No; if (addInterceptors) { addInterceptorConsumer = InterceptorAdding.ConfigurationOnly; } var processedCount = new IncrementWrapper(); using ( var creator = SharedSetup.CreateCreator <TTransportInit>(addInterceptorConsumer, logProvider, metrics, false, enableChaos, scope) ) { using (var schedulerCreator = new SchedulerContainer( // ReSharper disable once AccessToDisposedClosure serviceRegister => serviceRegister.Register(() => metrics, LifeStyles.Singleton), options => SharedSetup.SetOptions(options, enableChaos))) { bool rollBacks; using (var taskScheduler = schedulerCreator.CreateTaskScheduler()) { taskScheduler.Configuration.MaximumThreads = workerCount; taskScheduler.Configuration.MaxQueueSize = queueSize; taskScheduler.Start(); var taskFactory = schedulerCreator.CreateTaskFactory(taskScheduler); using ( var queue = creator .CreateConsumerQueueScheduler( queueConnection, taskFactory)) { rollBacks = queue.Configuration.TransportConfiguration.MessageRollbackSupported; SharedSetup.SetupDefaultConsumerQueue(queue.Configuration, readerCount, heartBeatTime, heartBeatMonitorTime, updateTime, route); SharedSetup.SetupDefaultErrorRetry(queue.Configuration); var waitForFinish = new ManualResetEventSlim(false); waitForFinish.Reset(); //start looking for work queue.Start <TMessage>((message, notifications) => { MessageHandlingShared.HandleFakeMessagesError(processedCount, waitForFinish, messageCount, message); }); waitForFinish.Wait(timeOut * 1000); //wait for last error to be saved if needed. Thread.Sleep(3000); } } if (rollBacks) { VerifyMetrics.VerifyRollBackCount(queueConnection.Queue, metrics.GetCurrentMetrics(), messageCount, 2, 2); } } } } }
/// <summary> /// Allows a transport to register its dependencies in the IoC container. /// </summary> /// <param name="container">The container.</param> /// <param name="registrationType">Type of the registration.</param> /// <param name="queueConnection">Queue and connection information.</param> public override void RegisterImplementations(IContainer container, RegistrationTypes registrationType, QueueConnection queueConnection) { RegisterConnectionImplementation.RegisterImplementations(container, queueConnection); }
public void ScaleUnit() { var count = Substitute.For<IQueueCount>(); var setup = Substitute.For<IQueueSetup<object>>(); setup.Name.Returns(Guid.NewGuid().ToString()); var connection = new QueueConnection<object>() { Setup = setup, ConnectionString = ConnectionString, }; var s = new BusQueueAutoScaler<object>(count, connection); var unit = s.ScaleUnit(connection); Assert.IsNotNull(unit); Assert.AreEqual(1, unit.Count()); }
public void ScaleUnitSetupNull() { var count = Substitute.For<IQueueCount>(); var setup = new QueueConnection<object>(); var s = new StorageQueueAutoScaler<object>(count, setup); var unit = s.ScaleUnit(null); Assert.IsNotNull(unit); Assert.AreEqual(1, unit.Count()); }
/// <summary> /// Creates an async consumer queue that uses a task scheduler /// </summary> /// <param name="queueConnection">Queue and connection information.</param> /// <param name="factory">The task factory.</param> /// <returns></returns> public IConsumerMethodQueueScheduler CreateConsumerMethodQueueScheduler(QueueConnection queueConnection, ITaskFactory factory) { Guard.NotNull(() => queueConnection, queueConnection); return(CreateConsumerMethodQueueSchedulerInternal(queueConnection, factory, null, false)); }
/// <summary> /// Creates the consumer method queue scheduler. /// </summary> /// <param name="queueConnection">Queue and connection information.</param> /// <param name="factory">The factory.</param> /// <param name="workGroup">The work group.</param> /// <param name="internalFactory">if set to <c>true</c> [internal factory].</param> /// <returns></returns> private IConsumerMethodQueueScheduler CreateConsumerMethodQueueSchedulerInternal(QueueConnection queueConnection, ITaskFactory factory, IWorkGroup workGroup, bool internalFactory) { Guard.NotNull(() => queueConnection, queueConnection); IContainer container; if (internalFactory) //we own factory { if (workGroup == null) { container = _createContainerInternal() .Create(QueueContexts.ConsumerMethodQueueScheduler, _registerService, queueConnection, _transportInit, ConnectionTypes.Receive, serviceRegister => serviceRegister.Register(() => factory, LifeStyles.Singleton) .Register <IWorkGroup>(() => new WorkGroupNoOp(), LifeStyles.Singleton) .Register(() => factory.Scheduler, LifeStyles.Singleton), _setOptions); } else { container = _createContainerInternal() .Create(QueueContexts.ConsumerMethodQueueScheduler, _registerService, queueConnection, _transportInit, ConnectionTypes.Receive, serviceRegister => serviceRegister.Register(() => factory, LifeStyles.Singleton) .Register(() => workGroup, LifeStyles.Singleton) .Register(() => factory.Scheduler, LifeStyles.Singleton), _setOptions); } } else //someone else owns factory { if (workGroup == null) { container = _createContainerInternal() .Create(QueueContexts.ConsumerMethodQueueScheduler, _registerService, queueConnection, _transportInit, ConnectionTypes.Receive, serviceRegister => serviceRegister.RegisterNonScopedSingleton(factory) .Register <IWorkGroup>(() => new WorkGroupNoOp(), LifeStyles.Singleton) .RegisterNonScopedSingleton(factory.Scheduler), _setOptions); } else { container = _createContainerInternal() .Create(QueueContexts.ConsumerMethodQueueScheduler, _registerService, queueConnection, _transportInit, ConnectionTypes.Receive, serviceRegister => serviceRegister.RegisterNonScopedSingleton(factory) .Register(() => workGroup, LifeStyles.Singleton) .RegisterNonScopedSingleton(factory.Scheduler), _setOptions); } } Containers.Add(container); return(container.GetInstance <IConsumerMethodQueueScheduler>()); }
/// <inheritdoc /> public override void RegisterImplementations(IContainer container, RegistrationTypes registrationType, QueueConnection queueConnection) { Guard.NotNull(() => container, container); base.RegisterImplementations(container, registrationType, queueConnection); var init = new RelationalDatabaseMessageQueueInit <long, Guid>(); init.RegisterStandardImplementations(container, Assembly.GetAssembly(GetType())); //**all container.Register <IDbConnectionFactory, DbConnectionFactory>(LifeStyles.Singleton); container.Register <PostgreSqlMessageQueueSchema>(LifeStyles.Singleton); container.Register <IQueueCreation, PostgreSqlMessageQueueCreation>(LifeStyles.Singleton); container.Register <IJobSchedulerLastKnownEvent, PostgreSqlJobSchedulerLastKnownEvent>(LifeStyles.Singleton); container.Register <IOptionsSerialization, OptionsSerialization>(LifeStyles.Singleton); container.Register <PostgreSqlJobSchema>(LifeStyles.Singleton); container.Register <ISendJobToQueue, PostgreSqlSendJobToQueue>(LifeStyles.Singleton); container.Register <CommandStringCache, PostgreSqlCommandStringCache>(LifeStyles.Singleton); container.Register <IJobSchema, PostgreSqlJobSchema>(LifeStyles.Singleton); container.Register <IReadColumn, ReadColumn>(LifeStyles.Singleton); container.Register <ITransportOptionsFactory, TransportOptionsFactory>(LifeStyles.Singleton); container.Register <IGetPreviousMessageErrors, GetPreviousMessageErrors <long> >(LifeStyles.Singleton); container.Register <IRemoveMessage, RemoveMessage>(LifeStyles.Singleton); container.Register <IGetTime, PostgreSqlTime>(LifeStyles.Singleton); container.Register <IGetFirstMessageDeliveryTime, GetFirstMessageDeliveryTime>(LifeStyles.Singleton); container .Register <IPostgreSqlMessageQueueTransportOptionsFactory, PostgreSqlMessageQueueTransportOptionsFactory>( LifeStyles.Singleton); container.Register <PostgreSqlCommandStringCache>(LifeStyles.Singleton); container.Register <IConnectionInformation>(() => new SqlConnectionInformation(queueConnection), LifeStyles.Singleton); container.Register <PostgreSqlMessageQueueTransportOptions>(LifeStyles.Singleton); container.Register <IConnectionHeader <NpgsqlConnection, NpgsqlTransaction, NpgsqlCommand>, ConnectionHeader <NpgsqlConnection, NpgsqlTransaction, NpgsqlCommand> >(LifeStyles.Singleton); //**all //**receive container.Register <IReceiveMessages, PostgreSqlMessageQueueReceive>(LifeStyles.Transient); container.Register <IConnectionHolderFactory <NpgsqlConnection, NpgsqlTransaction, NpgsqlCommand>, ConnectionHolderFactory>(LifeStyles.Singleton); container.Register <ITransportRollbackMessage, RollbackMessage>(LifeStyles.Singleton); container.Register <ReceiveMessage>(LifeStyles.Transient); container.Register <IBuildMoveToErrorQueueSql, BuildMoveToErrorQueueSql>(LifeStyles.Singleton); //**receive //reset heart beat container .Register <IPrepareCommandHandler <ResetHeartBeatCommand <long> >, ResetHeartBeatCommandPrepareHandler>(LifeStyles.Singleton); //delete table - need lower case container .Register <IPrepareCommandHandler <DeleteTableCommand>, DeleteTableCommandPrepareHandler>(LifeStyles.Singleton); //explicit registration of our job exists query container .Register <IQueryHandler <DoesJobExistQuery <NpgsqlConnection, NpgsqlTransaction>, QueueStatuses>, DoesJobExistQueryHandler <NpgsqlConnection, NpgsqlTransaction> >(LifeStyles.Singleton); //because we have an explicit registration for job exists, we need to explicitly register the prepare statement container .Register <IPrepareQueryHandler <DoesJobExistQuery <NpgsqlConnection, NpgsqlTransaction>, QueueStatuses>, DoesJobExistQueryPrepareHandler <NpgsqlConnection, NpgsqlTransaction> >(LifeStyles.Singleton); //expired messages container .Register <IPrepareQueryHandler <FindExpiredMessagesToDeleteQuery <long>, IEnumerable <long> >, FindExpiredRecordsToDeleteQueryPrepareHandler>(LifeStyles.Singleton); //error messages container .Register <IPrepareQueryHandler <FindErrorMessagesToDeleteQuery <long>, IEnumerable <long> >, FindErrorRecordsToDeleteQueryPrepareHandler>(LifeStyles.Singleton); //heartbeat container .Register <IPrepareQueryHandler <FindMessagesToResetByHeartBeatQuery <long>, IEnumerable <MessageToReset <long> > >, FindRecordsToResetByHeartBeatQueryPrepareHandler>(LifeStyles.Singleton); container .Register <ICommandHandlerWithOutput <DeleteTransactionalMessageCommand, long>, DeleteTransactionalMessageCommandHandler <NpgsqlConnection, NpgsqlTransaction, NpgsqlCommand> >(LifeStyles.Singleton); container .Register <ICommandHandler <MoveRecordToErrorQueueCommand <long> >, MoveRecordToErrorQueueCommandHandler <NpgsqlConnection, NpgsqlTransaction, NpgsqlCommand> >(LifeStyles.Singleton); //explicit registration of options container .Register <IQueryHandler <GetQueueOptionsQuery <PostgreSqlMessageQueueTransportOptions>, PostgreSqlMessageQueueTransportOptions>, GetQueueOptionsQueryHandler <PostgreSqlMessageQueueTransportOptions> >(LifeStyles.Singleton); container .Register <IPrepareQueryHandler <GetQueueOptionsQuery <PostgreSqlMessageQueueTransportOptions>, PostgreSqlMessageQueueTransportOptions>, GetQueueOptionsQueryPrepareHandler <PostgreSqlMessageQueueTransportOptions> >(LifeStyles.Singleton); container.RegisterDecorator(typeof(IPrepareQueryHandler <GetColumnNamesFromTableQuery, List <string> >), typeof(GetColumnNamesFromTableQueryPrepareDecorator), LifeStyles.Singleton); container.RegisterDecorator(typeof(IPrepareQueryHandler <GetTableExistsQuery, bool>), typeof(GetTableExistsQueryPrepareDecorator), LifeStyles.Singleton); container.RegisterDecorator(typeof(IPrepareQueryHandler <GetTableExistsTransactionQuery, bool>), typeof(GetTableExistsTransactionQueryPrepareDecorator), LifeStyles.Singleton); container.RegisterDecorator(typeof(ICommandHandlerWithOutput <,>), typeof(RetryCommandHandlerOutputDecorator <,>), LifeStyles.Singleton); container.RegisterDecorator(typeof(ICommandHandler <>), typeof(RetryCommandHandlerDecorator <>), LifeStyles.Singleton); container.RegisterDecorator(typeof(ICommandHandlerWithOutputAsync <,>), typeof(RetryCommandHandlerOutputDecoratorAsync <,>), LifeStyles.Singleton); container.RegisterDecorator(typeof(IQueryHandler <,>), typeof(RetryQueryHandlerDecorator <,>), LifeStyles.Singleton); //register our decorator that handles table creation errors container.RegisterDecorator( typeof(ICommandHandlerWithOutput <CreateJobTablesCommand <ITable>, QueueCreationResult>), typeof(CreateJobTablesCommandDecorator), LifeStyles.Singleton); //register our decorator that handles table creation errors container.RegisterDecorator( typeof(ICommandHandlerWithOutput <CreateQueueTablesAndSaveConfigurationCommand <ITable>, QueueCreationResult>), typeof(CreateQueueTablesAndSaveConfigurationDecorator), LifeStyles.Singleton); //trace fallback command container.RegisterDecorator( typeof(ICommandHandler <RollbackMessageCommand <long> >), typeof(DotNetWorkQueue.Transport.PostgreSQL.Trace.Decorator.RollbackMessageCommandHandlerDecorator), LifeStyles.Singleton); //trace sending a message so that we can add specific tags container.RegisterDecorator( typeof(ICommandHandlerWithOutput <SendMessageCommand, long>), typeof(DotNetWorkQueue.Transport.PostgreSQL.Trace.Decorator.SendMessageCommandHandlerDecorator), LifeStyles.Singleton); container.RegisterDecorator( typeof(ICommandHandlerWithOutputAsync <SendMessageCommand, long>), typeof(DotNetWorkQueue.Transport.PostgreSQL.Trace.Decorator.SendMessageCommandHandlerAsyncDecorator), LifeStyles.Singleton); }
public void IsQueueAutoScaler() { var count = Substitute.For<IQueueCount>(); var setup = new QueueConnection<object>(); Assert.IsNotNull(new StorageQueueAutoScaler<object>(count, setup) as QueueAutoScaler<IQueueConnection<object>>); }
/// <inheritdoc /> public SqliteConnectionInformation(QueueConnection queueConnection, IDbDataSource dataSource) : base(queueConnection) { _dataSource = dataSource; ValidateConnection(queueConnection.Connection); }
public VerifyErrorCounts(QueueConnection queueConnection) { _connection = new SqlConnectionInformation(queueConnection); _tableNameHelper = new SqlServerTableNameHelper(_connection); }
static void Main(string[] args) { //we are using serilog for sample purposes var log = new LoggerConfiguration() .WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] [{SourceContext}] {Message:lj}{NewLine}{Exception}") .MinimumLevel.Debug() .CreateLogger(); Log.Logger = log; log.Information("Startup"); log.Information(SharedConfiguration.AllSettings); var queueName = ConfigurationManager.AppSettings.ReadSetting("QueueName"); var connectionString = ConfigurationManager.AppSettings.ReadSetting("Database"); var queueConnection = new QueueConnection(queueName, connectionString); //create the container for creating a new queue using (var createQueueContainer = new QueueCreationContainer <SqlServerMessageQueueInit>(serviceRegister => Injectors.AddInjectors(Helpers.CreateForSerilog(), SharedConfiguration.EnableTrace, SharedConfiguration.EnableMetrics, SharedConfiguration.EnableCompression, SharedConfiguration.EnableEncryption, "SQLServerProducer", serviceRegister), options => Injectors.SetOptions(options, SharedConfiguration.EnableChaos))) { using (var createQueue = createQueueContainer.GetQueueCreation <SqlServerMessageQueueCreation>(queueConnection)) { var enabledUserColumns = ConfigurationManager.AppSettings.ReadSetting("UseUserDequeue"); if (bool.Parse(enabledUserColumns)) { _userData = true; } //Create the queue if it doesn't exist if (!createQueue.QueueExists) { //queue options createQueue.Options.EnableDelayedProcessing = true; createQueue.Options.EnableHeartBeat = true; createQueue.Options.EnableMessageExpiration = true; createQueue.Options.EnableStatus = true; createQueue.Options.EnableStatusTable = true; if (!string.IsNullOrEmpty(enabledUserColumns) && bool.Parse(enabledUserColumns)) { createQueue.Options.AdditionalColumnsOnMetaData = true; createQueue.Options.AdditionalColumns.Add(new Column("DayOfWeek", ColumnTypes.Int, true, null)); } var result = createQueue.CreateQueue(); log.Information(result.Status.ToString()); } else { log.Warning("Queue already exists; not creating; note that any setting changes won't be applied"); } } } //create the producer using (var queueContainer = new QueueContainer <SqlServerMessageQueueInit>(serviceRegister => Injectors.AddInjectors(Helpers.CreateForSerilog(), SharedConfiguration.EnableTrace, SharedConfiguration.EnableMetrics, SharedConfiguration.EnableCompression, SharedConfiguration.EnableEncryption, "SQLServerProducer", serviceRegister) , options => Injectors.SetOptions(options, SharedConfiguration.EnableChaos))) { using (var queue = queueContainer.CreateProducer <SimpleMessage>(queueConnection)) { RunProducer.RunLoop(queue, ExpiredData, ExpiredDataFuture, DelayedProcessing); } } //if jaeger is using udp, sometimes the messages get lost; there doesn't seem to be a flush() call ? if (SharedConfiguration.EnableTrace) { System.Threading.Thread.Sleep(2000); } }
/// <summary> /// Initializes a new instance of the <see cref="SqlConnectionInformation"/> class. /// </summary> /// <param name="queueConnection">Queue and connection information.</param> public SqlConnectionInformation(QueueConnection queueConnection) : base(queueConnection) { ValidateConnection(queueConnection.Connection); }
/// <summary> /// Registers the implementations. /// </summary> /// <param name="container">The container.</param> /// <param name="registrationType">Type of the registration.</param> /// <param name="queueConnection">Queue and connection information.</param> public override void RegisterImplementations(IContainer container, RegistrationTypes registrationType, QueueConnection queueConnection) { Guard.NotNull(() => container, container); base.RegisterImplementations(container, registrationType, queueConnection); var init = new RelationalDatabaseMessageQueueInit <long, Guid>(); init.RegisterStandardImplementations(container, Assembly.GetAssembly(GetType())); //override so that we can use schema as needed container.Register <ITableNameHelper, SqlServerTableNameHelper>(LifeStyles.Singleton); //**all container.Register <IDbConnectionFactory, DbConnectionFactory>(LifeStyles.Singleton); container.Register <SqlServerMessageQueueSchema>(LifeStyles.Singleton); container.Register <IQueueCreation, SqlServerMessageQueueCreation>(LifeStyles.Singleton); container.Register <IJobSchedulerLastKnownEvent, SqlServerJobSchedulerLastKnownEvent>(LifeStyles.Singleton); container.Register <SqlServerJobSchema>(LifeStyles.Singleton); container.Register <ISendJobToQueue, SqlServerSendJobToQueue>(LifeStyles.Singleton); container.Register <CommandStringCache, SqlServerCommandStringCache>(LifeStyles.Singleton); container.Register <IOptionsSerialization, OptionsSerialization>(LifeStyles.Singleton); container.Register <IJobSchema, SqlServerJobSchema>(LifeStyles.Singleton); container.Register <IReadColumn, ReadColumn>(LifeStyles.Singleton); container.Register <IBuildMoveToErrorQueueSql, BuildMoveToErrorQueueSql>(LifeStyles.Singleton); container.Register <ITransportOptionsFactory, TransportOptionsFactory>(LifeStyles.Singleton); container.Register <IRemoveMessage, RemoveMessage>(LifeStyles.Singleton); container.Register <IGetPreviousMessageErrors, GetPreviousMessageErrors <long> >(LifeStyles.Singleton); container.Register <ISqlSchema, SqlSchema>(LifeStyles.Singleton); container.Register <IGetTime, SqlServerTime>(LifeStyles.Singleton); container.Register <IGetFirstMessageDeliveryTime, GetFirstMessageDeliveryTime>(LifeStyles.Singleton); container .Register <ISqlServerMessageQueueTransportOptionsFactory, SqlServerMessageQueueTransportOptionsFactory>( LifeStyles.Singleton); container.Register <ICreationScope, CreationScopeNoOp>(LifeStyles.Singleton); container.Register <SqlServerCommandStringCache>(LifeStyles.Singleton); container.Register <IConnectionInformation>(() => new SqlConnectionInformation(queueConnection), LifeStyles.Singleton); container.Register <SqlServerMessageQueueTransportOptions>(LifeStyles.Singleton); container.Register <IConnectionHeader <SqlConnection, SqlTransaction, SqlCommand>, ConnectionHeader <SqlConnection, SqlTransaction, SqlCommand> >(LifeStyles.Singleton); //**all //**receive container.Register <IReceiveMessages, SqlServerMessageQueueReceive>(LifeStyles.Transient); container.Register <IConnectionHolderFactory <SqlConnection, SqlTransaction, SqlCommand>, ConnectionHolderFactory>(LifeStyles.Singleton); container.Register <ITransportRollbackMessage, RollbackMessage>(LifeStyles.Singleton); container.Register <ReceiveMessage>(LifeStyles.Transient); container.Register <CreateDequeueStatement>(LifeStyles.Singleton); container.Register <BuildDequeueCommand>(LifeStyles.Singleton); container.Register <ReadMessage>(LifeStyles.Singleton); //**receive //explicit registration of our job exists query container .Register <IQueryHandler <DoesJobExistQuery <SqlConnection, SqlTransaction>, QueueStatuses>, DoesJobExistQueryHandler <SqlConnection, SqlTransaction> >(LifeStyles.Singleton); //because we have an explicit registration for job exists, we need to explicitly register the prepare statement container .Register <IPrepareQueryHandler <DoesJobExistQuery <SqlConnection, SqlTransaction>, QueueStatuses>, DoesJobExistQueryPrepareHandler <SqlConnection, SqlTransaction> >(LifeStyles.Singleton); container .Register <ICommandHandlerWithOutput <SendHeartBeatCommand <long>, DateTime?>, SendHeartBeatCommandHandler>(LifeStyles.Singleton); container .Register <ICommandHandler <MoveRecordToErrorQueueCommand <long> >, MoveRecordToErrorQueueCommandHandler <SqlConnection, SqlTransaction, SqlCommand> >(LifeStyles.Singleton); //explicit registration of options container .Register <IQueryHandler <GetQueueOptionsQuery <SqlServerMessageQueueTransportOptions>, SqlServerMessageQueueTransportOptions>, GetQueueOptionsQueryHandler <SqlServerMessageQueueTransportOptions> >(LifeStyles.Singleton); container .Register <ICommandHandlerWithOutput <DeleteTransactionalMessageCommand, long>, DeleteTransactionalMessageCommandHandler <SqlConnection, SqlTransaction, SqlCommand> >(LifeStyles.Singleton); container .Register <IPrepareQueryHandler <GetQueueOptionsQuery <SqlServerMessageQueueTransportOptions>, SqlServerMessageQueueTransportOptions>, GetQueueOptionsQueryPrepareHandler <SqlServerMessageQueueTransportOptions> >(LifeStyles.Singleton); container.RegisterDecorator(typeof(ICommandHandlerWithOutput <,>), typeof(RetryCommandHandlerOutputDecorator <,>), LifeStyles.Singleton); container.RegisterDecorator(typeof(ICommandHandler <>), typeof(RetryCommandHandlerDecorator <>), LifeStyles.Singleton); container.RegisterDecorator(typeof(ICommandHandlerWithOutputAsync <,>), typeof(RetryCommandHandlerOutputDecoratorAsync <,>), LifeStyles.Singleton); container.RegisterDecorator(typeof(IQueryHandler <,>), typeof(RetryQueryHandlerDecorator <,>), LifeStyles.Singleton); //register our decorator that handles table creation errors container.RegisterDecorator( typeof(ICommandHandlerWithOutput <CreateJobTablesCommand <ITable>, QueueCreationResult>), typeof(CreateJobTablesCommandDecorator), LifeStyles.Singleton); //register our decorator that handles table creation errors container.RegisterDecorator( typeof(ICommandHandlerWithOutput <CreateQueueTablesAndSaveConfigurationCommand <ITable>, QueueCreationResult>), typeof(CreateQueueTablesAndSaveConfigurationDecorator), LifeStyles.Singleton); //trace fallback command container.RegisterDecorator( typeof(ICommandHandler <RollbackMessageCommand <long> >), typeof(DotNetWorkQueue.Transport.SqlServer.Trace.Decorator.RollbackMessageCommandHandlerDecorator), LifeStyles.Singleton); //trace sending a message so that we can add specific tags container.RegisterDecorator( typeof(ICommandHandlerWithOutput <SendMessageCommand, long>), typeof(DotNetWorkQueue.Transport.SqlServer.Trace.Decorator.SendMessageCommandHandlerDecorator), LifeStyles.Singleton); container.RegisterDecorator( typeof(ICommandHandlerWithOutputAsync <SendMessageCommand, long>), typeof(DotNetWorkQueue.Transport.SqlServer.Trace.Decorator.SendMessageCommandHandlerAsyncDecorator), LifeStyles.Singleton); //query exists custom handler for SQL server container .Register <IPrepareQueryHandler <GetTableExistsQuery, bool>, DotNetWorkQueue.Transport.SqlServer.Basic.QueryPrepareHandler.GetTableExistsQueryPrepareHandler>(LifeStyles.Singleton); //query exists custom handler for SQL server container .Register <IPrepareQueryHandler <GetTableExistsTransactionQuery, bool>, DotNetWorkQueue.Transport.SqlServer.Basic.QueryPrepareHandler.GetTableExistsTransactionQueryPrepareHandler>(LifeStyles.Singleton); }
/// <summary> /// Gets the specified queue. /// </summary> /// <typeparam name="TTransportInit">The type of the transport initialize.</typeparam> /// <param name="jobQueueCreation">The job queue creation.</param> /// <param name="queueConnection">Queue and connection information.</param> /// <param name="producerConfiguration">The producer configuration.</param> /// <returns></returns> /// <exception cref="DotNetWorkQueueException">Failed to create the queue. The error message is {createResult.ErrorMessage}</exception> public IProducerMethodJobQueue Get <TTransportInit>(IJobQueueCreation jobQueueCreation, QueueConnection queueConnection, Action <QueueProducerConfiguration> producerConfiguration = null) where TTransportInit : ITransportInit, new() { var connectionInfo = new BaseConnectionInformation(queueConnection); if (_queues.ContainsKey(connectionInfo)) { return(_queues[connectionInfo]); } var transportName = typeof(TTransportInit).ToString(); if (!_containers.ContainsKey(transportName)) { var container = new QueueContainer <TTransportInit>(_registrations.QueueRegistrations, _registrations.QueueOptions); if (!_containers.TryAdd(transportName, container)) { container.Dispose(); } } if (!_queues.ContainsKey(connectionInfo)) { var createResult = jobQueueCreation.CreateJobSchedulerQueue(_registrations.QueueCreationRegistrations, queueConnection, _registrations.QueueCreationOptions); if (createResult.Success) { var scope = jobQueueCreation.Scope; var queue = _containers[transportName].CreateMethodJobProducer(queueConnection); producerConfiguration?.Invoke(queue.Configuration); if (!_queues.TryAdd(connectionInfo, queue)) { queue.Dispose(); scope.Dispose(); } else { queue.Start(); _creationScopes.TryAdd(connectionInfo, scope); } } else { throw new DotNetWorkQueueException($"Failed to create the queue. The error message is {createResult.ErrorMessage}"); } } return(_queues[connectionInfo]); }
/// <inheritdoc /> public QueueCreationResult CreateJobSchedulerQueue(Action <IContainer> registerService, QueueConnection queueConnection, Action <IContainer> setOptions = null, bool enableRoute = false) { if (enableRoute) { _queueCreation.Options.EnableRoute = true; } return(_queueCreation.CreateQueue()); }
public static void VerifyQueueCount(QueueConnection queueConnection, IBaseTransportOptions arg3, ICreationScope arg4, int arg5, bool arg6, bool arg7) { new VerifyQueueRecordCount(queueConnection.Queue, queueConnection.Connection, (SqLiteMessageQueueTransportOptions)arg3).Verify(arg5, arg6, arg7); }
/// <summary> /// Allows a transport to register its dependencies in the IoC container. /// </summary> /// <param name="container">The container.</param> /// <param name="registrationType">Type of the registration.</param> /// <param name="queueConnection">Queue and connection information.</param> public override void RegisterImplementations(IContainer container, RegistrationTypes registrationType, QueueConnection queueConnection) { container.Register <IConnectionInformation>(() => new BaseConnectionInformation(queueConnection), LifeStyles.Singleton); container.Register <IInternalSerializer, JsonSerializerInternal>(LifeStyles.Singleton); container.Register <IWorkerNotificationFactory, WorkerNotificationFactoryNoOp>(LifeStyles.Singleton); container.Register <IJobScheduler, JobScheduler>(LifeStyles.Singleton); container.Register <IJobQueue, JobQueue>(LifeStyles.Singleton); }
public static void Verify(QueueConnection queueConnection, QueueProducerConfiguration queueProducerConfiguration, long messageCount, string route, ICreationScope scope) { new VerifyQueueData(queueConnection, queueProducerConfiguration.Options()).Verify(messageCount, route); }
private void VerifyRoutes(Action <QueueConnection, QueueProducerConfiguration, long, string, ICreationScope> verify, QueueConnection arg1, QueueProducerConfiguration arg3, long arg4, string route, ICreationScope scope) { verify(arg1, arg3, arg4, route, scope); }
static void Main(string[] args) { //we are using serilog for sample purposes var log = new LoggerConfiguration() .WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] [{SourceContext}] {Message:lj}{NewLine}{Exception}") .MinimumLevel.Debug() .CreateLogger(); Log.Logger = log; log.Information("Startup"); log.Information(SharedConfiguration.AllSettings); //verify that the queue exists var queueName = ConfigurationManager.AppSettings.ReadSetting("QueueName"); var connectionString = ConfigurationManager.AppSettings.ReadSetting("Database"); var queueConnection = new QueueConnection(queueName, connectionString); using (var createQueueContainer = new QueueCreationContainer <PostgreSqlMessageQueueInit>(serviceRegister => Injectors.AddInjectors(Helpers.CreateForSerilog(), SharedConfiguration.EnableTrace, SharedConfiguration.EnableMetrics, SharedConfiguration.EnableCompression, SharedConfiguration.EnableEncryption, "PostgreSqlConsumer", serviceRegister) , options => Injectors.SetOptions(options, SharedConfiguration.EnableChaos))) { using (var createQueue = createQueueContainer.GetQueueCreation <PostgreSqlMessageQueueCreation>(queueConnection)) { if (!createQueue.QueueExists) { //the consumer can't do anything if the queue hasn't been created Log.Error($"Could not find {connectionString}. Verify that you have run the producer, which will create the queue"); return; } } } using (var queueContainer = new QueueContainer <PostgreSqlMessageQueueInit>(serviceRegister => Injectors.AddInjectors(Helpers.CreateForSerilog(), SharedConfiguration.EnableTrace, SharedConfiguration.EnableMetrics, SharedConfiguration.EnableCompression, SharedConfiguration.EnableEncryption, "PostgreSqlConsumer", serviceRegister) , options => Injectors.SetOptions(options, SharedConfiguration.EnableChaos))) { using (var queue = queueContainer.CreateConsumer(queueConnection)) { //set some processing options and start looking for work queue.Configuration.Worker.WorkerCount = 4; //lets run 4 worker threads queue.Configuration.HeartBeat.UpdateTime = "sec(*%10)"; //set a heartbeat every 10 seconds queue.Configuration.HeartBeat.MonitorTime = TimeSpan.FromSeconds(15); //check for dead records every 15 seconds queue.Configuration.HeartBeat.Time = TimeSpan.FromSeconds(35); //records with no heartbeat after 35 seconds are considered dead //an invalid data exception will be re-tried 3 times, with delays of 3, 6 and then finally 9 seconds queue.Configuration.TransportConfiguration.RetryDelayBehavior.Add(typeof(InvalidDataException), new List <TimeSpan> { TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(6), TimeSpan.FromSeconds(9) }); queue.Configuration.MessageExpiration.Enabled = true; queue.Configuration.MessageExpiration.MonitorTime = TimeSpan.FromSeconds(20); //check for expired messages every 20 seconds queue.Start <SimpleMessage>(MessageProcessing.HandleMessages); Console.WriteLine("Processing messages - press any key to stop"); Console.ReadKey((true)); } } //if jaeger is using udp, sometimes the messages get lost; there doesn't seem to be a flush() call ? if (SharedConfiguration.EnableTrace) { System.Threading.Thread.Sleep(2000); } }
public void RunTest <TTransportInit, TMessage>(QueueConnection queueConnection, bool addInterceptors, int messageCount, ILogger logProvider, Func <QueueProducerConfiguration, AdditionalMessageData> generateData, Action <QueueConnection, QueueProducerConfiguration, long, string, ICreationScope> verify, bool sendViaBatch, List <string> routes1, List <string> routes2, int runTime, int timeOut, int readerCount, TimeSpan heartBeatTime, TimeSpan heartBeatMonitorTime, ICreationScope scope, string updateTime, bool enableChaos) where TTransportInit : ITransportInit, new() where TMessage : class { //add data with routes - generate data per route passed in Parallel.ForEach(routes1, route => { RunTest <TTransportInit, TMessage>(queueConnection, addInterceptors, messageCount, logProvider, generateData, verify, sendViaBatch, route, scope, false); }); Parallel.ForEach(routes2, route => { RunTest <TTransportInit, TMessage>(queueConnection, addInterceptors, messageCount, logProvider, generateData, verify, sendViaBatch, route, scope, false); }); //run a consumer for each route using (var schedulerCreator = new SchedulerContainer()) { var taskScheduler = schedulerCreator.CreateTaskScheduler(); taskScheduler.Configuration.MaximumThreads = routes1.Count + routes2.Count; taskScheduler.Start(); var taskFactory = schedulerCreator.CreateTaskFactory(taskScheduler); //spin up and process each route var running = new List <List <string> > { routes1, routes2 }; Parallel.ForEach(running, route => { foreach (var route2 in route) { var consumer = new ConsumerAsyncShared <TMessage> { Factory = taskFactory }; consumer.RunConsumer <TTransportInit>(queueConnection, addInterceptors, logProvider, runTime, messageCount, timeOut, readerCount, heartBeatTime, heartBeatMonitorTime, updateTime, enableChaos, scope, route2); } }); } }
/// <summary> /// Creates an async consumer queue that uses a task scheduler /// </summary> /// <param name="queueConnection">Queue and connection information.</param> /// <param name="factory">The task factory.</param> /// <param name="workGroup">The work group.</param> /// <returns></returns> public IConsumerQueueScheduler CreateConsumerQueueScheduler(QueueConnection queueConnection, ITaskFactory factory, IWorkGroup workGroup) { Guard.NotNull(() => queueConnection, queueConnection); return(CreateConsumerQueueSchedulerInternal(queueConnection, factory, workGroup, false)); }
/// <inheritdoc /> public QueueCreationResult CreateJobSchedulerQueue(Action <IContainer> registerService, QueueConnection queueConnection, Action <IContainer> setOptions = null, bool enableRoute = false) { if (_queueCreation.Options.AdditionalColumns.Count == 0) { _queueCreation.Options.AdditionalColumns.Add(new Column("JobName", ColumnTypes.Varchar, 255, false)); var constraint = new Constraint($"IX_{queueConnection.Queue}JobName", ConstraintType.Constraint, "JobName") { Unique = true }; _queueCreation.Options.AdditionalConstraints.Add(constraint); } if (enableRoute) { _queueCreation.Options.EnableRoute = true; } return(_queueCreation.CreateQueue()); }
void RunConsumer <TTransportInit>(QueueConnection queueConnection, bool addInterceptors, ILogger logProvider, int runTime, int messageCount, int timeOut, int readerCount, TimeSpan heartBeatTime, TimeSpan heartBeatMonitorTime, Guid id, string updateTime, bool enableChaos, ICreationScope scope) where TTransportInit : ITransportInit, new() { if (enableChaos) { timeOut *= 2; } using (var trace = SharedSetup.CreateTrace("consumer")) { using (var metrics = new Metrics.Metrics(queueConnection.Queue)) { var addInterceptorConsumer = InterceptorAdding.No; if (addInterceptors) { addInterceptorConsumer = InterceptorAdding.ConfigurationOnly; } using ( var creator = SharedSetup.CreateCreator <TTransportInit>(addInterceptorConsumer, logProvider, metrics, false, enableChaos, scope, trace.Source) ) { using ( var queue = creator .CreateConsumerMethodQueueScheduler( queueConnection, Factory)) { SharedSetup.SetupDefaultConsumerQueue(queue.Configuration, readerCount, heartBeatTime, heartBeatMonitorTime, updateTime, null); queue.Start(); var counter = 0; while (counter < timeOut) { if (MethodIncrementWrapper.Count(id) >= messageCount) { break; } Thread.Sleep(1000); counter++; } } Assert.Equal(messageCount, MethodIncrementWrapper.Count(id)); VerifyMetrics.VerifyProcessedCount(queueConnection.Queue, metrics.GetCurrentMetrics(), messageCount); LoggerShared.CheckForErrors(queueConnection.Queue); } } } }
private void ValidateErrorCounts(QueueConnection queueConnection, int arg3, ICreationScope arg4) { new VerifyErrorCounts(queueConnection.Queue).Verify(arg3, 2); }
private void VerifyQueueCount(QueueConnection queueConnection, IBaseTransportOptions arg3, ICreationScope arg4, int arg5, bool arg6, bool arg7) { new VerifyQueueRecordCount().Verify(arg4, 0, true); }
public void Constructor() { var count = Substitute.For<IQueueCount>(); var setup = new QueueConnection<object>(); new StorageQueueAutoScaler<object>(count, setup); }