Exemple #1
0
 private static PushQueueItem Dequeue(string messageQueuePath)
 {
     using (var messageQueue = new SqliteMessageQueue(messageQueuePath))
     {
         return(TransactionalDequeue <PushQueueItem>(messageQueue, timeoutMs: 60 * 1000));
     }
 }
        public void SqliteTransactionTests1()
        {
            string messageQueuePath = $@".\Private$\{Guid.NewGuid().ToString()}";

            using (var messageQueue = new SqliteMessageQueue(messageQueuePath))
            {
                messageQueue.Clear();

                using (var queueTransaction1 = messageQueue.CreateQueueTransaction())
                {
                    var expected = CreateRandomQueueItem();

                    queueTransaction1.Begin();

                    messageQueue.Enqueue(expected, queueTransaction1);

                    var actual = messageQueue.DequeueNextMessage <PushQueueItem>(queueTransaction1);

                    AssertCompare(expected, actual);

                    Assert.ThrowsException <MessageQueueReadException>(() => messageQueue.DequeueNextMessage <PushQueueItem>(queueTransaction1));

                    queueTransaction1.Commit();
                }
            }
        }
Exemple #3
0
 private static void Enqueue(PushQueueItem queueItem, string messageQueuePath)
 {
     using (var messageQueue = new SqliteMessageQueue(messageQueuePath))
     {
         Enqueue(queueItem, messageQueue);
     }
 }
Exemple #4
0
        public void SqliteNestedTransactionTest()
        {
            var messageQueuePath = $@".\Private$\{Guid.NewGuid()}";

            using (var messageQueue = new SqliteMessageQueue(messageQueuePath))
            {
                messageQueue.Clear();

                using (var queueTransaction1 = messageQueue.CreateQueueTransaction())
                {
                    queueTransaction1.Begin();

                    using (var queueTransaction2 = messageQueue.CreateQueueTransaction())
                    {
                        queueTransaction2.Begin();
                        messageQueue.Enqueue(CreateRandomQueueItem(0), queueTransaction2);
                        queueTransaction2.Commit();
                    }

                    var queueItem = messageQueue.DequeueNextMessage <PushQueueItem>(queueTransaction1);
                    Assert.IsNotNull(queueItem);

                    queueTransaction1.Commit();
                }
            }
        }
Exemple #5
0
        public async Task SqliteRenewLeaseTests1()
        {
            var messageQueuePath = $@".\Private$\{Guid.NewGuid()}";

            const uint transactionLeaseMs = 1000;

            using (var messageQueue = new SqliteMessageQueue(messageQueuePath, transactionLeaseMs: transactionLeaseMs))
            {
                messageQueue.Clear();

                using (var queueTransaction1 = messageQueue.CreateQueueTransaction())
                {
                    var expected = CreateRandomQueueItem();

                    queueTransaction1.Begin();

                    messageQueue.Enqueue(expected, queueTransaction1);

                    // Dequeue the item to start the renew lease expiry
                    var dequeued = messageQueue.DequeueNextMessage <PushQueueItem>(queueTransaction1);

                    // Wait for twice the time - the lease should have expired if the renew code is not working
                    await Task.Delay(TimeSpan.FromMilliseconds(transactionLeaseMs * 2)).ConfigureAwait(false);

                    Assert.ThrowsException <MessageQueueReadException>(() => messageQueue.DequeueNextMessage <PushQueueItem>(queueTransaction1));
                }

                using (var queueTransaction = messageQueue.CreateQueueTransaction())
                {
                    queueTransaction.Begin();

                    Assert.ThrowsException <MessageQueueReadException>(() => messageQueue.DequeueNextMessage <PushQueueItem>(queueTransaction));
                }
            }
        }
Exemple #6
0
        public void SqliteTransactionDisposeTest1()
        {
            var messageQueuePath = $@".\Private$\{Guid.NewGuid()}";
            var expected         = CreateRandomQueueItem();

            using (var messageQueue = new SqliteMessageQueue(messageQueuePath))
            {
                messageQueue.Clear();

                // Enqueue the expected item
                TransactionalEnqueue(messageQueue, expected);

                using (var queueTransaction = messageQueue.CreateQueueTransaction())
                {
                    queueTransaction.Begin();

                    // Dequeue but don't call abort specifically - let the dispose method do this
                    var actual = messageQueue.DequeueNextMessage <PushQueueItem>(queueTransaction);

                    AssertCompare(expected, actual);
                }

                using (var queueTransaction = messageQueue.CreateQueueTransaction())
                {
                    queueTransaction.Begin();

                    var actual = messageQueue.DequeueNextMessage <PushQueueItem>(queueTransaction);

                    AssertCompare(expected, actual);

                    queueTransaction.Commit();
                }
            }
        }
Exemple #7
0
        public void SqliteTransactionTests2()
        {
            var messageQueuePath = $@".\Private$\{Guid.NewGuid()}";

            using (var messageQueue = new SqliteMessageQueue(messageQueuePath))
            {
                messageQueue.Clear();

                using (var queueTransaction1 = messageQueue.CreateQueueTransaction())
                {
                    var expected = CreateRandomQueueItem();

                    queueTransaction1.Begin();

                    messageQueue.Enqueue(expected, queueTransaction1);

                    using (var queueTransaction2 = messageQueue.CreateQueueTransaction())
                    {
                        queueTransaction2.Begin();

                        Assert.ThrowsException <MessageQueueReadException>(() => messageQueue.DequeueNextMessage <PushQueueItem>(queueTransaction2));
                    }

                    queueTransaction1.Abort();
                }
            }
        }
Exemple #8
0
 private static void Enqueue(PushQueueItem queueItem, SqliteMessageQueue messageQueue)
 {
     using (var queueTransaction = messageQueue.CreateQueueTransaction())
     {
         queueTransaction.Begin();
         messageQueue.Enqueue(queueItem, queueTransaction);
         queueTransaction.Commit();
     }
 }
Exemple #9
0
        public void SqliteTestConcurrentReadWrite4()
        {
            var       messageQueuePath = $@".\Private$\{Guid.NewGuid()}";
            const int numberMessages   = 10;

            using (var messageQueue = new SqliteMessageQueue(messageQueuePath))
            {
                messageQueue.Clear();
            }

            var expectedResults = new PushQueueItem[numberMessages];
            var actualResults   = new PushQueueItem[numberMessages];

            for (var i = 0; i < numberMessages; i++)
            {
                expectedResults[i] = CreateRandomQueueItem(i);
            }

            using (var messageQueue = new SqliteMessageQueue(messageQueuePath))
            {
                using (var messageQueueTransaction = messageQueue.CreateQueueTransaction())
                {
                    messageQueueTransaction.Begin();

                    Parallel.For(0, numberMessages * 2, i =>
                    {
                        if (i % 2 == 0)
                        {
                            messageQueue.Enqueue(expectedResults[i / 2], messageQueueTransaction);
                        }
                        else
                        {
                            var dequeueResult = TryDequeue <PushQueueItem>(messageQueue, messageQueueTransaction, timeoutMs: 120 * 1000);

                            if (actualResults[dequeueResult.DequeueCount] != null)
                            {
                                throw new ArgumentException("This item has already been dequeued. Something is wrong.");
                            }

                            actualResults[dequeueResult.DequeueCount] = dequeueResult;
                        }
                    });

                    messageQueueTransaction.Commit();
                }
            }

            for (var i = 0; i < numberMessages; i++)
            {
                AssertCompare(expectedResults[i], actualResults[i]);
            }
        }
Exemple #10
0
        public void SqliteTestDequeueOnly1()
        {
            var messageQueuePath = $@".\Private$\{Guid.NewGuid()}";

            using (var messageQueue = new SqliteMessageQueue(messageQueuePath))
                using (var queueTransaction = messageQueue.CreateQueueTransaction())
                {
                    queueTransaction.Begin();

                    Assert.ThrowsException <MessageQueueReadException>(() => messageQueue.DequeueNextMessage <PushQueueItem>(queueTransaction));

                    queueTransaction.Abort();
                }
        }
Exemple #11
0
        public void SqliteTestConcurrentReadWrite3()
        {
            var messageQueuePath = $@".\Private$\{Guid.NewGuid()}";

            const int numberThreads           = 4;
            const int numberMessagesPerThread = 10;
            const int numberMessages          = numberThreads * numberMessagesPerThread;

            using (var messageQueue = new SqliteMessageQueue(messageQueuePath))
            {
                messageQueue.Clear();
            }

            var expectedResults = new PushQueueItem[numberMessages];
            var actualResults   = new PushQueueItem[numberMessages];

            for (var i = 0; i < numberMessages; i++)
            {
                expectedResults[i] = CreateRandomQueueItem(i);
            }

            Parallel.For(0, numberThreads, i =>
            {
                for (var ii = 0; ii < numberMessagesPerThread * 2; ii++)
                {
                    // Switch between reading and writing
                    if (ii % 2 == 0)
                    {
                        Enqueue(expectedResults[(i * numberMessagesPerThread) + (ii / 2)], messageQueuePath);
                    }
                    else
                    {
                        var dequeueResult = Dequeue(messageQueuePath);

                        if (actualResults[dequeueResult.DequeueCount] != null)
                        {
                            throw new ArgumentException("This item has already been dequeued. Something is wrong.");
                        }

                        actualResults[dequeueResult.DequeueCount] = dequeueResult;
                    }
                }
            });

            for (var i = 0; i < numberMessages; i++)
            {
                AssertCompare(expectedResults[i], actualResults[i]);
            }
        }
Exemple #12
0
        public void SqliteTransactionExceptionTests2()
        {
            var messageQueuePath = $@".\Private$\{Guid.NewGuid()}";

            const uint transactionLeaseMs = 3000;

            using (var messageQueue = new SqliteMessageQueue(messageQueuePath, transactionLeaseMs: transactionLeaseMs))
            {
                var queueTransaction1 = messageQueue.CreateQueueTransaction();
                queueTransaction1.Dispose();

                Assert.ThrowsException <ObjectDisposedException>(() => queueTransaction1.Begin());
                Assert.ThrowsException <ObjectDisposedException>(() => queueTransaction1.Commit());
                Assert.ThrowsException <ObjectDisposedException>(() => queueTransaction1.Abort());
            }
        }
Exemple #13
0
        public async Task SqliteClearDuringTransaction1()
        {
            var messageQueuePath = $@".\Private$\{Guid.NewGuid()}";

            const uint transactionLeaseMs = 1000;

            using (var messageQueue = new SqliteMessageQueue(messageQueuePath, transactionLeaseMs: transactionLeaseMs))
            {
                messageQueue.Clear();

                var expected = CreateRandomQueueItem();

                // Also test Abort is called when disposing
                using (var transaction = messageQueue.CreateQueueTransaction())
                {
                    transaction.Begin();

                    messageQueue.Enqueue(expected, transaction);
                    var actual = messageQueue.DequeueNextMessage <PushQueueItem>(transaction);

                    messageQueue.Clear();

                    AssertCompare(expected, actual);

                    // Wait for the renew lease task to be called at least once.
                    await Task.Delay(TimeSpan.FromMilliseconds(transactionLeaseMs * 2)).ConfigureAwait(false);
                }

                using (var transaction = messageQueue.CreateQueueTransaction())
                {
                    transaction.Begin();

                    messageQueue.Enqueue(expected, transaction);
                    var actual = messageQueue.DequeueNextMessage <PushQueueItem>(transaction);

                    messageQueue.Clear();

                    AssertCompare(expected, actual);

                    // Wait for the renew lease task to be called at least once.
                    await Task.Delay(TimeSpan.FromMilliseconds(transactionLeaseMs * 2)).ConfigureAwait(false);

                    // Make sure no exception is thrown.
                    transaction.Commit();
                }
            }
        }
Exemple #14
0
        public void SqliteTransactionExceptionTests1()
        {
            var messageQueuePath = $@".\Private$\{Guid.NewGuid()}";

            const uint transactionLeaseMs = 3000;

            using (var messageQueue = new SqliteMessageQueue(messageQueuePath, transactionLeaseMs: transactionLeaseMs))
            {
                messageQueue.Clear();

                using (var queueTransaction1 = messageQueue.CreateQueueTransaction())
                {
                    Assert.ThrowsException <InvalidOperationException>(() => queueTransaction1.Commit());
                    Assert.ThrowsException <InvalidOperationException>(() => queueTransaction1.Abort());
                }
            }
        }
Exemple #15
0
        public void SqliteTestConcurrentReadWrite2()
        {
            var       messageQueuePath = $@".\Private$\{Guid.NewGuid()}";
            const int numberMessages   = 100;

            using (var messageQueue = new SqliteMessageQueue(messageQueuePath))
            {
                messageQueue.Clear();
            }

            var expectedResults = new PushQueueItem[numberMessages];
            var actualResults   = new PushQueueItem[numberMessages];

            for (var i = 0; i < numberMessages; i++)
            {
                expectedResults[i] = CreateRandomQueueItem(i);
            }

            Parallel.For(0, numberMessages * 2, i =>
            {
                if (i >= numberMessages)
                {
                    var dequeueResult = Dequeue(messageQueuePath);

                    if (actualResults[dequeueResult.DequeueCount] != null)
                    {
                        throw new ArgumentException("This item has already been dequeued. Something is wrong.");
                    }

                    actualResults[dequeueResult.DequeueCount] = dequeueResult;
                }
                else
                {
                    Enqueue(expectedResults[i], messageQueuePath);
                }
            });

            for (var i = 0; i < numberMessages; i++)
            {
                AssertCompare(expectedResults[i], actualResults[i]);
            }
        }
Exemple #16
0
        public async Task SqliteExpiredLeaseTests1()
        {
            var messageQueuePath = $@".\Private$\{Guid.NewGuid()}";

            const uint transactionLeaseMs = 1000;

            using (var messageQueue = new SqliteMessageQueue(messageQueuePath, transactionLeaseMs: transactionLeaseMs))
            {
                messageQueue.Clear();

                var expected = CreateRandomQueueItem();

                TransactionalEnqueue(messageQueue, expected);

                // Create a new transaction with the renew task larger than the time of the transaction lease (not a good idea in practice)
                using (var queueTransaction1 = new SqliteMessageQueueTransaction(messageQueue.DatabaseConnectionString, 60 * 1000))
                {
                    queueTransaction1.Begin();

                    // Dequeue the item to start the renew lease expiry
                    var actual1 = messageQueue.DequeueNextMessage <PushQueueItem>(queueTransaction1);

                    AssertCompare(expected, actual1);

                    // Wait for twice the time - the lease should have now expired
                    await Task.Delay(TimeSpan.FromMilliseconds(transactionLeaseMs * 2)).ConfigureAwait(false);

                    // Dequeue on a different transaction
                    var actual2 = TransactionalDequeue <PushQueueItem>(messageQueue);

                    // Check the item was recovered.
                    AssertCompare(expected, actual2);

                    queueTransaction1.Abort();
                }
            }
        }
Exemple #17
0
        public void SqliteTestEnqueueDequeue1()
        {
            var messageQueuePath = $@".\Private$\{Guid.NewGuid()}";

            var expectedItem1 = CreateRandomQueueItem(0);
            var expectedItem2 = CreateRandomQueueItem(1);

            using (var messageQueue = new SqliteMessageQueue(messageQueuePath))
                using (var queueTransaction = messageQueue.CreateQueueTransaction())
                {
                    // Clear the queue
                    messageQueue.Clear();

                    queueTransaction.Begin();
                    messageQueue.Enqueue(expectedItem1, queueTransaction);
                    messageQueue.Enqueue(expectedItem2, queueTransaction);
                    queueTransaction.Commit();
                }

            // Read from queue and then abort
            using (var messageQueue = new SqliteMessageQueue(messageQueuePath))
                using (var queueTransaction = messageQueue.CreateQueueTransaction())
                {
                    queueTransaction.Begin();

                    var actualItem = messageQueue.DequeueNextMessage <PushQueueItem>(queueTransaction);
                    AssertCompare(expectedItem1, actualItem);

                    queueTransaction.Abort();
                }

            // Read from queue and the commit
            using (var messageQueue = new SqliteMessageQueue(messageQueuePath))
                using (var queueTransaction = messageQueue.CreateQueueTransaction())
                {
                    queueTransaction.Begin();

                    var actualItem = messageQueue.DequeueNextMessage <PushQueueItem>(queueTransaction);
                    AssertCompare(expectedItem1, actualItem);

                    queueTransaction.Commit();
                }

            // Read from queue and check we can dequeue the second item.
            using (var messageQueue = new SqliteMessageQueue(messageQueuePath))
                using (var queueTransaction = messageQueue.CreateQueueTransaction())
                {
                    queueTransaction.Begin();

                    var actualItem = messageQueue.DequeueNextMessage <PushQueueItem>(queueTransaction);
                    AssertCompare(expectedItem2, actualItem);

                    queueTransaction.Commit();
                }

            // Read from queue and check we can dequeue the second item.
            using (var messageQueue = new SqliteMessageQueue(messageQueuePath))
                using (var queueTransaction = messageQueue.CreateQueueTransaction())
                {
                    queueTransaction.Begin();

                    Assert.ThrowsException <MessageQueueReadException>(() => messageQueue.DequeueNextMessage <PushQueueItem>(queueTransaction));

                    queueTransaction.Abort();
                }
        }
Exemple #18
0
        public static async Task Main(string[] _)
        {
            //elasticsearch setup example
            var elasticSearchOptions =
                new ElasticSearchMessageQueueOptions <MyMessage>()
                .UseConnectionUri(new Uri("YOUR URI HERE"),
                                  (options) =>
            {
                options.ThrowExceptions();
            }
                                  );
            var elasticSearchQueue = new ElasticSearchMessageQueue <MyMessage>(new Logger <ElasticSearchMessageQueue <MyMessage> >(), Options.Create(elasticSearchOptions));

            //sqlite setup example
            var sqliteOptions = new SqliteMessageQueueOptions <MyMessage>()
            {
                ConnectionString = $"Data Source = {Path.Combine(AppContext.BaseDirectory, "Queue.db")}"
            };
            var sqliteQueue = new SqliteMessageQueue <MyMessage>(new Logger <SqliteMessageQueue <MyMessage> >(), Options.Create(sqliteOptions));

            //mqtt setup example
            var mqttOptions =
                new MqttMessageQueueOptions <MyMessage>()
                .UseManagedMqttClientOptionsBuilder(builder =>
            {
                builder.WithClientOptions(options =>
                                          options
                                          .WithTcpServer("HOST HERE")
                                          .WithCredentials("USERNAME", "PASSWORD")
                                          .Build()
                                          );
            });


            //setup for disk queue forwarding to azure queue
            var diskOptions = new DiskMessageQueueOptions <MyMessage>()
            {
                MessageStore = new DirectoryInfo("/my-messages")
            };
            var diskQueue = new DiskMessageQueue <MyMessage>(new Logger <DiskMessageQueue <MyMessage> >(), Options.Create(diskOptions));

            var azureTopicOptions =
                new AzureTopicMessageQueueOptions <MyMessage>()
                .UseConnectionStringBuilder(
                    endpoint: "YOUR ENDPOINT HERE",
                    entityPath: "YOUR ENTITYPATH HERE",
                    sharedAccessKeyName: "YOUR SHARED ACCESS KEY NAME HERE",
                    sharedAccessKey: "YOUR SHARED ACCESS KEY HERE"
                    );
            var azureTopic = new AzureTopicMessageQueue <MyMessage>(new Logger <AzureTopicMessageQueue <MyMessage> >(), Options.Create(azureTopicOptions));

            var forwarderLogger  = new Logger <ForwarderMessageQueue <MyMessage> >();
            var forwarderOptions = new ForwarderMessageQueueOptions()
            {
                SourceSubscriptionName = "YOUR SUBSCRIPTION NAME HERE",
                ForwardingErrorHandler = (ex) =>
                {
                    forwarderLogger.LogError(ex, string.Empty);
                    return(Task.FromResult(CompletionResult.Abandon));
                }
            };
            var forwarder = new ForwarderMessageQueue <MyMessage>(forwarderLogger, Options.Create(forwarderOptions), diskQueue, azureTopic);


            //create the message
            var msg = new MyMessage()
            {
                GUID = Guid.NewGuid(),
                TEST = "TEST"
            };

            //with attributes
            var attributes = new MessageAttributes()
            {
                Label       = "YOUR LABEL HERE",
                ContentType = "application/json"
            };

            //and post to whichever queue you'd like. this one posts to the forwarder queue which posts to the disk and then forwards to azure
            await forwarder.PostMessageAsync(msg, attributes, CancellationToken.None);

            Console.Write("press any key to exit");
            Console.ReadKey();
        }